x11rb-0.8.1/.cargo_vcs_info.json0000644000000001121402220037500120220ustar { "git": { "sha1": "b3777af43d8a649af00cb5d83b37839004ad0815" } } x11rb-0.8.1/.github/workflows/CI.yml010064400017500001750000000104441402220031600152420ustar 00000000000000name: CI on: push: pull_request: schedule: # Midnight on the 1st of a month - cron: '0 0 1 * *' env: CARGO_TERM_COLOR: always MOST_FEATURES: all-extensions cursor image jobs: code_gen: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable - name: Run code generator run: make - name: Check for changes run: if ! git diff --exit-code; then exit 1; fi clippy-rustfmt: runs-on: ubuntu-latest strategy: matrix: include: - rust: stable - rust: beta #fixme: remove this hack clippy_args: -A clippy::manual_strip -A clippy::upper_case_acronyms steps: - uses: actions/checkout@v2 - name: Install rustfmt and clippy uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: ${{ matrix.rust }} override: true components: rustfmt, clippy # rustfmt - name: rustfmt uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check # clippy - name: clippy x11rb without features uses: actions-rs/cargo@v1 with: command: clippy args: -p x11rb --all-targets -- -D warnings ${{ matrix.clippy_args }} - name: clippy x11rb with allow-unsafe-code but without dl-libxcb uses: actions-rs/cargo@v1 with: command: clippy args: -p x11rb --all-targets --features "allow-unsafe-code" -- -D warnings ${{ matrix.clippy_args }} - name: clippy x11rb with allow-unsafe-code and dl-libxcb uses: actions-rs/cargo@v1 with: command: clippy args: -p x11rb --all-targets --features "allow-unsafe-code dl-libxcb" -- -D warnings ${{ matrix.clippy_args }} - name: clippy workspace with all features uses: actions-rs/cargo@v1 with: command: clippy args: --workspace --all-targets --all-features -- -D warnings ${{ matrix.clippy_args }} build: runs-on: ubuntu-latest strategy: matrix: include: - rust: 1.40.0 - rust: stable - rust: beta - rust: nightly steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: ${{ matrix.rust }} override: true - name: Set ALL_FEATURES run: echo "ALL_FEATURES=$MOST_FEATURES allow-unsafe-code dl-libxcb" >> $GITHUB_ENV # build - name: cargo build with all features run: cargo build --verbose --all-targets --features "$ALL_FEATURES" # test - name: cargo test with all features run: cargo test --verbose --workspace --features "$ALL_FEATURES" # doc - name: cargo doc with all features run: cargo doc --verbose --features "$ALL_FEATURES" # run examples - name: Prepare run examples run: | echo '#!/bin/bash for example in examples/*.rs; do example=${example/examples\//} example=${example/.rs/} if [ "$example" != tutorial ] ; then X11RB_EXAMPLE_TIMEOUT=1 xvfb-run -a cargo run --example "$example" "$@" || exit 1 fi done ' > run_examples && chmod a+x run_examples - name: run examples with RustConnection run: ./run_examples --features "$MOST_FEATURES libc" - name: run examples with XCBConnection run: ./run_examples --features "$MOST_FEATURES libc allow-unsafe-code" - name: run examples with XCBConnection and dl-libxcb run: ./run_examples --features "$MOST_FEATURES libc allow-unsafe-code dl-libxcb" big-endian-test: runs-on: ubuntu-latest env: CROSS_TARGET: mips64-unknown-linux-gnuabi64 steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable override: true - name: Install cross rust run: rustup target add "$CROSS_TARGET" - name: Install cross run: cargo install cross --force - name: cargo test run: cross test --target "$CROSS_TARGET" --verbose --features "$MOST_FEATURES" x11rb-0.8.1/.gitignore010064400017500001750000000000361402220031600126130ustar 00000000000000/target **/*.rs.bk Cargo.lock x11rb-0.8.1/Cargo.lock0000644000000054251402220037500100110ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "cc" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "gethostname" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" dependencies = [ "libc", "winapi", ] [[package]] name = "libc" version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" [[package]] name = "libloading" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" dependencies = [ "cfg-if", "winapi", ] [[package]] name = "nix" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ "bitflags", "cc", "cfg-if", "libc", ] [[package]] name = "once_cell" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-wsapoll" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "x11rb" version = "0.8.1" dependencies = [ "gethostname", "libc", "libloading", "nix", "once_cell", "winapi", "winapi-wsapoll", ] x11rb-0.8.1/Cargo.toml0000644000000052711402220037500100330ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "x11rb" version = "0.8.1" authors = ["Uli Schlachter ", "Eduardo Sánchez Muñoz "] exclude = ["/xcb-proto-1.14-1-g2b3559c", "/Makefile", "/.mergify.yml", "/appveyor.yml"] description = "Rust bindings to X11" readme = "README.md" keywords = ["xcb", "X11"] license = "MIT OR Apache-2.0" repository = "https://github.com/psychon/x11rb" [package.metadata.docs.rs] features = ["all-extensions", "allow-unsafe-code", "cursor", "dl-libxcb", "image", "resource_manager"] [[example]] name = "generic_events" required-features = ["present"] [[example]] name = "shared_memory" required-features = ["libc", "shm"] [[example]] name = "xeyes" required-features = ["shape"] [[example]] name = "simple_window" required-features = ["cursor", "resource_manager"] [[example]] name = "display_ppm" required-features = ["image"] [[example]] name = "record" required-features = ["record"] [dependencies.gethostname] version = "0.2.1" [dependencies.libc] version = "0.2" optional = true [dependencies.libloading] version = "0.7.0" optional = true [dependencies.once_cell] version = "1.6.0" optional = true [features] all-extensions = ["composite", "damage", "dpms", "dri2", "dri3", "glx", "present", "randr", "record", "render", "res", "screensaver", "shape", "shm", "sync", "xevie", "xf86dri", "xf86vidmode", "xfixes", "xinerama", "xinput", "xkb", "xprint", "xselinux", "xtest", "xv", "xvmc"] allow-unsafe-code = ["libc"] composite = ["xfixes"] cursor = ["render", "resource_manager"] damage = ["xfixes"] dl-libxcb = ["allow-unsafe-code", "libloading", "once_cell"] dpms = [] dri2 = [] dri3 = [] glx = [] image = [] present = ["randr", "xfixes", "sync"] randr = ["render"] record = [] render = [] res = [] resource_manager = [] screensaver = [] shape = [] shm = [] sync = [] xevie = [] xf86dri = [] xf86vidmode = [] xfixes = ["render", "shape"] xinerama = [] xinput = ["xfixes"] xkb = [] xprint = [] xselinux = [] xtest = [] xv = ["shm"] xvmc = ["xv"] [target."cfg(unix)".dependencies.nix] version = "0.20" [target."cfg(windows)".dependencies.winapi] version = "0.3" features = ["winsock2"] [target."cfg(windows)".dependencies.winapi-wsapoll] version = "0.1.1" x11rb-0.8.1/Cargo.toml.orig010064400017500001750000000055641402220031600135250ustar 00000000000000[package] name = "x11rb" version = "0.8.1" description = "Rust bindings to X11" authors = [ "Uli Schlachter ", "Eduardo Sánchez Muñoz ", ] repository = "https://github.com/psychon/x11rb" readme = "README.md" edition = "2018" license = "MIT OR Apache-2.0" keywords = ["xcb", "X11"] exclude = [ "/xcb-proto-1.14-1-g2b3559c", "/Makefile", "/.mergify.yml", "/appveyor.yml", ] [dependencies] libc = { version = "0.2", optional = true } libloading = { version = "0.7.0", optional = true } once_cell = { version = "1.6.0", optional = true } gethostname = "0.2.1" [target.'cfg(unix)'.dependencies] nix = "0.20" [target.'cfg(windows)'.dependencies] winapi-wsapoll = "0.1.1" [target.'cfg(windows)'.dependencies.winapi] version = "0.3" features = ["winsock2"] [features] # Without this feature, all uses of `unsafe` in the crate are forbidden via # #![deny(unsafe_code)]. This has the effect of disabling the XCB FFI bindings. allow-unsafe-code = ["libc"] # Enable utility functions in `x11rb::cursor` for loading mouse cursors. cursor = ["render", "resource_manager"] # Enable utility functions in `x11rb::image` for working with image data. image = [] # Enable utility functions in `x11rb::resource_manager` for querying the # resource databases. resource_manager = [] dl-libxcb = ["allow-unsafe-code", "libloading", "once_cell"] # Enable this feature to enable all the X11 extensions all-extensions = [ "composite", "damage", "dpms", "dri2", "dri3", "glx", "present", "randr", "record", "render", "res", "screensaver", "shape", "shm", "sync", "xevie", "xf86dri", "xf86vidmode", "xfixes", "xinerama", "xinput", "xkb", "xprint", "xselinux", "xtest", "xv", "xvmc", ] # Features to enable individual X11 extensions composite = ["xfixes"] damage = ["xfixes"] dpms = [] dri2 = [] dri3 = [] glx = [] present = ["randr", "xfixes", "sync"] randr = ["render"] record = [] render = [] res = [] screensaver = [] shape = [] shm = [] sync = [] xevie = [] xf86dri = [] xf86vidmode = [] xfixes = ["render", "shape"] xinerama = [] xinput = ["xfixes"] xkb = [] xprint = [] xselinux = [] xtest = [] xv = ["shm"] xvmc = ["xv"] [package.metadata.docs.rs] features = [ "all-extensions", "allow-unsafe-code", "cursor", "dl-libxcb", "image", "resource_manager", ] [[example]] name = "generic_events" required-features = ["present"] [[example]] name = "shared_memory" required-features = ["libc", "shm"] [[example]] name = "xeyes" required-features = ["shape"] [[example]] name = "simple_window" required-features = ["cursor", "resource_manager"] [[example]] name = "display_ppm" required-features = ["image"] [[example]] name = "record" required-features = ["record"] [workspace] members = ["generator", "xcbgen-rs", "cairo-example", "xtrace-example"] x11rb-0.8.1/LICENSE-APACHE010064400017500001750000000261361402220031600125600ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. x11rb-0.8.1/LICENSE-MIT010064400017500001750000000020421402220031600122560ustar 00000000000000Copyright 2019 x11rb Contributers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. x11rb-0.8.1/README.md010064400017500001750000000057521402220031600121140ustar 00000000000000# X11 rust bindings [![GitHub Actions Status](https://github.com/psychon/x11rb/workflows/CI/badge.svg)](https://github.com/psychon/x11rb/actions) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/950g0t6i8hfc9dup/branch/master?svg=true)](https://ci.appveyor.com/project/psychon/x11rb) [![Crate](https://img.shields.io/crates/v/x11rb.svg)](https://crates.io/crates/x11rb) [![API](https://docs.rs/x11rb/badge.svg)](https://docs.rs/x11rb) ![Minimum rustc version](https://img.shields.io/badge/rustc-1.40+-lightgray.svg) [![License](https://img.shields.io/crates/l/x11rb.svg)](https://github.com/psychon/x11rb#license) Feel free to open issues for any problems or questions you might have. A comparison with some other Rust X11 libraries is available in an [extra document](doc/comparison.md). ## Building This crate uses a code generator that is implemented in Rust. A copy of the generated code is included, so you do not need to run the generator unless you have modified the definitions or the generator itself. The code generator uses the X11 XML description from `xcb-proto`. A copy of xcb-proto that comes with the source code is used. The interaction with libxcb via `XCBConnection` requires at least libxcb 1.12. ## Does this support async/await No. If you have so many X11 connections that this would matter, you are doing something wrong. Also, it encourages people to write high-latency code instead of sending multiple requests and only afterwards wait for the replies. ## Crate features Most X11 extensions are feature-gated. For example, to use the shared memory extansion, the `shm` feature has to be enabled. The `all-extensions` feature just enables all X11 extensions. Additionally, the `allow-unsafe-code` feature enables `XCBConnection`. This uses `libxcb` internally and allows sharing the underlying `xcb_connection_t` pointer with other code. The `cursor` feature enables X11 cursor support via the `cursor` module. This module helps with loading cursors from the current cursor theme. ## Current state The full X11 protocol is supported by this library. All extensions that are available in `xcb-proto` can be used and even [FD passing](examples/shared_memory.rs) with the server is supported. The changelog is available in a [separate file](doc/changelog.md). ## License Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. The subdirectory xcb-proto-1.14-1-g2b3559c contains a vendored copy of the package of the same name. It is covered by the MIT license. See [xcb-proto-1.14-1-g2b3559c/COPYING](xcb-proto-1.14-1-g2b3559c/COPYING) for details. ## Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. x11rb-0.8.1/doc/changelog.md010064400017500001750000000543531402220031600136540ustar 00000000000000# Version 0.8.1 (2021-03-10) Minor changes: * Update to latest version of crate dependencies. * Fix some warnings from rustdoc. * Deal with warnings from newest clippy. * Try to clarify the documentation for X11 error handling. # Version 0.8.0 (2021-01-09) New features: * Added a `resource_manager` library for querying the X11 resource database (Xrm). * Added a `from_configure_request(&ConfigureRequestEvent)` function to `xproto::ConfigureWindowAux`. Fixes: * Rework `` representation so that we can represent invalid values from the X11 server. This mainly fixes problems with XInput. * Add an `InvalidValue` variant to the representation of ``es. This variant is used when the server sends an invalid value for the `` discriminant. This fixes problems with XInput. * The `cursor` code now depends on the Xrm code for proper database support. Breaking changes: * Reword `` representation: Instead of using a Rust `enum`, we now use a newtype around an integer. The named variants are provided as associated constants instead of enum variants. Due to Rust's naming rules, this means that e.g. `xproto::EventMask::ButtonRelease` is now called `BUTTON_RELEASE`. * `ParseError` no longer implements `From`. * Enumerations no longer implement conversion to `bool`. * Removed unused `TryFrom` implementations for enumerations. * Removed `TryFrom<&[u8]>` implementations from the generated code. Minor changes: * Removed some unnecessary `unwrap()`s in the generated code. * Minor improvements to the code generator. * Fixed some new clippy warnings. * Binary operations on enumeration values now preserve the type instead of mapping to integers (e.g. `ConfigWindow::WIDTH | 0` now has type `ConfigWindow` instead of `u8`). * Add a `Debug` impl to enums that selects between `UPPER_CASE` and `CamelCase` based on the `alternate()` flag. * Documentation improvements * Added an internal helper trait `TryIntoUSize` to shorten the conversion from other numbers to `usize`. * Remove some no longer necessary `#![allow]`s from the generated code. # Version 0.7.0 (2020-10-11) New features: * An image utility was added under `x11rb::image`. This allows to do similar things as xcb's image library, e.g. endian conversion. A new `display_ppm` example showcases this new library a bit. * Add a `dl-libxcb` feature. With this feature, we do not link against `libxcb.so` for `XCBConnection`, but instead load the library at runtime via `libloading`. * Request structs now have a `send()` method. This allows for more readable request sending, without having to wonder "what was the fifth argument to `create_window` again?": ``` conn.create_window( screen.root_depth, win_id, screen.root, 0, 0, width, height, 0, WindowClass::InputOutput, 0, &win_aux, )?; CreateWindowRequest { depth: screen.root_depth, wid: win_id, parent: screen.root, x: 0, y: 0, width, height, border_width: 0, class: WindowClass::InputOutput, visual: 0, value_list: std::borrow::Cow::Borrowed(&win_aux), }.send(conn)?; ``` Fixes: * X11 errors are now represented by a single struct `x11rb::x11_utils::X11Error`, because all errors are structurally equivalent. Only the error code differs. * More features are enabled for `docs.rs`, hopefully making the docs complete. * Improve support for the record extension and add an example that shows how to use it. Breaking changes: * The minimum supported Rust version is now Rust 1.40 due to `#[non_exhaustive]`. * The enumeration `x11rb::errors::ParseError` was split up into multiple values that now provide more information about which kind of error occurred. * Hide `x11rb::cursor` behind a feature gate. * `x11rb::protocol::Error` and all individual error structs were removed and replaced with `x11rb::x11_utils::X11Error`. This removes about 2.5k LOC of generated code. * Some enums are now marked as `#[non_exhaustive]`. This includes all enums in the generated protocol code. Minor changes: * `x11rb::utils::RawFdContainer` now always implements `Drop`, even on non-`cfg(unix)` systems. * More items received doc comments. Only the generated code is not fully documented. * Added a new `xtrace-example` that runs a program and prints all of its X11 traffic to the console. * The `simple_window_manager` example was improved. It now has better support for titlebars: Only clicks inside the close button close the window and the remaining area allows to move a window. Also, the example now uses the X11 save set. * Update dependencies to `nix` 0.18 and `winapi-wsapoll` 0.1.1. * Minor internal changes to please newer clippy versions. # Version 0.6.0 (2020-06-19) New features: * The examples in this repository where extended: * New `xclock_utc` example shows a clock. This is useful to see how to get a wakeup once per second. * `cairo-example` uses a transparent background if a EWMH compliant composite manager is running. * The value of length fields are not part of the generated code. This release adds accessors that allow recomputing their value. The motivation for this change was `xproto::GetModiferMappingReply`'s `keycodes_per_modifier` field. * Added `struct`s for X11 requests and added infrastructure for parsing requests. Interested users should start with the `protocol::Request` enum. * Added a `protocol::Reply` enum over all possible replies. * Added a `TryParseFd` trait for types that can be parsed from a combination of raw bytes and a list of file descriptors. Fixes: * Use nonblocking reads and writes for all interactions with the X11 server. This fixes a theoretical deadlock with the X11 server that was never seen in practice. Bindings for `poll()` are now required. * `RustConnection::poll_for_event()` previously only checked for pending queued event, but did not actually try to read new events from the X11 server. * There was a possible deadlock on low-level socket errors. A thread could end up waiting on a condition variable without ever getting woken up. * The support for big requests was broken. Big requests are requests with more than 2^18 bytes. An incorrect length field was sent, cutting of the last four bytes of the request and causing them to be interpreted as a new request. * The parsing codes for errors, events, and replies now return a correct `remaining` slice. Breaking changes: * The whole code around `rust_connection`'s low level stream abstraction was redesigned. This now uses an abstraction over the `poll()` function from libc (and requires similar support for all alternative transport implementations). * The `allow-unsafe-code` feature is no longer enabled by default. * `xkb_select_event`'s `affect_which` field is now deduced based on other arguments and no longer has to be provided explicitly. * Changed return type of `VoidCookie::check()` from `Result, ConnectionError>` to `Result<(), ReplyError>`. This still has the same possible errors as before, but they are represented differently. * Remove the `response_type` fields from errors and replies, because they always have a fixed value (`0` for errors and `1` for replies). Minor changes: * `x11rb::rust_connection::Stream` now implements the traits `AsRawFd`, `IntoRawFd`, `AsRawSocket`, and `IntoRawSocket`. * `x11rb::rust_connection::RustConnection` provides immutable access to its low level stream via the `stream()` method. * Reworked CI integration. Tests are now also run on a big endian platform. * Brought back the [explanation of the generated code](generated_code.md). * Added a module-level doc comment to the generated code. * Satisfy the newest version of our clippy overload for she has many complaints. # Version 0.5.0 (2020-05-10) New features: * The new `Connection::prefetch_maximum_request_bytes()` API allows avoiding a round-trip when sending large requests. * Use enums to represent values in structs where it makes sense. Previously, numeric types like `u8` were used. This simplifies usage of much of the API. * `x11rb::extension_manager::ExtensionInformation` can now provide information about all the extensions that are known to be present. * New enums `x11rb::protocol::Error` and `Event` allow representing any possible error or event in a parsed form. This allows e.g. `match`ing on events for event handling. Also, these enums implement `Debug` and thus allow printing human-readable output on unexpected errors or events. This type also abstracts some of the complications of parsing events away from the library user. The `Connection` trait was extended to be able to parse events/errors into these new types. * Some arguments to request functions became generic where it makes sense. For example, `xproto::change_property` now accepts `Into` instead of just `ATOM` as the name of the property to be changed. Thus, the predefined atoms like `AtomEnum::WM_NAME` can be used directly without having to call `.into()` yourself. * Type names now follow Rust convention. For example, `xproto::WINDOW` is now called `xproto::Window`. * Added utilities for working `WM_CLASS`, `WM_SIZE_HINTS`, and `WM_SIZE` properties. * Implement `Serialize` and `TryParse` for tuples. * Increased the bus factor of the project by about factor 2. Welcome @eduardosm! * Replace the Python code generator with a generator written in Rust. * Added an API for reading a cursor from the active cursor theme. The `simple_window` example was extended to use the new API. * `RustConnection` now supports FD passing. Fixes: * A possible hang when a `QueryExtension` request failed was fixed. * Improve FFI definitions used by `XCBConnection`. * Fix some shadowing issues in the generated code. For example, GLX has its own `Pixmap` type, but also wants to refer to xproto's `Pixmap` in some places. * Alignment pads were incorrectly ignored in `` cases with only one visible field. This affected only the xinput and xkb extensions. * Properly reconstruct sequence numbers in `XCBConnection` after 2^32 requests. The old code only ever provided 32 bits of the sequence number. * Fix compiler error on empty `atom_manager!` invocations. * Request serialisation panics if some overflow occurs instead of producing incorrect data. Breaking changes: * The `vendor-xcb-proto` feature flag is no longer available. The included xcb-proto is now always used. * The `xproto` feature flag was removed. It did not do anything. * The module `x11rb::generated` was renamed to `x11rb::protocol`. * Better snake names are generated, e.g. `XIQueryVersion` becomes `xi_query_version` instead of `xiquery_version`. * Opcodes for events using the generic event extension are now `u16`. * `x11rb::connection::Connection::compute_length_field()` was moved out of the `Connection` trait and to `x11rb::connection::compute_length_field()`. * Use enums to represent values in structs where it makes sense. * Enums that collide with types now have the suffix `Enum` attached to their name. For example, `xproto::Atom` is now called `xproto::AtomEnum`. * Return a simplified struct from `RequestConnection::extension_information` instead of the full `QueryExtensionReply`. * Rename the `ExtensionInformation` struct to `ExtensionManager`. * `GenericEvent`, `GenericError`, and the related `Event` trait were removed. * Changes to `RequestConnection` and `Connection` that affect implementations of these traits. For example, methods `parse_event` and `parse_error` were added. * The `Connection` trait now returns parsed event and errors of type `x11rb::protocol::Event` and `Error`, respectively. The old API providing bytes is retained with alternative names. For example, there is `wait_for_event()` and `wait_for_raw_event()`. * Some functions in the `Connection` trait now return X11 errors in their `Ok` variant via a new `ReplyOrError` enum. This should only affect implementations of the `Connection` trait. * Added some wrapper structs in some parts of `xinput`. This is related to `` handling. * Swap the order of elements in `EventAndSeqNumber`. * Remove some length fields from the public API that can be deduced from the length of other values. * Some `Serialize` implementations were removed from types that depend on value from the surrounding context. * `RustConnection` now supports FD passing. This removes the API for constructing a `RustConnection` from a pair of `Read` and `Write`, but alternatives for the new API exists. * `RawFdContainer` provides no methods when it is not available. This turns some run-time errors into compile-time errors. Minor changes: * No code is generated anymore at build times. Instead, the generated code is shipped with the crate. * The code generator sorts the list of XML files before generating output, ensuring a stable output independent of file system order. * Some parsing code was simplified, saving 5903 (according to git's `--stat` output). * The vendored copy of xcb-proto was updated. * Some fixes to the internal XCB FFI mock that is used for testing. * The code generator and `xcb-proto` are excluded from releases, shrinking the size of the crate a bit. * `XCBConnection` now uses `xcb_poll_for_reply64()` instead of `xcb_poll_for_reply()`. This means that libxcb 1.12 or newer is required. * The `simple_window` example sets more properties. * Some readability and general improvements to the generated code. * Implement conversion to `bool` for enums with just two values. * Added a special fast path for parsing lists of `u8`. * Some refactoring to the I/O in `RustConnection`. * Implement `From` for `ReplyOrIdError`. * Added an example showing how to use x11rb with cairo. * `RawFdContainer` no longer depends on the `allow-unsafe-code` feature. * `RawFdContainer` no longer panics when the `close` on drop fails. * New API `close()` and `try_clone()` is available on `RawFdContainer`. * Use type aliases for `` and `` definitions. This means that the `Debug` implementation may now print the 'wrong' type name, but shortens the generated code by more than 4000 lines. # Version 0.4.1 (2020-03-12) Fixes for XKB: * Fix encoding of `xkb::SelectEvents`. More details can be found in commit 83ff34452bf9. * Make fields of `switch` structs public so that e.g. `GetMapMap` becomes usable. Minor changes: * Only depend on libc if the `allow-unsafe-code` feature is enabled. * Reexport error/event type in `rust_connection`/`xcb_ffi` modules. * Move `multithread_test` from `examples/` to `tests/`. # Version 0.4.0 (2020-03-08) New features: * Add support for the XKB and XInput extensions to the code generator. * x11rb now supports the same X11 extension that libxcb supports! * The `GetKbdByName`, `GetGeometry`, `SetGeometry`, `ListComponents` are not correctly described by xcb-proto and thus still unsupported. * Add an `allow-unsafe-code` and `forbid(unsafe-code)` without this feature. * Add `x11rb::connect()` for establishing a connection to an X11 server. Depending on the `allow-unsafe-code` feature, this either returns a `RustConnection` or an `XCBConnection`. * Make `RustConnection` fully functional and thread-safe. * The only known missing features are FD-passing and XDM-AUTHORIZATION-1 support. * This required a new dependency on the `gethostname` crate. * Add an `atom_manager!` macro. * This macro allows to generate a struct that queries many atoms with a single round-trip. * Add a `Serialize` trait for producing wire bytes from an in-memory representation. * This trait can be implemented for all types and slices, simplifying the generated Rust code. * Serialization is possible into a returned `Vec` or by appending into a provided `&mut Vec`. * Add helpers to `GetPropertyReply` that simplify its interpretation. * This adds `value8(&self)`, `value16(&self)` and `value32(&self)` methods that check for the correct format and return an iterator over the value. * Add a function to create an `XCBConnection` from a raw pointer. * Add `Connection::wait_for_event_with_sequence()` and `Connection::poll_for_event_with_sequence()` that allow to get an event together with its full sequence number. * Add API for prefetching extension information. * General improvements to the documentation. * Emit correct `cargo:rerun-if-changed=` lines from `build.rs`. * Make `x11rb::utils::CSlice` safer. * Use `rustfmt`. * Add AppVeyor for Windows CI. Breaking changes: * Add feature gates for individual X11 extensions. The `all-extensions` feature enables all X11 extensions. * Introduce `Result`s in some places that previously ignored errors or paniced. * Split up `ConnectionError` into two enums, one for errors that can occur while establishing a connection and another for errors on an already-established connection. * Prefix request function names in the `ConnectionExt` traits with the extension name. This is necessary since several extensions contain different versions of the same request. * As an example, `x11rb::generated::shm::ConnectionExt::create_pixmap` is now called `shm_create_pixmap` to avoid a collision with `x11rb::generated::xproto::ConnectionExt::create_pixmap`. The plain function `shm::create_pixmap` kept its name. * Rename `ConnectionErrorOrX11Error` to `ReplyError`. * Remove `x11rb::utils::Buffer` type. Instead, there is an associated type `Connection::Buf`. This is `Vec` for `RustConnection` and `CSlice` for `XCBConnection`. * Remove `LazyAtom`. Changes to the generated code and the code generator. * Implement `From` instead of `Into` in the generated code. * Use better type names in the generated code, e.g. `WINDOW` instead of `u32`. * Simplify and fix some warnings in the generated code without changing visible behaviour. * Change internal storage of unions in the generated code from `Vec` to fixed length arrays. * Fix xproto's `SetModifierMapping` request. The code generator was ignoring an expression that required a multiplication with a constant value to get the length of a list. * Fix xproto's `SetupAuthenticate` and res's `ClientIdValue` serialization. An expression in the XMl was ignored. * Specify enum discriminators where possible. * Implement `TryFrom` for enums. Many thanks to @dalcde and @eduardosm for their valuable contributions. # Version 0.3.0 (2020-01-04) * Split out some types from `x11rb::connection` into their own modules. * Split `xcb_ffi` and `rust_connection` into multiple modules. * Use type aliases like `WINDOW` in the generated code instead of `u32`. * Fix a type confusion in the SYNC extension's generated code where `i64` was used instead of the correct `Int64`. * Update the vendored copy of xcb-proto so that `bool` types can be properly handled in the generated code. * Add constants to extensions containing the extension version number. * Add a `LazyAtom` type that sends an `InternAtom` request and asynchronously waits for the answer. * Implement `Clone`, `PartialEq`, and `Eq` for various types. * Add various "zero constants" that XCB defines in `xcb.h`. * Allow `Connection` implementations to be unsized (`?Sized`). * Split the `Connection` trait into `RequestConnection` and `Connection`. * Run Clippy on the code and deal with its findings. * Return a copy instead of a reference from `extension_information()`. * Allow the creation of union instances via `From`. * Add module-level functions for each request instead of having them only available in traits. This simplifies handling of some name collisions, e.g. around `query_version` being defined by basically all extensions. * Add support for XGE events to the code generator and `XCBConnection`. * Mock libxcb for unit tests. * Implement parsing from borrowed data where possible, i.e. `TryFrom<&Buffer>`, `From<&GenericEvent>`, and `From<&GenericError>`. * Implement `From` for `GenericEvent`. * Clean up some of the internals of `XCBConnection` and `RustConnection`. * Add API for checked/unchecked requests and improve documentation on X11 error handling. * Simplify and document the code generator. * Use examples as integration tests on Travis. * Fix padding with non-unitary alignment. * Implement implicit padding at end of requests. * Fix padding length calculation in conjunction with ``. * Add `sequence_number()` and `raw_reply()` functions to all cookies. * Add a `Makefile` that allows to evaluate changes to the code generator. Usage is `make ref`, then changing the code generator, then `make cmp` to get a diff with the changes. * Add support for some of the XML used for the XInput extension. * Implement `TryParse` only for structs. * Deny more Rust lints and fix resulting errors. * Add support for sending and receiving file descriptors (FD passing). * Add more examples. * Add a sync() function behaving like `xcb_aux_sync()` / `XSync()`. * Test rustc 1.37.0 on Travis as minimum supported Rust version. # Version 0.2.0 (2019-11-02) * The `only_if_exists` parameter of `InternAtom` has type `bool`. * Make `SendEvent` usable. Events now implement `Into<[u8; 32]>`. * Add fields like `sequence` to the generates structs for replies, errors, and events. * Implement `From` for events and `From` for errors. * Add support for big requests. * Derive `Eq` for the error enums. * Return `Result` from `send_request_with/without_reply()`. * Make `XCBConnection` Send and Sync. * Add a getter for `xcb_connection_t*` to `XCBConnection`. * Implement `AsRawFd` for `XCBConnection`. * Move functions for sending requests into an extension trait. * Generate documentation from the `` tags in the XML. * Add a copy of xcb-proto 1.13 to this crate. This copy is used if the `vendor-xcb-proto` feature is enabled, which it is by default. Thus, this crate becomes easier to compile. * Change calls to `xcb_send_request64()` so that the indices -1 and -2 are valid. * Add `poll_for_event()` to `Connection`. * Improve the code generator so that all extensions except xinput and xkb are supported. * Improve the examples. * New examples: `xeyes`, `hypnomoire`, `tutorial` * Add hand-written wrappers to simplify use of `ChangeProperty`. * Improve documentation * Fix length calculations for lists with expressions (`ChangeProperty`, `ChangeKeyboardMapping`, `GetPropertyReply`, ...) * Fix padding calculation for lists with elements with sizes different from zero. * Added a tutorial as `examples/tutorial.rs`. # Version 0.1.0 (2019-10-11) * First release. x11rb-0.8.1/doc/comparison.md010064400017500001750000000116431402220031600140720ustar 00000000000000# Comparison with other Rust X11 libraries My main motivation for writing this library is fun and getting some experience with Rust. As such, "there is already a library" does not count. [![Motivation](https://imgs.xkcd.com/comics/standards.png)](https://xkcd.com/927/) (The image is licensed under a Creative Commons Attribution-NonCommercial 2.5 License) However, since you brought this topic up, let us look at some other libraries that allow accessing an X11 server from Rust. If you know about more libraries or want me to know that I got something wrong, feel free to tell me about them, for example by opening an issue. ## xproto-rs I only found this [on crates.io](https://crates.io/crates/xproto). The Repository link is broken and documentation looks like someone dumped the result of `bindgen` on the Xlib headers into a crate. ## xrb The [Pure Rust bindings for X11](https://github.com/DaMrNelson/xrb) seem to contain hand-written code for parsing and sending X11 messages. Also, its README currently claims that this project is in an early state. ## x11-rs This seems to provide FFI wrappers around Xlib and various related libraries. I recently heard about this library because [its unsafe](https://github.com/erlepereira/x11-rs/issues/99) code is [unsound](https://github.com/rust-lang/rust/issues/52898) and causes undefined behaviour. This is basically all I know and heard about this library. ## rust-xcb This project uses xcb-proto, the XML description of the X11 protocol that comes from the libxcb project. Based on this XML, code is generated that provides a foreign function interface to the various libxcb libraries. Due to its FFI nature, this project contains many instances of `unsafe`. Worse, its `basic_window` example indicates that users of this library must also use `unsafe` for [handling events](https://github.com/rtbo/rust-xcb/blob/d7cb614a6fe9f4424ed26939a5720770f84acd05/examples/basic_window.rs#L66). How can one ever be sure that there is nothing wrong with the `unsafe` one writes? I briefly looked at this project and found a [NULL pointer dereference](https://github.com/rtbo/rust-xcb/issues/64) and re-discovered an already known [leak](https://github.com/rtbo/rust-xcb/issues/57). ## rust-xcbalt The [alternative Rust wrappers for XCB](https://github.com/eduardosm/rust-xcbalt) seem to have a similar goal to rust-xcb: Provide FFI-based bindings to libxcb. I did not look closely at this, but the last commit happened almost two years ago, so this seems to be abandoned. Some of the API looks [interesting](https://github.com/eduardosm/rust-xcbalt/blob/974b76a5e2e776f87a06fa0abc9fd0d3962696b3/examples/core_events.rs#L9-L36). Requests can apparently be generated by filling out a `RequestBuilder` struct and then calling `.send()` on it. ## breadx "An implementation of the X Window System Protocol in Rust. 100% safe and mutex-free." [breadx](https://github.com/not-a-seagull/breadx) is another project that uses the xcb-proto XML description of the X11 protocol to generate code. The project claims that it is "generally faster (awaiting verification)". One highlight is support for async. However, interactions with the X11 server require `&mut`-access to the [Display](https://docs.rs/breadx/0.1.3/breadx/display/struct.Display.html). Thus, the Display needs to be wrapped in a `Mutex` or `RefCell` to share with multiple async tasks. Another highlight is `no_std` support. ## xcb-sys The [xcb-sys crate](https://crates.io/crates/xcb-sys) uses bindgen to automatically generate a Rust API from libxcb's C headers. Everything is unsafe and as a user you are basically writing C code in Rust. Put differently: There is lots of existing documentation (for C code) and reference code (written in C) that you can use. It is pretty much directly transferable to this library. ## x11rb (this project) x11rb, the x11 rust bindings, is based on the XML description of the X11 protocol that comes from the libxcb project, similar to rust-xcb. However, instead of providing a foreign function interface to libxcb, the generated code reimplements the serialising and unserialising code that is provided by libxcb. libxcb is only used for receiving and sending opaque packets. This reimplementation tries to avoid uses of `unsafe` and thus should enjoy Rust's usual safety guarantees. After all, the best way to trust the unsafe code coming out of your code generator is if your code generator does not generate any unsafe code. Unsafe code is currently necessary for FFI binding to a handful of functions from libxcb (see `src/xcb_ffi.rs`). This means that this project is even safer than libxcb, because libxcb forces its users to blindly trust length fields that come from the X11 server. The downside of this is possibly slower code. However, if your bottleneck is in talking to the X11 server, you are seriously doing something wrong. Examples of the generated code [can be found here](generated_code.md). Feel free to suggest improvements to it. x11rb-0.8.1/doc/generated_code.md010064400017500001750000001073441402220031600146540ustar 00000000000000# Examples of the generated code This crate uses a code generator to generate rust code for the X11 protocol. You might be curious what the generated code looks like. This document is there to answer this question. As you may know, the code generator uses an XML description of the X11 protocol from `xcb-proto`. This document will show some examples of the XML description followed by the Rust code that is generated for it. The following code is generated at the beginning of a module (example for `xproto`; other modules have some slight differences): ```rust // This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the core X11 protocol. //! //! For more documentation on the X11 protocol, see the //! [protocol reference manual](https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html). //! This is especially recommended for looking up the exact semantics of //! specific errors, events, or requests. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::cookie::ListFontsWithInfoCookie; use crate::errors::{ConnectionError, ParseError}; ``` ## XID types XIDs simply are numbers. They uniquely identify, for example, a window. ```xml ``` Since all XIDs are 32 bit numbers, the generated code is a type alias: ```rust pub type Window = u32; ``` ## Structs ### Fixed length structs Structs are used as building blocks for other things. For example, a request could send a list of structs to the X11 server. ```xml ``` The server can send structs to us. For this reason, there is a `TryParse` trait that is implemented on structs. This trait is used by the generated code, for example to parse a list of `Point`s. We must also be able to send structs to the server. This is handled through the `Serialize` trait that produces data in the native endian. ```rust #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Point { pub x: i16, pub y: i16, } impl TryParse for Point { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let result = Point { x, y }; Ok((result, remaining)) } } impl Serialize for Point { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); [ x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.x.serialize_into(bytes); self.y.serialize_into(bytes); } } ``` ### Variable length structs Structs can be a bit more complicated than the above example, because they can contain lists of other structs. This example demonstrates this. ```xml visuals_len ``` The field `visuals_len` is not part of the generated struct since it is represented implicitly as the length of the `visuals` `Vec`. To make this less confusing, a function `visuals_len` is generated. ```rust #[derive(Debug, Clone, PartialEq, Eq)] pub struct Depth { pub depth: u8, pub visuals: Vec, } impl TryParse for Depth { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (visuals_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (visuals, remaining) = crate::x11_utils::parse_list::(remaining, visuals_len.try_to_usize()?)?; let result = Depth { depth, visuals }; Ok((result, remaining)) } } impl Serialize for Depth { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.depth.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); let visuals_len = u16::try_from(self.visuals.len()).expect("`visuals` has too many elements"); visuals_len.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); self.visuals.serialize_into(bytes); } } impl Depth { /// Get the value of the `visuals_len` field. /// /// The `visuals_len` field is used as the length field of the `visuals` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn visuals_len(&self) -> u16 { self.visuals.len() .try_into().unwrap() } } ``` ## Enumerations Enumerations have a set of defined values, similar to rust `enum`s. However, they are not represented as `enum`s since there are cases where the X11 server violates the X11 protocol. These cases previously caused `ParseError`. Thus, enumerations are now represented as a newtype around numbers. ### 'Real' enumerations ```xml 0 1 2 ``` Depending on the largest value, appropriate `From` and `TryFrom` implementations are generated. ```rust #[derive(Clone, Copy, PartialEq, Eq)] pub struct BackingStore(u32); impl BackingStore { pub const NOT_USEFUL: Self = Self(0); pub const WHEN_MAPPED: Self = Self(1); pub const ALWAYS: Self = Self(2); } impl From for u32 { #[inline] fn from(input: BackingStore) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BackingStore) -> Self { Some(input.0) } } impl From for BackingStore { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for BackingStore { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for BackingStore { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for BackingStore { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NOT_USEFUL.0, "NOT_USEFUL", "NotUseful"), (Self::WHEN_MAPPED.0, "WHEN_MAPPED", "WhenMapped"), (Self::ALWAYS.0, "ALWAYS", "Always"), ]; pretty_print_enum(fmt, self.0, &variants) } } ``` ### Bitmask enumerations Bitmasks also get an invocation of the `bitmask_binop!` macro. This creates implementations of `BitOr` and `BitOrAssign`. ```xml 0 1 2 3 4 5 6 ``` ```rust #[derive(Clone, Copy, PartialEq, Eq)] pub struct ConfigWindow(u8); impl ConfigWindow { pub const X: Self = Self(1 << 0); pub const Y: Self = Self(1 << 1); pub const WIDTH: Self = Self(1 << 2); pub const HEIGHT: Self = Self(1 << 3); pub const BORDER_WIDTH: Self = Self(1 << 4); pub const SIBLING: Self = Self(1 << 5); pub const STACK_MODE: Self = Self(1 << 6); } impl From for u8 { #[inline] fn from(input: ConfigWindow) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ConfigWindow) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ConfigWindow) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ConfigWindow) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ConfigWindow) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ConfigWindow) -> Self { Some(u32::from(input.0)) } } impl From for ConfigWindow { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ConfigWindow { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::X.0.into(), "X", "X"), (Self::Y.0.into(), "Y", "Y"), (Self::WIDTH.0.into(), "WIDTH", "Width"), (Self::HEIGHT.0.into(), "HEIGHT", "Height"), (Self::BORDER_WIDTH.0.into(), "BORDER_WIDTH", "BorderWidth"), (Self::SIBLING.0.into(), "SIBLING", "Sibling"), (Self::STACK_MODE.0.into(), "STACK_MODE", "StackMode"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ConfigWindow, u8); ``` ## Unions Sadly, there are unions in X11. In core X11, there is only one union: ClientMessageData. ```xml 20 10 5 ``` The union contains an array of unparsed data. The data is then parsed as the requested type in the accessor functions. ```rust #[derive(Debug, Copy, Clone)] pub struct ClientMessageData([u8; 20]); impl ClientMessageData { pub fn as_data8(&self) -> [u8; 20] { fn do_the_parse(remaining: &[u8]) -> Result<[u8; 20], ParseError> { let (data8, remaining) = crate::x11_utils::parse_u8_list(remaining, 20)?; let data8 = <[u8; 20]>::try_from(data8).unwrap(); let _ = remaining; Ok(data8) } do_the_parse(&self.0).unwrap() } pub fn as_data16(&self) -> [u16; 10] { fn do_the_parse(remaining: &[u8]) -> Result<[u16; 10], ParseError> { let (data16_0, remaining) = u16::try_parse(remaining)?; let (data16_1, remaining) = u16::try_parse(remaining)?; let (data16_2, remaining) = u16::try_parse(remaining)?; let (data16_3, remaining) = u16::try_parse(remaining)?; let (data16_4, remaining) = u16::try_parse(remaining)?; let (data16_5, remaining) = u16::try_parse(remaining)?; let (data16_6, remaining) = u16::try_parse(remaining)?; let (data16_7, remaining) = u16::try_parse(remaining)?; let (data16_8, remaining) = u16::try_parse(remaining)?; let (data16_9, remaining) = u16::try_parse(remaining)?; let data16 = [ data16_0, data16_1, data16_2, data16_3, data16_4, data16_5, data16_6, data16_7, data16_8, data16_9, ]; let _ = remaining; Ok(data16) } do_the_parse(&self.0).unwrap() } pub fn as_data32(&self) -> [u32; 5] { fn do_the_parse(remaining: &[u8]) -> Result<[u32; 5], ParseError> { let (data32_0, remaining) = u32::try_parse(remaining)?; let (data32_1, remaining) = u32::try_parse(remaining)?; let (data32_2, remaining) = u32::try_parse(remaining)?; let (data32_3, remaining) = u32::try_parse(remaining)?; let (data32_4, remaining) = u32::try_parse(remaining)?; let data32 = [ data32_0, data32_1, data32_2, data32_3, data32_4, ]; let _ = remaining; Ok(data32) } do_the_parse(&self.0).unwrap() } } impl Serialize for ClientMessageData { type Bytes = [u8; 20]; fn serialize(&self) -> [u8; 20] { self.0 } fn serialize_into(&self, bytes: &mut Vec) { bytes.extend_from_slice(&self.0); } } impl TryParse for ClientMessageData { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let inner: [u8; 20] = value.get(..20) .ok_or(ParseError::InsufficientData)? .try_into() .unwrap(); let result = ClientMessageData(inner); Ok((result, &value[20..])) } } impl From<[u8; 20]> for ClientMessageData { fn from(data8: [u8; 20]) -> Self { Self(data8) } } impl From<[u16; 10]> for ClientMessageData { fn from(data16: [u16; 10]) -> Self { let data16_0_bytes = data16[0].serialize(); let data16_1_bytes = data16[1].serialize(); let data16_2_bytes = data16[2].serialize(); let data16_3_bytes = data16[3].serialize(); let data16_4_bytes = data16[4].serialize(); let data16_5_bytes = data16[5].serialize(); let data16_6_bytes = data16[6].serialize(); let data16_7_bytes = data16[7].serialize(); let data16_8_bytes = data16[8].serialize(); let data16_9_bytes = data16[9].serialize(); let value = [ data16_0_bytes[0], data16_0_bytes[1], data16_1_bytes[0], data16_1_bytes[1], data16_2_bytes[0], data16_2_bytes[1], data16_3_bytes[0], data16_3_bytes[1], data16_4_bytes[0], data16_4_bytes[1], data16_5_bytes[0], data16_5_bytes[1], data16_6_bytes[0], data16_6_bytes[1], data16_7_bytes[0], data16_7_bytes[1], data16_8_bytes[0], data16_8_bytes[1], data16_9_bytes[0], data16_9_bytes[1], ]; Self(value) } } impl From<[u32; 5]> for ClientMessageData { fn from(data32: [u32; 5]) -> Self { let data32_0_bytes = data32[0].serialize(); let data32_1_bytes = data32[1].serialize(); let data32_2_bytes = data32[2].serialize(); let data32_3_bytes = data32[3].serialize(); let data32_4_bytes = data32[4].serialize(); let value = [ data32_0_bytes[0], data32_0_bytes[1], data32_0_bytes[2], data32_0_bytes[3], data32_1_bytes[0], data32_1_bytes[1], data32_1_bytes[2], data32_1_bytes[3], data32_2_bytes[0], data32_2_bytes[1], data32_2_bytes[2], data32_2_bytes[3], data32_3_bytes[0], data32_3_bytes[1], data32_3_bytes[2], data32_3_bytes[3], data32_4_bytes[0], data32_4_bytes[1], data32_4_bytes[2], data32_4_bytes[3], ]; Self(value) } } ``` ## Events ```xml [SNIP] ``` ```rust /// Opcode for the KeyPress event pub const KEY_PRESS_EVENT: u8 = 2; /// [SNIP] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyPressEvent { pub response_type: u8, pub detail: Keycode, pub sequence: u16, pub time: Timestamp, pub root: Window, pub event: Window, pub child: Window, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub same_screen: bool, } impl TryParse for KeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = Keycode::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = Timestamp::try_parse(remaining)?; let (root, remaining) = Window::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (child, remaining) = Window::try_parse(remaining)?; let (root_x, remaining) = i16::try_parse(remaining)?; let (root_y, remaining) = i16::try_parse(remaining)?; let (event_x, remaining) = i16::try_parse(remaining)?; let (event_y, remaining) = i16::try_parse(remaining)?; let (state, remaining) = u16::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = KeyPressEvent { response_type, detail, sequence, time, root, event, child, root_x, root_y, event_x, event_y, state, same_screen }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&KeyPressEvent> for [u8; 32] { fn from(input: &KeyPressEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = input.detail.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let root_bytes = input.root.serialize(); let event_bytes = input.event.serialize(); let child_bytes = input.child.serialize(); let root_x_bytes = input.root_x.serialize(); let root_y_bytes = input.root_y.serialize(); let event_x_bytes = input.event_x.serialize(); let event_y_bytes = input.event_y.serialize(); let state_bytes = input.state.serialize(); let same_screen_bytes = input.same_screen.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], child_bytes[0], child_bytes[1], child_bytes[2], child_bytes[3], root_x_bytes[0], root_x_bytes[1], root_y_bytes[0], root_y_bytes[1], event_x_bytes[0], event_x_bytes[1], event_y_bytes[0], event_y_bytes[1], state_bytes[0], state_bytes[1], same_screen_bytes[0], 0, ] } } impl From for [u8; 32] { fn from(input: KeyPressEvent) -> Self { Self::from(&input) } } ``` ## Errors ```xml ``` All X11 errors contain the same fields. Thus, we only need to remember which number represents this error. ```rust /// Opcode for the Request error pub const REQUEST_ERROR: u8 = 1; ``` The actual representation of an X11 error can be found in [`x11rb::x11_utils::X11Error`](../src/x11_utils.rs). ## Requests For requests, we generate an extension trait. Individual requests are available on this trait and as global functions. The generic structure looks like this: ```rust /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { // Following code examples are in here } impl ConnectionExt for C {} ``` ### Request without a reply ```xml ``` The request is represented by a structure that contains all of the request's fields. This `struct` can be constructed explicitly and then `.send()` to an X11 server. This code is generated in the module: ```rust /// Opcode for the NoOperation request pub const NO_OPERATION_REQUEST: u8 = 127; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NoOperationRequest; impl NoOperationRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> BufWithFds> where Conn: RequestConnection + ?Sized, { let _ = conn; let length_so_far = 0; let mut request0 = vec![ NO_OPERATION_REQUEST, 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); (vec![request0.into()], vec![]) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn); let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.major_opcode != NO_OPERATION_REQUEST { return Err(ParseError::InvalidValue); } let remaining = &[header.minor_opcode]; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let _ = remaining; let _ = value; Ok(NoOperationRequest ) } } ``` A trait is used to map between requests and their corresponding reply. For requests without a reply, this maps to the unit type: ```rust impl Request for NoOperationRequest { type Reply = (); } ``` There is also a helper function for sending the request with a function call. ```rust pub fn no_operation(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = NoOperationRequest; request0.send(conn) } ``` The request sending function is also available on the extension trait: ```rust fn no_operation(&self) -> Result, ConnectionError> { no_operation(self) } ``` ### Request with a reply ```xml ``` There is again a structure generated in the code that represents the request: ```rust /// Opcode for the GetInputFocus request pub const GET_INPUT_FOCUS_REQUEST: u8 = 43; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetInputFocusRequest; impl GetInputFocusRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> BufWithFds> where Conn: RequestConnection + ?Sized, { let _ = conn; let length_so_far = 0; let mut request0 = vec![ GET_INPUT_FOCUS_REQUEST, 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); (vec![request0.into()], vec![]) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn); let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.major_opcode != GET_INPUT_FOCUS_REQUEST { return Err(ParseError::InvalidValue); } let remaining = &[header.minor_opcode]; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let _ = remaining; let _ = value; Ok(GetInputFocusRequest ) } } ``` Since this request has a reply, the implementation of the `Request` trait maps to that reply: ```rust impl Request for GetInputFocusRequest { type Reply = GetInputFocusReply; } ``` Of course, there is a function to send the request: ```rust pub fn get_input_focus(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetInputFocusRequest; request0.send(conn) } ``` The reply is handled similar to a `struct`: ```rust #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetInputFocusReply { pub revert_to: InputFocus, pub sequence: u16, pub length: u32, pub focus: Window, } impl TryParse for GetInputFocusReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (revert_to, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (focus, remaining) = Window::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let revert_to = revert_to.into(); let result = GetInputFocusReply { revert_to, sequence, length, focus }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } ``` There is also a function for sending the request in the extension trait: ```rust fn get_input_focus(&self) -> Result, ConnectionError> { get_input_focus(self) } ``` ### Requests with a switch Some requests have optional fields. A bit in the request then indicates the presence of this extra field. For this kind of requests, a helper structure is generated. ```xml value_mask X Y Width Height BorderWidth Sibling StackMode [SNIP] ``` The switch is represented via a helper struct: ```rust /// Auxiliary and optional information for the `configure_window` function #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct ConfigureWindowAux { pub x: Option, pub y: Option, pub width: Option, pub height: Option, pub border_width: Option, pub sibling: Option, pub stack_mode: Option, } impl ConfigureWindowAux { fn try_parse(value: &[u8], value_mask: u16) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(value_mask); let mut outer_remaining = value; let x = if switch_expr & u32::from(ConfigWindow::X) != 0 { let remaining = outer_remaining; let (x, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(x) } else { None }; let y = if switch_expr & u32::from(ConfigWindow::Y) != 0 { let remaining = outer_remaining; let (y, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(y) } else { None }; [SNIP - you get the idea] let result = ConfigureWindowAux { x, y, width, height, border_width, sibling, stack_mode }; Ok((result, outer_remaining)) } } impl ConfigureWindowAux { #[allow(dead_code)] fn serialize(&self, value_mask: u16) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, value_mask); result } fn serialize_into(&self, bytes: &mut Vec, value_mask: u16) { assert_eq!(self.switch_expr(), u32::from(value_mask), "switch `value_list` has an inconsistent discriminant"); if let Some(x) = self.x { x.serialize_into(bytes); } if let Some(y) = self.y { y.serialize_into(bytes); } [SNIP - you get the idea] } } impl ConfigureWindowAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.x.is_some() { expr_value |= u32::from(ConfigWindow::X); } if self.y.is_some() { expr_value |= u32::from(ConfigWindow::Y); } [SNIP - you get the idea] expr_value } } impl ConfigureWindowAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `x` field of this structure. pub fn x(mut self, value: I) -> Self where I: Into> { self.x = value.into(); self } /// Set the `y` field of this structure. pub fn y(mut self, value: I) -> Self where I: Into> { self.y = value.into(); self } [SNIP - you get the idea] } ``` This code is generated for the actual request: ```rust /// Opcode for the ConfigureWindow request pub const CONFIGURE_WINDOW_REQUEST: u8 = 12; /// [SNIP] #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConfigureWindowRequest<'input> { pub window: Window, pub value_list: Cow<'input, ConfigureWindowAux>, } impl<'input> ConfigureWindowRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> BufWithFds> where Conn: RequestConnection + ?Sized, { let _ = conn; let length_so_far = 0; let window_bytes = self.window.serialize(); let value_mask = u16::try_from(self.value_list.switch_expr()).unwrap(); let value_mask_bytes = value_mask.serialize(); let mut request0 = vec![ CONFIGURE_WINDOW_REQUEST, 0, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], value_mask_bytes[0], value_mask_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let value_list_bytes = self.value_list.serialize(value_mask); let length_so_far = length_so_far + value_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); (vec![request0.into(), value_list_bytes.into(), padding0.into()], vec![]) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn); let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.major_opcode != CONFIGURE_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let remaining = &[header.minor_opcode]; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let _ = remaining; let (window, remaining) = Window::try_parse(value)?; let (value_mask, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (value_list, remaining) = ConfigureWindowAux::try_parse(remaining, value_mask)?; let _ = remaining; Ok(ConfigureWindowRequest { window, value_list: Cow::Owned(value_list), }) } /// Clone all borrowed data in this ConfigureWindowRequest. pub fn into_owned(self) -> ConfigureWindowRequest<'static> { ConfigureWindowRequest { window: self.window, value_list: Cow::Owned(self.value_list.into_owned()), } } } impl<'input> Request for ConfigureWindowRequest<'input> { type Reply = (); } /// [SNIP] pub fn configure_window<'c, 'input, Conn>(conn: &'c Conn, window: Window, value_list: &'input ConfigureWindowAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ConfigureWindowRequest { window, value_list: Cow::Borrowed(value_list), }; request0.send(conn) } ``` And this code is in the extension trait: ```rust /// [SNIP] fn configure_window<'c, 'input>(&'c self, window: Window, value_list: &'input ConfigureWindowAux) -> Result, ConnectionError> { configure_window(self, window, value_list) } ``` ## Common code The above showed examples for the code that is generated in a single module. There is also some common code in [`x11rb::protocol`](../src/protocol/mod.rs). This contains `enum`s over all possible requests, replies, errors, and events. Via these, you can e.g. get the `sequence_number` contained in an event without having to write a big `match` over all possible events. x11rb-0.8.1/doc/making_a_release.md010064400017500001750000000004251402220031600151620ustar 00000000000000``` vim doc/generated_code.md # Update the generated code vim doc/changelog.md # Update the changelog vim Cargo.toml # Update version number # Now get these changes merged cargo publish --dry-run git tag -a -m "Version 0.2.0" v0.2.0 cargo publish git push origin v0.2.0 ``` x11rb-0.8.1/examples/check_unchecked_requests.rs010064400017500001750000000060601402220031600200330ustar 00000000000000// This program shows error handling. It causes some X11 errors and shows where they end up. // // This program also serves as a (bad) integration test. To verify that the expected behaviour // occurs, it needs to do some extra work. In particular, all calls to .sequence_number() are not // needed for the example, but only for the test. Where needed, extra comments indicate how the // short version of each case would look. extern crate x11rb; use x11rb::connection::Connection; use x11rb::errors::ReplyError; use x11rb::protocol::xproto::ConnectionExt as _; use x11rb::protocol::Event; use x11rb::wrapper::ConnectionExt as _; const INVALID_WINDOW: u32 = 0; fn main() -> Result<(), Box> { let (conn, _) = x11rb::connect(None).unwrap(); // For requests with responses, there are four possibilities: // We can just normally get the response or error to the request via reply() let res = conn.get_geometry(INVALID_WINDOW)?.reply(); assert!(res.is_err()); // We can decide that we do not care about the response and also do not care about errors via // discard_reply_and_errors() conn.get_geometry(INVALID_WINDOW)? .discard_reply_and_errors(); // Errors can show up as 'events' in wait_for_event() via reply_unchecked() let cookie = conn.get_geometry(INVALID_WINDOW)?; let seq1 = cookie.sequence_number(); let res = cookie.reply_unchecked()?; assert!(res.is_none()); // The short version of the above would be: // let res = conn.get_geomtry(INVALID_WINDOW)?.reply_unchecked()?; // Errors can show up as 'events' in wait_for_event() by just dropping the cookie let cookie = conn.get_geometry(INVALID_WINDOW)?; let seq2 = cookie.sequence_number(); drop(cookie); // The short version of the above would be: // drop(conn.get_geometry(INVALID_WINDOW)?); // For requests without responses, there are three possibilities // We can check for errors explicitly match conn.destroy_window(INVALID_WINDOW)?.check() { Err(ReplyError::X11Error(_)) => {} e => panic!("{:?} unexpected", e), } // We can silently ignore the error conn.destroy_window(INVALID_WINDOW)?.ignore_error(); // An error can be handled as an event. let cookie = conn.destroy_window(INVALID_WINDOW)?; let seq3 = cookie.sequence_number(); drop(cookie); // The short version of the above would be: // drop(conn.destroy_window(INVALID_WINDOW)?); // Synchronise with the server so that all errors are already received. conn.sync()?; // Now check if the things above really caused errors. This is the part that is supposed to // turn this example into a (bad) integration test. for &seq in &[seq1, seq2, seq3] { let (event, seq2) = conn.wait_for_event_with_sequence()?; match event { Event::Error(_) => {} event => panic!("Unexpectedly got {:?} instead of an X11 error", event), } assert_eq!(seq, seq2); } assert!(conn.poll_for_event()?.is_none()); println!("Done"); Ok(()) } x11rb-0.8.1/examples/display_ppm.rs010064400017500001750000000205731402220031600153400ustar 00000000000000// This example reads a .ppm file and displays the image on screen. It shows how to work // with images. use x11rb::connection::Connection; use x11rb::errors::ReplyOrIdError; use x11rb::image::{ColorComponent, Image, PixelLayout}; use x11rb::protocol::xproto::{ AtomEnum, ConnectionExt, CreateGCAux, CreateWindowAux, PropMode, Screen, VisualClass, Visualid, Window, WindowClass, }; use x11rb::protocol::Event; use x11rb::wrapper::ConnectionExt as _; x11rb::atom_manager! { Atoms: AtomsCookie { WM_PROTOCOLS, WM_DELETE_WINDOW, } } /// Create a window with the given image as background. fn create_window( conn: &impl Connection, screen: &Screen, atoms: &Atoms, image: &Image, ) -> Result { let win_id = conn.generate_id()?; let pixmap_id = conn.generate_id()?; let gc_id = conn.generate_id()?; conn.create_gc( gc_id, screen.root, &CreateGCAux::default().graphics_exposures(0), )?; conn.create_pixmap( screen.root_depth, pixmap_id, screen.root, image.width(), image.height(), )?; image.put(conn, pixmap_id, gc_id, 0, 0)?; conn.free_gc(gc_id)?; conn.create_window( screen.root_depth, win_id, screen.root, 0, 0, image.width(), image.height(), 0, WindowClass::INPUT_OUTPUT, 0, &CreateWindowAux::default().background_pixmap(pixmap_id), )?; conn.free_pixmap(pixmap_id)?; conn.change_property32( PropMode::REPLACE, win_id, atoms.WM_PROTOCOLS, AtomEnum::ATOM, &[atoms.WM_DELETE_WINDOW], )?; Ok(win_id) } /// Check that the given visual is "as expected" (pixel values are 0xRRGGBB with RR/GG/BB being the /// colors). Otherwise, this exits the process. fn check_visual(screen: &Screen, id: Visualid) -> PixelLayout { // Find the information about the visual and at the same time check its depth. let visual_info = screen .allowed_depths .iter() .filter_map(|depth| { let info = depth.visuals.iter().find(|depth| depth.visual_id == id); info.map(|info| (depth.depth, info)) }) .next(); let (depth, visual_type) = match visual_info { Some(info) => info, None => { eprintln!("Did not find the root visual's description?!"); std::process::exit(1); } }; // Check that the pixels have red/green/blue components that we can set directly. match visual_type.class { VisualClass::TRUE_COLOR | VisualClass::DIRECT_COLOR => {} _ => { eprintln!( "The root visual is not true / direct color, but {:?}", visual_type, ); std::process::exit(1); } } let result = PixelLayout::from_visual_type(*visual_type) .expect("The server sent a malformed visual type"); assert_eq!(result.depth(), depth); result } fn main() -> Result<(), Box> { // Load the image let image = match std::env::args_os().nth(1) { None => { eprintln!( "Expected a file name of a PPM as argument, using a built-in default image instead" ); ppm_parser::parse_ppm_bytes(&BUILTIN_IMAGE)? } Some(arg) => ppm_parser::parse_ppm_file(&arg)?, }; let (conn, screen_num) = x11rb::connect(None)?; // The following is only needed for start_timeout_thread(), which is used for 'tests' let conn1 = std::sync::Arc::new(conn); let conn = &*conn1; let screen = &conn.setup().roots[screen_num]; let pixel_layout = check_visual(screen, screen.root_visual); // Convert the image from the PPM format into the server's native format. let ppm_layout = PixelLayout::new( ColorComponent::new(8, 16)?, ColorComponent::new(8, 8)?, ColorComponent::new(8, 0)?, ); let image = image.reencode(ppm_layout, pixel_layout, conn.setup())?; let atoms = Atoms::new(conn)?.reply()?; let win_id = create_window(conn, screen, &atoms, &image)?; conn.map_window(win_id)?; util::start_timeout_thread(conn1.clone(), win_id); conn.flush()?; loop { let event = conn.wait_for_event().unwrap(); match event { Event::ClientMessage(event) => { let data = event.data.as_data32(); if event.format == 32 && event.window == win_id && data[0] == atoms.WM_DELETE_WINDOW { println!("Window was asked to close"); return Ok(()); } } Event::Error(err) => println!("Got an unexpected error: {:?}", err), ev => println!("Got an unknown event: {:?}", ev), } } } mod ppm_parser { use std::ffi::OsStr; use std::io::{Error as IOError, ErrorKind, Read, Result as IOResult}; use x11rb::image::{BitsPerPixel, Image, ImageOrder, ScanlinePad}; fn make_io_error(text: &'static str) -> IOError { IOError::new(ErrorKind::Other, text) } /// Read until the next b'\n'. fn read_to_end_of_line(input: &mut impl Read) -> IOResult<()> { let mut byte = [0; 1]; loop { input.read_exact(&mut byte)?; if byte[0] == b'\n' { return Ok(()); } } } /// Read a decimal number from the input. fn read_decimal(input: &mut impl Read) -> IOResult { let mut byte = [0; 1]; // Skip leading whitespace and comments loop { input.read_exact(&mut byte)?; match byte[0] { b' ' | b'\t' | b'\r' => {} // Comment, skip a whole line b'#' => read_to_end_of_line(input)?, _ => break, } } // Now comes a number if !byte[0].is_ascii_digit() { return Err(make_io_error("Failed parsing a number")); } let mut result: u16 = 0; while byte[0].is_ascii_digit() { let value = u16::from(byte[0] - b'0'); result = result .checked_mul(10) .map(|result| result + value) .ok_or_else(|| make_io_error("Overflow while parsing number"))?; input.read_exact(&mut byte)?; } // After the number, there should be some whitespace. if byte[0].is_ascii_whitespace() { Ok(result) } else { Err(make_io_error("Unexpected character in header")) } } fn parse_ppm(input: &mut impl Read) -> IOResult> { let mut header = [0; 2]; input.read_exact(&mut header)?; if header != *b"P6" { return Err(make_io_error("Incorrect file header")); } read_to_end_of_line(input)?; let width = read_decimal(input)?; let height = read_decimal(input)?; let max = read_decimal(input)?; if max != 255 { eprintln!( "Image declares a max pixel value of {}, but I expected 255.", max, ); eprintln!("Something will happen...?"); } let mut image = Image::allocate( width, height, ScanlinePad::Pad8, 24, BitsPerPixel::B24, ImageOrder::MSBFirst, ); input.read_exact(image.data_mut())?; Ok(image) } pub fn parse_ppm_bytes(bytes: &[u8]) -> IOResult> { use std::io::Cursor; parse_ppm(&mut Cursor::new(bytes)) } pub fn parse_ppm_file(file_name: &OsStr) -> IOResult> { use std::fs::File; use std::io::BufReader; parse_ppm(&mut BufReader::new(File::open(file_name)?)) } } // Simple builtin PPM that is used if none is provided on the command line #[rustfmt::skip] const BUILTIN_IMAGE: [u8; 35] = [ b'P', b'6', b'\n', // width and height b'4', b' ', b'2', b'\n', b'2', b'5', b'5', b'\n', // Black pixel 0x00, 0x00, 0x00, // red pixel 0xff, 0x00, 0x00, // green pixel 0x00, 0xff, 0x00, // blue pixel 0x00, 0x00, 0xff, // white pixel 0xff, 0xff, 0xff, // cyan pixel 0x00, 0xff, 0xff, // magenta pixel 0xff, 0x00, 0xff, // yellow pixel 0xff, 0xff, 0x00, ]; include!("integration_test_util/util.rs"); x11rb-0.8.1/examples/generic_events.rs010064400017500001750000000044631402220031600160170ustar 00000000000000// This example tests support for generic events (XGE). It generates a window and uses the PRESENT // extension to cause an XGE event to be sent. use std::process::exit; use x11rb::connection::{Connection as _, RequestConnection as _}; use x11rb::protocol::xproto::{ ConfigureWindowAux, ConnectionExt as _, CreateWindowAux, WindowClass, }; use x11rb::protocol::{present, Event}; use x11rb::COPY_DEPTH_FROM_PARENT; fn main() -> Result<(), Box> { let (conn, screen_num) = x11rb::connect(None)?; let screen = &conn.setup().roots[screen_num]; if conn .extension_information(present::X11_EXTENSION_NAME)? .is_none() { eprintln!("Present extension is not supported"); exit(1); } // Create a window let win_id = conn.generate_id()?; let win_aux = CreateWindowAux::new().background_pixel(screen.white_pixel); conn.create_window( COPY_DEPTH_FROM_PARENT, win_id, screen.root, 0, 0, 10, 10, 0, WindowClass::INPUT_OUTPUT, 0, &win_aux, )?; // Ask for present ConfigureNotify events let event_id = conn.generate_id()?; present::select_input( &conn, event_id, win_id, present::EventMask::CONFIGURE_NOTIFY, )?; // Cause an event conn.configure_window(win_id, &ConfigureWindowAux::new().width(20))?; // Wait for the event conn.flush()?; let event = conn.wait_for_event()?; // Now check that the event really is what we wanted to get let event = match event { Event::PresentConfigureNotify(event) => event, other => panic!("Unexpected event {:?}", other), }; println!( "Got a Present ConfigureNotify event for event ID 0x{:x} and window 0x{:x}.", event.event, event.window ); println!( "x={}, y={}, width={}, height={}, off_x={}, off_y={}, pixmap_width={}, pixmap_height={}, \ pixmap_flags={:x}", event.x, event.y, event.width, event.height, event.off_x, event.off_y, event.pixmap_width, event.pixmap_height, event.pixmap_flags, ); assert_eq!( (20, 10, 0), (event.pixmap_width, event.pixmap_height, event.pixmap_flags) ); Ok(()) } x11rb-0.8.1/examples/hypnomoire.rs010064400017500001750000000171651402220031600152130ustar 00000000000000// This is a (rough) port of hypnomoire from the xcb-demo repository. // The original file has Copyright (C) 2001-2002 Bart Massey and Jamey Sharp and is licensed under // a MIT license. extern crate x11rb; use std::f64::consts::PI; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; use x11rb::connection::Connection; use x11rb::errors::{ReplyError, ReplyOrIdError}; use x11rb::protocol::xproto::*; use x11rb::protocol::Event; use x11rb::wrapper::ConnectionExt as _; use x11rb::COPY_DEPTH_FROM_PARENT; /// Lag angle for the follow line const LAG: f64 = 0.3; /// Frames per second const FRAME_RATE: u64 = 10; /// Number of windows to show const WINS: usize = 3; #[derive(Default)] struct WindowState { window: Window, pixmap: Pixmap, angle_velocity: f64, } fn main() { let (conn, screen_num) = x11rb::connect(None).unwrap(); let conn = Arc::new(conn); let screen = &conn.setup().roots[screen_num]; let white = conn.generate_id().unwrap(); let black = conn.generate_id().unwrap(); conn.create_gc( white, screen.root, &CreateGCAux::new() .graphics_exposures(0) .foreground(screen.white_pixel), ) .unwrap(); conn.create_gc( black, screen.root, &CreateGCAux::new() .graphics_exposures(0) .foreground(screen.black_pixel), ) .unwrap(); let windows: Vec<_> = (0..WINS) .map(|_| Arc::new(Mutex::new(WindowState::default()))) .collect(); for win in windows.iter() { let conn2 = Arc::clone(&conn); let win = Arc::clone(&win); thread::spawn(move || run(conn2, win, screen_num, white, black)); } event_thread(conn, windows, white).unwrap(); } fn run( conn: Arc, window_state: Arc>, screen_num: usize, white: Gcontext, black: Gcontext, ) -> Result<(), ReplyOrIdError> { let wm_protocols = conn.intern_atom(false, b"WM_PROTOCOLS")?; let wm_delete_window = conn.intern_atom(false, b"WM_DELETE_WINDOW")?; let wm_protocols = wm_protocols.reply().unwrap().atom; let wm_delete_window = wm_delete_window.reply().unwrap().atom; let screen = &conn.setup().roots[screen_num]; let default_size = 300; let pixmap = conn.generate_id()?; let window = conn.generate_id()?; { let mut guard = window_state.lock().unwrap(); guard.pixmap = pixmap; guard.window = window; guard.angle_velocity = 0.05; } conn.create_window( COPY_DEPTH_FROM_PARENT, window, screen.root, 0, // x 0, // y default_size, // width default_size, // height 0, WindowClass::INPUT_OUTPUT, screen.root_visual, &CreateWindowAux::new() .background_pixel(screen.white_pixel) .event_mask( EventMask::BUTTON_RELEASE | EventMask::EXPOSURE | EventMask::STRUCTURE_NOTIFY, ) .do_not_propogate_mask(EventMask::BUTTON_PRESS), )?; conn.change_property32( PropMode::REPLACE, window, wm_protocols, AtomEnum::ATOM, &[wm_delete_window], )?; conn.map_window(window)?; conn.create_pixmap( screen.root_depth, pixmap, window, default_size, default_size, )?; let rect = Rectangle { x: 0, y: 0, width: default_size, height: default_size, }; conn.poly_fill_rectangle(pixmap, white, &[rect])?; let mut theta: f64 = 0.0; let radius = f64::from(default_size) + 1.0; loop { let guard = window_state.lock().unwrap(); let (center_x, center_y) = (default_size as i16 / 2, default_size as i16 / 2); let (sin, cos) = theta.sin_cos(); let (x, y) = ((radius * cos) as i16, (radius * sin) as i16); let lines = [ Point { x: center_x, y: center_y, }, Point { x, y }, ]; conn.poly_line(CoordMode::PREVIOUS, pixmap, black, &lines)?; let (sin, cos) = (theta + LAG).sin_cos(); let (x, y) = ((radius * cos) as i16, (radius * sin) as i16); let lines = [ Point { x: center_x, y: center_y, }, Point { x, y }, ]; conn.poly_line(CoordMode::PREVIOUS, pixmap, white, &lines)?; conn.copy_area( pixmap, window, white, 0, 0, 0, 0, default_size, default_size, )?; conn.flush()?; theta += guard.angle_velocity; while theta > 2.0 * PI { theta -= 2.0 * PI; } while theta < 0.0 { theta += 2.0 * PI; } drop(guard); thread::sleep(Duration::from_micros(1_000_000 / FRAME_RATE)); } } fn event_thread( conn_arc: Arc, windows: Vec>>, white: Gcontext, ) -> Result<(), ReplyError> where C: Connection + Send + Sync + 'static, { let mut first_window_mapped = false; let conn = &*conn_arc; loop { let event = conn.wait_for_event()?; match event { Event::Expose(event) => { if let Some(state) = find_window_by_id(&windows, event.window) { let state = state.lock().unwrap(); conn.copy_area( state.pixmap, state.window, white, event.x as _, event.y as _, event.x as _, event.y as _, event.width, event.height, )?; if event.count == 0 { conn.flush()?; } } else { eprintln!("Expose on unknown window!"); } } Event::ButtonRelease(event) => { if let Some(state) = find_window_by_id(&windows, event.event) { let mut state = state.lock().unwrap(); match event.detail { // Button 1 is left mouse button 1 => state.angle_velocity *= -1.0, // Buttons 4 and 5 are mouse wheel 4 => state.angle_velocity += 0.001, 5 => state.angle_velocity -= 0.001, _ => {} } } else { eprintln!("ButtonRelease on unknown window!"); } } Event::MapNotify(event) => { if !first_window_mapped { first_window_mapped = true; util::start_timeout_thread(conn_arc.clone(), event.window); } } Event::ClientMessage(_) => { // We simply assume that this is a message to close. Since we are the main thread, // everything closes when we exit. return Ok(()); } Event::Error(err) => { eprintln!("Got an X11 error: {:?}", err); } _ => {} } } } fn find_window_by_id( windows: &[Arc>], window: Window, ) -> Option<&Arc>> { windows.iter().find(|state| { state .lock() .map(|state| state.window == window) .unwrap_or(false) }) } include!("integration_test_util/util.rs"); x11rb-0.8.1/examples/integration_test_util/util.rs010064400017500001750000000041521402220031600204060ustar 00000000000000// As far as I can see, I cannot easily share code between different examples. The following code // is used by several examples to react to the $X11RB_EXAMPLE_TIMEOUT variable. This code is // include!()d in the examples mod util { use std::env; use std::sync::Arc; use std::thread; use std::time::Duration; use x11rb::connection::Connection; use x11rb::protocol::xproto::{ ClientMessageData, ClientMessageEvent, ConnectionExt as _, EventMask, CLIENT_MESSAGE_EVENT, Window, }; use x11rb::x11_utils::TryParse; pub fn start_timeout_thread(conn: Arc, window: Window) where C: Connection + Send + Sync + 'static, { let timeout = match env::var("X11RB_EXAMPLE_TIMEOUT") .ok() .and_then(|str| str.parse().ok()) { None => return, Some(timeout) => timeout, }; thread::spawn(move || { let wm_protocols = conn.intern_atom(false, b"WM_PROTOCOLS").unwrap(); let wm_delete_window = conn.intern_atom(false, b"WM_DELETE_WINDOW").unwrap(); thread::sleep(Duration::from_secs(timeout)); let mut data = [0; 20]; data[..4].copy_from_slice(&wm_delete_window.reply().unwrap().atom.to_ne_bytes()); let (data, _): (ClientMessageData, _) = TryParse::try_parse(&data).unwrap(); let event = ClientMessageEvent { response_type: CLIENT_MESSAGE_EVENT, format: 32, sequence: 0, window, type_: wm_protocols.reply().unwrap().atom, data, }; if let Err(err) = conn.send_event(false, window, EventMask::NO_EVENT, &event) { eprintln!("Error while sending event: {:?}", err); } if let Err(err) = conn.send_event( false, window, EventMask::SUBSTRUCTURE_REDIRECT, &event, ) { eprintln!("Error while sending event: {:?}", err); } conn.flush().unwrap(); }); } } x11rb-0.8.1/examples/list_fonts.rs010064400017500001750000000025121402220031600151740ustar 00000000000000// This program should produce output identical to `xlsfonts -lu`. extern crate x11rb; use x11rb::protocol::xproto::{ConnectionExt, FontDraw}; fn main() { let (conn, _) = x11rb::connect(None).unwrap(); println!("DIR MIN MAX EXIST DFLT PROP ASC DESC NAME"); for reply in conn.list_fonts_with_info(u16::max_value(), b"*").unwrap() { let reply = reply.unwrap(); let dir = if reply.draw_direction == FontDraw::LEFT_TO_RIGHT { "-->" } else if reply.draw_direction == FontDraw::RIGHT_TO_LEFT { "<--" } else { "???" }; let (min, max, indicator) = if reply.min_byte1 == 0 && reply.max_byte1 == 0 { (reply.min_char_or_byte2, reply.max_char_or_byte2, ' ') } else { (u16::from(reply.min_byte1), u16::from(reply.max_byte1), '*') }; let all = if reply.all_chars_exist { "all" } else { "some" }; let name = String::from_utf8_lossy(&reply.name); println!( "{} {}{:3} {}{:3} {:>5} {:4} {:4} {:3} {:4} {}", dir, indicator, min, indicator, max, all, reply.default_char, reply.properties.len(), reply.font_ascent, reply.font_descent, name ); } } x11rb-0.8.1/examples/record.rs010064400017500001750000000143261402220031600142740ustar 00000000000000// This example shows how to use the record extension. // // The short version is: You do not want to use the record extension. // // The long version is: It's ugly and here is how it works. // // If you want to learn more about the record extension, it is recommended to read // https://www.x.org/releases/X11R7.6/doc/recordproto/record.html // // This example is based on // https://github.com/nibrahim/showkeys/blob/master/tests/record-example.c, which is GPLv3 and // contains no copyright information. According to the git history, it was written by // Noufal Ibrahim in 2011. use std::convert::TryFrom; use x11rb::connection::Connection; use x11rb::connection::RequestConnection; use x11rb::errors::ParseError; use x11rb::protocol::record::{self, ConnectionExt as _}; use x11rb::protocol::xproto; use x11rb::wrapper::ConnectionExt; use x11rb::x11_utils::TryParse; fn main() -> Result<(), Box> { // From https://www.x.org/releases/X11R7.6/doc/recordproto/record.html: // "The typical communication model for a recording client is to open two connections to the // server and use one for RC control and the other for reading protocol data." let (ctrl_conn, _) = x11rb::connect(None)?; let (data_conn, _) = x11rb::connect(None)?; // Check if the record extension is supported. if ctrl_conn .extension_information(record::X11_EXTENSION_NAME)? .is_none() { eprintln!("The X11 server does not support the RECORD extension"); return Ok(()); } let ver = ctrl_conn .record_query_version( record::X11_XML_VERSION.0 as _, record::X11_XML_VERSION.1 as _, )? .reply()?; println!( "requested RECORD extension version {:?}, server supports {:?}", record::X11_XML_VERSION, (ver.major_version, ver.minor_version) ); // Set up a recording context let rc = ctrl_conn.generate_id()?; let empty = record::Range8 { first: 0, last: 0 }; let empty_ext = record::ExtRange { major: empty, minor: record::Range16 { first: 0, last: 0 }, }; let range = record::Range { core_requests: empty, core_replies: empty, ext_requests: empty_ext, ext_replies: empty_ext, delivered_events: empty, device_events: record::Range8 { // We want notification of core X11 events between key press and motion notify first: xproto::KEY_PRESS_EVENT, last: xproto::MOTION_NOTIFY_EVENT, }, errors: empty, client_started: false, client_died: false, }; ctrl_conn .record_create_context(rc, 0, &[record::CS::ALL_CLIENTS.into()], &[range])? .check()?; // Apply a timeout if we are requested to do so. match std::env::var("X11RB_EXAMPLE_TIMEOUT") .ok() .and_then(|str| str.parse().ok()) { None => {} Some(timeout) => { std::thread::spawn(move || { std::thread::sleep(std::time::Duration::from_secs(timeout)); ctrl_conn.record_disable_context(rc).unwrap(); ctrl_conn.sync().unwrap(); }); } } // The above check() makes sure that the server already handled the CreateContext request. // Alternatively, we could do ctrl_conn.sync() here for the same effect. // We now switch to using "the other" connection. // FIXME: These constants should be added to the XML const START_OF_DATA: u8 = 4; const RECORD_FROM_SERVER: u8 = 0; for reply in data_conn.record_enable_context(rc)? { let reply = reply?; if reply.client_swapped { println!("Byte swapped clients are unsupported"); } else if reply.category == RECORD_FROM_SERVER { let mut remaining = &reply.data[..]; let mut should_exit = false; while !remaining.is_empty() { let (r, exit) = print_reply_data(&reply.data)?; remaining = r; if exit { should_exit = true; } } if should_exit { break; } } else if reply.category == START_OF_DATA { println!("Press Escape to exit..."); } else { println!("Got a reply with an unsupported category: {:?}", reply); } } Ok(()) } // Print a single reply data packet and return the remaining data. When escape is pressed, true is // also returned to indicate that we should exit. fn print_reply_data(data: &[u8]) -> Result<(&[u8], bool), ParseError> { match data[0] { xproto::KEY_PRESS_EVENT => { let (event, remaining) = xproto::KeyPressEvent::try_parse(data)?; println!("key press: {:?}", event); Ok((remaining, false)) } xproto::KEY_RELEASE_EVENT => { let (event, remaining) = xproto::KeyReleaseEvent::try_parse(data)?; println!("key release: {:?}", event); Ok((remaining, event.detail == 9)) } xproto::BUTTON_PRESS_EVENT => { let (event, remaining) = xproto::ButtonPressEvent::try_parse(data)?; println!("button press: {:?}", event); Ok((remaining, false)) } xproto::BUTTON_RELEASE_EVENT => { let (event, remaining) = xproto::ButtonReleaseEvent::try_parse(data)?; println!("button release: {:?}", event); Ok((remaining, false)) } xproto::MOTION_NOTIFY_EVENT => { let (event, remaining) = xproto::MotionNotifyEvent::try_parse(data)?; println!("motion notify: {:?}", event); Ok((remaining, false)) } 0 => { // This is a reply, we compute its length as follows let (length, _) = u32::try_parse(&data[4..])?; let length = usize::try_from(length).unwrap() * 4 + 32; println!("unparsed reply: {:?}", &data[..length]); Ok((&data[length..], false)) } _ => { // Error or event, they always have length 32 // TODO: What about XGE events? println!("unparsed error/event: {:?}", &data[..32]); Ok((&data[32..], false)) } } } x11rb-0.8.1/examples/shared_memory.rs010064400017500001750000000120631402220031600156500ustar 00000000000000extern crate x11rb; use std::fs::{remove_file, File, OpenOptions}; use std::io::{Result as IOResult, Write}; #[cfg(unix)] use std::os::unix::io::AsRawFd; use std::ptr::null_mut; use libc::{mmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE}; use x11rb::connection::Connection; use x11rb::errors::{ConnectionError, ReplyError, ReplyOrIdError}; use x11rb::protocol::shm::{self, ConnectionExt as _}; use x11rb::protocol::xproto::{self, ConnectionExt as _, ImageFormat}; const TEMP_FILE_CONTENT: [u8; 8] = [0x00, 0x01, 0x02, 0x03, 0xff, 0xfe, 0xfd, 0xfc]; struct FreePixmap<'c, C: Connection>(&'c C, xproto::Pixmap); impl Drop for FreePixmap<'_, C> { fn drop(&mut self) { self.0.free_pixmap(self.1).unwrap(); } } /// Get the supported SHM version from the X11 server fn check_shm_version(conn: &C) -> Result, ReplyError> { if conn .extension_information(shm::X11_EXTENSION_NAME)? .is_none() { return Ok(None); } let shm_version = conn.shm_query_version()?.reply()?; Ok(Some((shm_version.major_version, shm_version.minor_version))) } /// Get the bytes describing the first pixel at the given offset of the given shared memory segment /// (interpreted in the screen's root_visual) fn get_shared_memory_content_at_offset( conn: &C, screen: &xproto::Screen, shmseg: shm::Seg, offset: u32, ) -> Result, ReplyOrIdError> { let width = match screen.root_depth { 24 => 1, 16 => 2, 8 => 4, _ => panic!("I do not know how to handle depth {}", screen.root_depth), }; let pixmap = conn.generate_id()?; conn.shm_create_pixmap( pixmap, screen.root, width, 1, screen.root_depth, shmseg, offset, )?; let pixmap = FreePixmap(conn, pixmap); let image = xproto::get_image(conn, ImageFormat::Z_PIXMAP, pixmap.1, 0, 0, width, 1, !0)?.reply()?; Ok(image.data) } fn use_shared_mem( conn: &C, screen_num: usize, shmseg: shm::Seg, ) -> Result<(), ReplyOrIdError> { let screen = &conn.setup().roots[screen_num]; let content = get_shared_memory_content_at_offset(conn, screen, shmseg, 0)?; assert_eq!(content[..], TEMP_FILE_CONTENT[0..4]); let content = get_shared_memory_content_at_offset(conn, screen, shmseg, 4)?; assert_eq!(content[..], TEMP_FILE_CONTENT[4..8]); Ok(()) } /// Make a temporary file fn make_file() -> IOResult { let file_name = "shared_memory.bin"; let mut file = OpenOptions::new() .create(true) .read(true) .write(true) .truncate(true) .open(file_name)?; file.write_all(&TEMP_FILE_CONTENT)?; remove_file(file_name)?; Ok(file) } fn send_fd(conn: &C, screen_num: usize, file: File) -> Result<(), ReplyOrIdError> { let shmseg = conn.generate_id()?; conn.shm_attach_fd(shmseg, file, false)?; use_shared_mem(conn, screen_num, shmseg)?; conn.shm_detach(shmseg)?; Ok(()) } fn receive_fd(conn: &C, screen_num: usize) -> Result<(), ReplyOrIdError> { let shmseg = conn.generate_id()?; let segment_size = TEMP_FILE_CONTENT.len() as _; let reply = conn .shm_create_segment(shmseg, segment_size, false)? .reply()?; let shm::CreateSegmentReply { shm_fd, .. } = reply; let addr = unsafe { mmap( null_mut(), segment_size as _, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd.as_raw_fd(), 0, ) }; if addr == MAP_FAILED { conn.shm_detach(shmseg)?; return Err(ConnectionError::InsufficientMemory.into()); } unsafe { let slice = std::slice::from_raw_parts_mut(addr as *mut u8, segment_size as _); slice.copy_from_slice(&TEMP_FILE_CONTENT); } use_shared_mem(conn, screen_num, shmseg)?; conn.shm_detach(shmseg)?; // Let's ignore the munmap() that we should do here Ok(()) } fn main() { let file = make_file().expect("Failed to create temporary file for FD passing"); match x11rb::connect(None) { Err(err) => eprintln!("Failed to connect to the X11 server: {}", err), Ok((conn, screen_num)) => { // Check for SHM 1.2 support (needed for fd passing) if let Some((major, minor)) = check_shm_version(&conn).unwrap() { if major < 1 || (major == 1 && minor < 2) { eprintln!( "X11 server supports version {}.{} of the SHM extension, but version 1.2 \ is needed", major, minor, ); return; } } else { eprintln!("X11 server does not support SHM extension"); return; } println!("Trying to send an FD"); send_fd(&conn, screen_num, file).unwrap(); println!("Trying to receive an FD"); receive_fd(&conn, screen_num).unwrap(); } } } x11rb-0.8.1/examples/simple_window.rs010064400017500001750000000122451402220031600156740ustar 00000000000000extern crate x11rb; use x11rb::connection::Connection; use x11rb::cursor::Handle as CursorHandle; use x11rb::protocol::xproto::*; use x11rb::protocol::Event; use x11rb::resource_manager::Database; use x11rb::wrapper::ConnectionExt as _; fn main() { let (conn, screen_num) = x11rb::connect(None).unwrap(); // The following is only needed for start_timeout_thread(), which is used for 'tests' let conn1 = std::sync::Arc::new(conn); let conn = &*conn1; let screen = &conn.setup().roots[screen_num]; let win_id = conn.generate_id().unwrap(); let gc_id = conn.generate_id().unwrap(); let resource_db = Database::new_from_default(conn).unwrap(); let cursor_handle = CursorHandle::new(conn, screen_num, &resource_db).unwrap(); let wm_protocols = conn.intern_atom(false, b"WM_PROTOCOLS").unwrap(); let wm_delete_window = conn.intern_atom(false, b"WM_DELETE_WINDOW").unwrap(); let net_wm_name = conn.intern_atom(false, b"_NET_WM_NAME").unwrap(); let utf8_string = conn.intern_atom(false, b"UTF8_STRING").unwrap(); let wm_protocols = wm_protocols.reply().unwrap().atom; let wm_delete_window = wm_delete_window.reply().unwrap().atom; let net_wm_name = net_wm_name.reply().unwrap().atom; let utf8_string = utf8_string.reply().unwrap().atom; let cursor_handle = cursor_handle.reply().unwrap(); let win_aux = CreateWindowAux::new() .event_mask(EventMask::EXPOSURE | EventMask::STRUCTURE_NOTIFY | EventMask::NO_EVENT) .background_pixel(screen.white_pixel) .win_gravity(Gravity::NORTH_WEST) // Just because, we set the cursor to "wait" .cursor(cursor_handle.load_cursor(conn, "wait").unwrap()); let gc_aux = CreateGCAux::new().foreground(screen.black_pixel); let (mut width, mut height) = (100, 100); conn.create_window( screen.root_depth, win_id, screen.root, 0, 0, width, height, 0, WindowClass::INPUT_OUTPUT, 0, &win_aux, ) .unwrap(); util::start_timeout_thread(conn1.clone(), win_id); let title = "Simple Window"; conn.change_property8( PropMode::REPLACE, win_id, AtomEnum::WM_NAME, AtomEnum::STRING, title.as_bytes(), ) .unwrap(); conn.change_property8( PropMode::REPLACE, win_id, net_wm_name, utf8_string, title.as_bytes(), ) .unwrap(); conn.change_property32( PropMode::REPLACE, win_id, wm_protocols, AtomEnum::ATOM, &[wm_delete_window], ) .unwrap(); conn.change_property8( PropMode::REPLACE, win_id, AtomEnum::WM_CLASS, AtomEnum::STRING, b"simple_window\0simple_window\0", ) .unwrap(); conn.change_property8( PropMode::REPLACE, win_id, AtomEnum::WM_CLIENT_MACHINE, AtomEnum::STRING, // Text encoding in X11 is complicated. Let's use UTF-8 and hope for the best. gethostname::gethostname() .to_str() .unwrap_or("[Invalid]") .as_bytes(), ) .unwrap(); let reply = conn .get_property(false, win_id, AtomEnum::WM_NAME, AtomEnum::STRING, 0, 1024) .unwrap(); let reply = reply.reply().unwrap(); assert_eq!(reply.value, title.as_bytes()); conn.create_gc(gc_id, win_id, &gc_aux).unwrap(); conn.map_window(win_id).unwrap(); conn.flush().unwrap(); loop { let event = conn.wait_for_event().unwrap(); println!("{:?})", event); match event { Event::Expose(event) => { if event.count == 0 { // There already is a white background because we set background_pixel to white // when creating the window. let (width, height): (i16, i16) = (width as _, height as _); let points = [ Point { x: width, y: height, }, Point { x: -10, y: -10 }, Point { x: -10, y: height + 10, }, Point { x: width + 10, y: -10, }, ]; conn.poly_line(CoordMode::ORIGIN, win_id, gc_id, &points) .unwrap(); conn.flush().unwrap(); } } Event::ConfigureNotify(event) => { width = event.width; height = event.height; } Event::ClientMessage(event) => { let data = event.data.as_data32(); if event.format == 32 && event.window == win_id && data[0] == wm_delete_window { println!("Window was asked to close"); return; } } Event::Error(_) => println!("Got an unexpected error"), _ => println!("Got an unknown event"), } } } include!("integration_test_util/util.rs"); x11rb-0.8.1/examples/simple_window_manager.rs010064400017500001750000000363431402220031600173730ustar 00000000000000// A very simple reparenting window manager. // This WM does NOT follow ICCCM! extern crate x11rb; use std::cmp::Reverse; use std::collections::{BinaryHeap, HashSet}; use std::process::exit; use x11rb::connection::Connection; use x11rb::errors::{ReplyError, ReplyOrIdError}; use x11rb::protocol::xproto::*; use x11rb::protocol::{ErrorKind, Event}; use x11rb::{COPY_DEPTH_FROM_PARENT, CURRENT_TIME}; const TITLEBAR_HEIGHT: u16 = 20; const DRAG_BUTTON: Button = 1; /// The state of a single window that we manage #[derive(Debug)] struct WindowState { window: Window, frame_window: Window, x: i16, y: i16, width: u16, height: u16, } impl WindowState { fn new(window: Window, frame_window: Window, geom: &GetGeometryReply) -> WindowState { WindowState { window, frame_window, x: geom.x, y: geom.y, width: geom.width, height: geom.height, } } fn close_x_position(&self) -> i16 { std::cmp::max(0, self.width - TITLEBAR_HEIGHT) as _ } } /// The state of the full WM #[derive(Debug)] struct WMState<'a, C: Connection> { conn: &'a C, screen_num: usize, black_gc: Gcontext, windows: Vec, pending_expose: HashSet, wm_protocols: Atom, wm_delete_window: Atom, sequences_to_ignore: BinaryHeap>, // If this is Some, we are currently dragging the given window with the given offset relative // to the mouse. drag_window: Option<(Window, (i16, i16))>, } impl<'a, C: Connection> WMState<'a, C> { fn new(conn: &'a C, screen_num: usize) -> Result, ReplyOrIdError> { let screen = &conn.setup().roots[screen_num]; let black_gc = conn.generate_id()?; let font = conn.generate_id()?; conn.open_font(font, b"9x15")?; let gc_aux = CreateGCAux::new() .graphics_exposures(0) .background(screen.white_pixel) .foreground(screen.black_pixel) .font(font); conn.create_gc(black_gc, screen.root, &gc_aux)?; conn.close_font(font)?; let wm_protocols = conn.intern_atom(false, b"WM_PROTOCOLS")?; let wm_delete_window = conn.intern_atom(false, b"WM_DELETE_WINDOW")?; Ok(WMState { conn, screen_num, black_gc, windows: Vec::default(), pending_expose: HashSet::default(), wm_protocols: wm_protocols.reply()?.atom, wm_delete_window: wm_delete_window.reply()?.atom, sequences_to_ignore: Default::default(), drag_window: None, }) } /// Scan for already existing windows and manage them fn scan_windows(&mut self) -> Result<(), ReplyOrIdError> { // Get the already existing top-level windows. let screen = &self.conn.setup().roots[self.screen_num]; let tree_reply = self.conn.query_tree(screen.root)?.reply()?; // For each window, request its attributes and geometry *now* let mut cookies = Vec::with_capacity(tree_reply.children.len()); for win in tree_reply.children { let attr = self.conn.get_window_attributes(win)?; let geom = self.conn.get_geometry(win)?; cookies.push((win, attr, geom)); } // Get the replies and manage windows for (win, attr, geom) in cookies { let (attr, geom) = (attr.reply(), geom.reply()); if attr.is_err() || geom.is_err() { // Just skip this window continue; } let (attr, geom) = (attr.unwrap(), geom.unwrap()); if !attr.override_redirect && attr.map_state != MapState::UNMAPPED { self.manage_window(win, &geom)?; } } Ok(()) } /// Add a new window that should be managed by the WM fn manage_window( &mut self, win: Window, geom: &GetGeometryReply, ) -> Result<(), ReplyOrIdError> { println!("Managing window {:?}", win); let screen = &self.conn.setup().roots[self.screen_num]; assert!(self.find_window_by_id(win).is_none()); let frame_win = self.conn.generate_id()?; let win_aux = CreateWindowAux::new() .event_mask( EventMask::EXPOSURE | EventMask::SUBSTRUCTURE_NOTIFY | EventMask::BUTTON_PRESS | EventMask::BUTTON_RELEASE | EventMask::POINTER_MOTION | EventMask::ENTER_WINDOW, ) .background_pixel(screen.white_pixel); self.conn.create_window( COPY_DEPTH_FROM_PARENT, frame_win, screen.root, geom.x, geom.y, geom.width, geom.height + TITLEBAR_HEIGHT, 1, WindowClass::INPUT_OUTPUT, 0, &win_aux, )?; self.conn.grab_server()?; self.conn.change_save_set(SetMode::INSERT, win)?; let cookie = self .conn .reparent_window(win, frame_win, 0, TITLEBAR_HEIGHT as _)?; self.conn.map_window(win)?; self.conn.map_window(frame_win)?; self.conn.ungrab_server()?; self.windows.push(WindowState::new(win, frame_win, geom)); // Ignore all events caused by reparent_window(). All those events have the sequence number // of the reparent_window() request, thus remember its sequence number. The // grab_server()/ungrab_server() is done so that the server does not handle other clients // in-between, which could cause other events to get the same sequence number. self.sequences_to_ignore .push(Reverse(cookie.sequence_number() as u16)); Ok(()) } /// Draw the titlebar of a window fn redraw_titlebar(&self, state: &WindowState) -> Result<(), ReplyError> { let close_x = state.close_x_position(); self.conn.poly_line( CoordMode::ORIGIN, state.frame_window, self.black_gc, &[ Point { x: close_x, y: 0 }, Point { x: state.width as _, y: TITLEBAR_HEIGHT as _, }, ], )?; self.conn.poly_line( CoordMode::ORIGIN, state.frame_window, self.black_gc, &[ Point { x: close_x, y: TITLEBAR_HEIGHT as _, }, Point { x: state.width as _, y: 0, }, ], )?; let reply = self .conn .get_property( false, state.window, AtomEnum::WM_NAME, AtomEnum::STRING, 0, std::u32::MAX, )? .reply()?; self.conn .image_text8(state.frame_window, self.black_gc, 1, 10, &reply.value)?; Ok(()) } /// Do all pending work that was queued while handling some events fn refresh(&mut self) { while let Some(&win) = self.pending_expose.iter().next() { self.pending_expose.remove(&win); if let Some(state) = self.find_window_by_id(win) { if let Err(err) = self.redraw_titlebar(state) { eprintln!( "Error while redrawing window {:x?}: {:?}", state.window, err ); } } } } fn find_window_by_id(&self, win: Window) -> Option<&WindowState> { self.windows .iter() .find(|state| state.window == win || state.frame_window == win) } fn find_window_by_id_mut(&mut self, win: Window) -> Option<&mut WindowState> { self.windows .iter_mut() .find(|state| state.window == win || state.frame_window == win) } /// Handle the given event fn handle_event(&mut self, event: Event) -> Result<(), ReplyOrIdError> { let mut should_ignore = false; if let Some(seqno) = event.wire_sequence_number() { // Check sequences_to_ignore and remove entries with old (=smaller) numbers. while let Some(&Reverse(to_ignore)) = self.sequences_to_ignore.peek() { // Sequence numbers can wrap around, so we cannot simply check for // "to_ignore <= seqno". This is equivalent to "to_ignore - seqno <= 0", which is what we // check instead. Since sequence numbers are unsigned, we need a trick: We decide // that values from [MAX/2, MAX] count as "<= 0" and the rest doesn't. if to_ignore.wrapping_sub(seqno) <= u16::max_value() / 2 { // If the two sequence numbers are equal, this event should be ignored. should_ignore = to_ignore == seqno; break; } self.sequences_to_ignore.pop(); } } println!("Got event {:?}", event); if should_ignore { println!(" [ignored]"); return Ok(()); } match event { Event::UnmapNotify(event) => self.handle_unmap_notify(event), Event::ConfigureRequest(event) => self.handle_configure_request(event)?, Event::MapRequest(event) => self.handle_map_request(event)?, Event::Expose(event) => self.handle_expose(event), Event::EnterNotify(event) => self.handle_enter(event)?, Event::ButtonPress(event) => self.handle_button_press(event), Event::ButtonRelease(event) => self.handle_button_release(event)?, Event::MotionNotify(event) => self.handle_motion_notify(event)?, _ => {} } Ok(()) } fn handle_unmap_notify(&mut self, event: UnmapNotifyEvent) { let root = self.conn.setup().roots[self.screen_num].root; let conn = self.conn; self.windows.retain(|state| { if state.window != event.window { return true; } conn.change_save_set(SetMode::DELETE, state.window).unwrap(); conn.reparent_window(state.window, root, state.x, state.y) .unwrap(); conn.destroy_window(state.frame_window).unwrap(); false }); } fn handle_configure_request(&mut self, event: ConfigureRequestEvent) -> Result<(), ReplyError> { if let Some(state) = self.find_window_by_id_mut(event.window) { let _ = state; unimplemented!(); } // Allow clients to change everything, except sibling / stack mode let aux = ConfigureWindowAux::from_configure_request(&event) .sibling(None) .stack_mode(None); println!("Configure: {:?}", aux); self.conn.configure_window(event.window, &aux)?; Ok(()) } fn handle_map_request(&mut self, event: MapRequestEvent) -> Result<(), ReplyOrIdError> { self.manage_window( event.window, &self.conn.get_geometry(event.window)?.reply()?, ) } fn handle_expose(&mut self, event: ExposeEvent) { self.pending_expose.insert(event.window); } fn handle_enter(&mut self, event: EnterNotifyEvent) -> Result<(), ReplyError> { if let Some(state) = self.find_window_by_id(event.event) { // Set the input focus (ignoring ICCCM's WM_PROTOCOLS / WM_TAKE_FOCUS) self.conn .set_input_focus(InputFocus::PARENT, state.window, CURRENT_TIME)?; // Also raise the window to the top of the stacking order self.conn.configure_window( state.frame_window, &ConfigureWindowAux::new().stack_mode(StackMode::ABOVE), )?; } Ok(()) } fn handle_button_press(&mut self, event: ButtonPressEvent) { if event.detail != DRAG_BUTTON || event.state != 0 { return; } if let Some(state) = self.find_window_by_id(event.event) { if self.drag_window.is_none() && event.event_x < state.close_x_position() { let (x, y) = (-event.event_x, -event.event_y); self.drag_window = Some((state.frame_window, (x, y))); } } } fn handle_button_release(&mut self, event: ButtonReleaseEvent) -> Result<(), ReplyError> { if event.detail == DRAG_BUTTON { self.drag_window = None; } if let Some(state) = self.find_window_by_id(event.event) { if event.event_x >= state.close_x_position() { let data = [self.wm_delete_window, 0, 0, 0, 0]; let event = ClientMessageEvent { response_type: CLIENT_MESSAGE_EVENT, format: 32, sequence: 0, window: state.window, type_: self.wm_protocols, data: data.into(), }; self.conn .send_event(false, state.window, EventMask::NO_EVENT, &event)?; } } Ok(()) } fn handle_motion_notify(&mut self, event: MotionNotifyEvent) -> Result<(), ReplyError> { if let Some((win, (x, y))) = self.drag_window { let (x, y) = (x + event.root_x, y + event.root_y); // Sigh, X11 and its mixing up i16 and i32 let (x, y) = (x as i32, y as i32); self.conn .configure_window(win, &ConfigureWindowAux::new().x(x).y(y))?; } Ok(()) } } fn become_wm(conn: &C, screen: &Screen) -> Result<(), ReplyError> { // Try to become the window manager. This causes an error if there is already another WM. let change = ChangeWindowAttributesAux::default() .event_mask(EventMask::SUBSTRUCTURE_REDIRECT | EventMask::SUBSTRUCTURE_NOTIFY); let res = conn.change_window_attributes(screen.root, &change)?.check(); if let Err(ReplyError::X11Error(error)) = res { if error.error_kind == ErrorKind::Access { eprintln!("Another WM is already running."); exit(1); } else { res } } else { res } } fn main() { let (conn, screen_num) = x11rb::connect(None).unwrap(); // The following is only needed for start_timeout_thread(), which is used for 'tests' let conn1 = std::sync::Arc::new(conn); let conn = &*conn1; let screen = &conn.setup().roots[screen_num]; become_wm(conn, screen).unwrap(); let mut wm_state = WMState::new(conn, screen_num).unwrap(); wm_state.scan_windows().unwrap(); util::start_timeout_thread(conn1.clone(), screen.root); loop { wm_state.refresh(); conn.flush().unwrap(); let event = conn.wait_for_event().unwrap(); let mut event_option = Some(event); while let Some(event) = event_option { if let Event::ClientMessage(_) = event { // This is start_timeout_thread() signaling us to close (most likely). return; } wm_state.handle_event(event).unwrap(); event_option = conn.poll_for_event().unwrap(); } } } include!("integration_test_util/util.rs"); x11rb-0.8.1/examples/tutorial.rs010064400017500001750000003240531402220031600146620ustar 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////// // // This file contains a tutorial of both this crate and the X11 protocol. It was created by porting // an existing libxcb tutorial that is available here: // // https://www.x.org/releases/X11R7.7/doc/libxcb/tutorial/index.html // // References to libxcb in the text were retained. Only the code examples were adapted, where // possible. Some detailed explanations of libxcb required heavier editing. // // Since the libxcb tutorial is part of the libxcb source code, I assume that its MIT LICENSE // applies. The exact situation is a bit unclear (libxcb's COPYING file has "Copyright (C) // 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett.", but the git history says that the // tutorial was only started in 2006 and was last touched in 2014). // // This tutorial is in a Rust file to ensure that the contained code actually compiles and // everything works as intended. Nothing is worse than bitrotted tutorial. Here are all the // imports: extern crate x11rb; use std::error::Error; use x11rb::connection::{Connection, SequenceNumber}; use x11rb::errors::{ConnectionError, ReplyError, ReplyOrIdError}; use x11rb::protocol::xproto::*; use x11rb::protocol::Event; use x11rb::wrapper::ConnectionExt as _; use x11rb::COPY_DEPTH_FROM_PARENT; /////////////////////////////////////////////////////////////////////////////////////////////////// // // Introduction // ============ // // This tutorial is based on the [Xlib Tutorial] written by Guy Keren. The author allowed me to // take some parts of his text, mainly the text which deals with the X Windows generality. // // [Xlib Tutorial](http://users.actcom.co.il/~choo/lupg/tutorials/xlib-programming/xlib-programming.html) // // This tutorial is intended for people who want to start to program with the [XCB] library. keep // in mind that XCB, like the [Xlib] library, isn't what most programmers wanting to write X // applications are looking for. They should use a much higher level GUI toolkit like Motif, // [LessTiff], [GTK], [QT], [EWL], [ETK], or use [Cairo]. However, we need to start somewhere. More // than this, knowing how things work down below is never a bad idea. // // [XCB](http://xcb.freedesktop.org) // [Xlib](http://tronche.com/gui/x/xlib/introduction) // [LessTiff](http://www.lesstif.org) // [GTK](http://www.gtk.org) // [QT](http://www.trolltech.com) // [EWL](http://www.enlightenment.org) // [ETK](http://www.enlightenment.org) // [Cairo](http://cairographics.org) // // After reading this tutorial, one should be able to write very simple graphical programs, but not // programs with decent user interfaces. For such programs, one of the previously mentioned // libraries should be used. // // But what is XCB? Xlib has been the standard C binding for the [X Window System] protocol for // many years now. It is an excellent piece of work, but there are applications for which it is not // ideal, for example: // // [X Window System](http://www.x.org) // // * **Small platforms**: Xlib is a large piece of code, and it's difficult to make it smaller // * **Latency hiding**: Xlib requests requiring a reply are effectively synchronous: they block // until the reply appears, whether the result is needed immediately or // not. // * **Direct access to the protocol**: Xlib does quite a bit of caching, layering, and similar // optimizations. While this is normally a feature, it makes it difficult // to simply emit specified X protocol requests and process specific // responses. // * **Threaded applications**: While Xlib does attempt to support multithreading, the API makes // this difficult and error-prone. // * **New extensions**: The Xlib infrastructure provides limited support for the new creation of // X extension client side code. // // For these reasons, among others, XCB, an X C binding, has been designed to solve the above // problems and thus provide a base for // // * Toolkit implementation. // * Direct protocol-level programming. // * Lightweight emulation of commonly used portions of the Xlib API. // // // The client and server model of the X window system // ================================================== // // The X Window System was developed with one major goal: flexibility. The idea was that the way // things look is one thing, but the way things work is another matter. Thus, the lower levels // provide the tools required to draw windows, handle user input, allow drawing graphics using // colors (or black and white screens), etc. To this point, a decision was made to separate the // system into two parts. A client that decides what to do, and a server that actually draws on the // screen and reads user input in order to send it to the client for processing. // // This model is the complete opposite of what is used to when dealing with clients and servers. In // our case, the user sits near the machine controlled by the server, while the client might be // running on a remote machine. The server controls the screens, mouse and keyboard. A client may // connect to the server, request that it draws a window (or several windows), and ask the server // to send it any input the user sends to these windows. Thus, several clients may connect to a // single X server (one might be running mail software, one running a WWW browser, etc). When input // is sent by the user to some window, the server sends a message to the client controlling this // window for processing. The client decides what to do with this input, and sends the server // requests for drawing in the window. // // The whole session is carried out using the X message protocol. This protocol was originally // carried over the TCP/IP protocol suite, allowing the client to run on any machine connected to // the same network that the server is. Later on, the X servers were extended to allow clients // running on the local machine with more optimized access to the server (note that an X protocol // message may be several hundreds of KB in size), such as using shared memory, or using Unix // domain sockets (a method for creating a logical channel on a Unix system between two processes). // // // GUI programming: the asynchronous model // ======================================= // // Unlike conventional computer programs, that carry some serial nature, a GUI program usually uses // an asynchronous programming model, also known as "event-driven programming". This means that // that program mostly sits idle, waiting for events sent by the X server, and then acts upon these // events. An event may say "The user pressed the 1st button mouse in spot (x,y)", or "The window // you control needs to be redrawn". In order for the program to be responsive to the user input, // as well as to refresh requests, it needs to handle each event in a rather short period of time // (e.g. less that 200 milliseconds, as a rule of thumb). // // This also implies that the program may not perform operations that might take a long time while // handling an event (such as opening a network connection to some remote server, or connecting to // a database server, or even performing a long file copy operation). Instead, it needs to perform // all these operations in an asynchronous manner. This may be done by using various asynchronous // models to perform the longish operations, or by performing them in a different process or // thread. // // So the way a GUI program looks is something like that: // 1. Perform initialization routines. // 2. Connect to the X server. // 3. Perform X-related initialization. // 4. While not finished: // 1. Receive the next event from the X server. // 2. Handle the event, possibly sending various drawing requests to the X server. // 3. If the event was a quit message, exit the loop. // 5. Close down the connection to the X server. // 6. Perform cleanup operations. // // // Basic XCB notions // ================= // // XCB has been created to eliminate the need for programs to actually implement the X protocol // layer. This library gives a program a very low-level access to any X server. Since the protocol // is standardized, a client using any implementation of XCB may talk with any X server (the same // occurs for Xlib, of course). We now give a brief description of the basic XCB notions. They will // be detailed later. // // // The X Connection // ---------------- // // The major notion of using XCB is the X Connection. This is a structure representing the // connection we have open with a given X server. It hides a queue of messages coming from the // server, and a queue of pending requests that our client intends to send to the server. In XCB, // this structure is named 'xcb_connection_t'. It is analogous to the Xlib Display. When we open a // connection to an X server, the library returns a pointer to such a structure. Later, we supply // this pointer to any XCB function that should send messages to the X server or receive messages // from this server. // // // Requests and replies: the Xlib killers // -------------------------------------- // // To ask for information from the X server, we have to make a request and ask for a reply. With // Xlib, these two tasks are automatically done: Xlib locks the system, sends a request, waits for // a reply from the X server and unlocks. This is annoying, especially if one makes a lot of // requests to the X server. Indeed, Xlib has to wait for the end of a reply before asking for the // next request (because of the locks that Xlib sends). For example, here is a time-line of N=4 // requests/replies with Xlib, with a round-trip latency **T_round_trip** that is 5 times long as // the time required to write or read a request/reply (**T_write/T_read**): // // W-----RW-----RW-----RW-----R // // * W: Writing request // * -: Stalled, waiting for data // * R: Reading reply // // The total time is N * (T_write + T_round_trip + T_read). // // With XCB, we can suppress most of the round-trips as the requests and the replies are not // locked. We usually send a request, then XCB returns to us a **cookie**, which is an identifier. // Then, later, we ask for a reply using this **cookie** and XCB returns a pointer to that reply. // Hence, with XCB, we can send a lot of requests, and later in the program, ask for all the // replies when we need them. Here is the time-line for 4 requests/replies when we use this // property of XCB: // // WWWW--RRRR // // The total time is N * T_write + max (0, T_round_trip - (N-1) * T_write) + N * T_read. // Which can be considerably faster than all those Xlib round-trips. // // Here is a program that computes the time to create 500 atoms with Xlib and XCB. It shows the Xlib way, the bad XCB way (which is similar to Xlib) and the good XCB way. On my computer, XCB is 25 times faster than Xlib. // #[allow(clippy::needless_collect)] fn example1() -> Result<(), Box> { use std::time::Instant; let (conn, _) = x11rb::connect(None)?; const COUNT: usize = 500; let mut atoms = [Into::::into(AtomEnum::NONE); COUNT]; // Init names let names = (0..COUNT).map(|i| format!("NAME{}", i)).collect::>(); // Bad use let start = Instant::now(); for i in 0..COUNT { atoms[i] = conn.intern_atom(false, names[i].as_bytes())?.reply()?.atom; } let diff = start.elapsed(); println!("bad use time: {:?}", diff); // Good use let start = Instant::now(); // The `collect` is needed to make sure that the closure passed to // `map` is called for every iteration before executing the for loop. let cookies = names .iter() .map(|name| conn.intern_atom(false, name.as_bytes())) .collect::>(); for (i, atom) in cookies.into_iter().enumerate() { atoms[i] = atom?.reply()?.atom; } let diff2 = start.elapsed(); println!("good use time: {:?}", diff2); println!( "ratio: {:?}", diff.as_nanos() as f64 / diff2.as_nanos() as f64 ); Ok(()) } // // The Graphic Context // ------------------- // // When we perform various drawing operations (graphics, text, etc), we may specify various options // for controlling how the data will be drawn (what foreground and background colors to use, how // line edges will be connected, what font to use when drawing some text, etc). In order to avoid // the need to supply hundreds of parameters to each drawing function, a graphical context // structure is used. We set the various drawing options in this structure, and then we pass a // pointer to this structure to any drawing routines. This is rather handy, as we often need to // perform several drawing requests with the same options. Thus, we would initialize a graphical // context, set the desired options, and pass this structure to all drawing functions. // // Note that graphic contexts have no client-side structure in XCB, they're just XIDs. Xlib has a // client-side structure because it caches the GC contents so it can avoid making redundant // requests, but of course XCB doesn't do that. // // // Events // ------ // // A structure is used to pass events received from the X server. XCB supports exactly the events // specified in the protocol (33 events). This structure contains the type of event received // (including a bit for whether it came from the server or another client), as well as the data // associated with the event (e.g. position on the screen where the event was generated, mouse // button associated with the event, region of the screen associated with a "redraw" event, etc). // The way to read the event's data depends on the event type. // // // Using XCB-based programs // ======================== // // [This part of the tutorial was not translated. Go read https://www.x.org/releases/X11R7.7/doc/libxcb/tutorial/index.html#use if you want. // // // Opening and closing the connection to an X server // ================================================= // // An X program first needs to open the connection to the X server. There is a function that opens // a connection. It requires the display name, or None. In the latter case, the display name will // be the one in the environment variable DISPLAY. // // pub fn connect(dpy_name: Option<&str>) -> Result<([...], usize), [...]>; // // The second tuple value provides the screen number used for the connection. The returned // structure describes an X11 connection and is opaque. Here is how the connection can be opened: fn example2() -> Result<(), Box> { let (conn, _screen) = x11rb::connect(None)?; // To close a connection, it suffices to drop the connection object drop(conn); Ok(()) } // Checking basic information about a connection // --------------------------------------------- // // Once we have opened a connection to an X server, we should check some basic information about // it: what screens it has, what is the size (width and height) of the screen, how many colors it // supports (black and white ? grey scale ?, 256 colors ? more ?), and so on. We get such // information from the x11rb::xproto::Screen structure: #[allow(unused)] #[derive(Debug, Clone)] pub struct RenamedScreen { pub root: u32, pub default_colormap: u32, pub white_pixel: u32, pub black_pixel: u32, pub current_input_masks: u32, pub width_in_pixels: u16, pub height_in_pixels: u16, pub width_in_millimeters: u16, pub height_in_millimeters: u16, pub min_installed_maps: u16, pub max_installed_maps: u16, pub root_visual: u32, pub backing_stores: u8, pub save_unders: u8, pub root_depth: u8, pub allowed_depths: Vec, } // Here is a small program that shows how to use get this struct: fn example3() -> Result<(), Box> { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; println!(); println!("Informations of screen {}:", screen.root); println!(" width.........: {}", screen.width_in_pixels); println!(" height........: {}", screen.height_in_pixels); println!(" white pixel...: {}", screen.white_pixel); println!(" black pixel...: {}", screen.black_pixel); println!(); Ok(()) } // Creating a basic window - the "hello world" program // =================================================== // // After we got some basic information about our screen, we can create our first window. In the X // Window System, a window is characterized by an Id. So, in XCB, a window is of type: // #[allow(unused)] pub type Window = u32; // We first ask for a new Id for our window, with this function: // // trait Connection { // fn generate_id(&self) -> u32; // } // // Then, XCB supplies the following function to create new windows: #[allow(unused, clippy::too_many_arguments)] fn own_create_window( c: &A, // The connection to use depth: u8, // Depth of the screen wid: u32, // Id of the window parent: u32, // Id of an existing window that should be the parent of the new window x: i16, // X position of the top-left corner of the window (in pixels) y: i16, // Y position of the top-left corner of the window (in pixels) width: u16, // Width of the window (in pixels) height: u16, // Height of the window (in pixels) border_width: u16, // Width of the window's border (in pixels) class: B, visual: u32, value_list: &CreateWindowAux, ) -> Result where B: Into, { unimplemented!(); } // The fact that we created the window does not mean that it will be drawn on screen. By default, // newly created windows are not mapped on the screen (they are invisible). In order to make our // window visible, we use the function `map_window()`, whose prototype is // // fn map_window(&self, window: u32) -> Result; // // Finally, here is a small program to create a window of size 150x150 pixels, positioned at the top-left corner of the screen: fn example4() -> Result<(), Box> { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; // Ask for our window's Id let win = conn.generate_id()?; // Create the window conn.create_window( COPY_DEPTH_FROM_PARENT, // depth (same as root) win, // window Id screen.root, // parent window 0, // x 0, // y 150, // width 150, // height 10, // border width WindowClass::INPUT_OUTPUT, // class screen.root_visual, // visual &Default::default(), )?; // masks, not used yet // Map the window on the screen conn.map_window(win)?; // Make sure commands are sent before the sleep, so window is shown conn.flush()?; std::thread::sleep(std::time::Duration::from_secs(10)); Ok(()) } // In this code, you see one more function - flush(), not explained yet. It is used to flush // all the pending requests. More precisely, there are 2 functions that do such things. The first // one is flush(): // // trait Connection { // fn flush(&self) -> Result<(), ConnectionError>; // } // // This function flushes all pending requests to the X server (much like the fflush() function is // used to flush standard output). The second function is xcb_aux_sync() / sync(): // // trait ConnectionExt { // fn sync(&self) -> Result<(), ReplyError>; // } // // This functions also flushes all pending requests to the X server, and then waits until the X // server finishing processing these requests. In a normal program, this will not be necessary // (we'll see why when we get to write a normal X program), but for now, we put it there. // // The window that is created by the above code has a non defined background. This one can be set // to a specific color, thanks to the two last parameters of `xcb_create_window()`, which are not // described yet. See the subsections [Configuring a window] or [Registering for event types using // event masks] for examples on how to use these parameters. In addition, as no events are handled, // you have to make a Ctrl-C to interrupt the program. // // // Drawing in a window // =================== // // Drawing in a window can be done using various graphical functions (drawing pixels, lines, // rectangles, etc). In order to draw in a window, we first need to define various general drawing // parameters (what line width to use, which color to draw with, etc). This is done using a // graphical context. // // // Allocating a Graphics Context // ----------------------------- // // As we said, a graphical context defines several attributes to be used with the various drawing // functions. For this, we define a graphical context. We can use more than one graphical context // with a single window, in order to draw in multiple styles (different colors, different line // widths, etc). In XCB, a Graphics Context is, as a window, characterized by an Id: // // pub type Gcontext = u32; // // We first ask the X server to attribute an Id to our graphic context with this function: // // trait Connection { // fn generate_id(&self) -> u32; // } // // Then, we set the attributes of the graphic context with this function: // #[allow(unused)] fn my_create_gc( c: &A, cid: u32, drawable: u32, value_list: &CreateGCAux, ) -> Result { unimplemented!(); } // The CreateGCAux parameter of this function is specific to x11rb. It contains all the optional // arguments of the request. It is defined like this: #[allow(unused)] #[derive(Debug, Clone, Copy, Default)] pub struct RenamedCreateGCAux { pub function: Option, pub plane_mask: Option, pub foreground: Option, pub background: Option, pub line_width: Option, pub line_style: Option, pub cap_style: Option, pub join_style: Option, pub fill_style: Option, pub fill_rule: Option, pub tile: Option, pub stipple: Option, pub tile_stipple_x_origin: Option, pub tile_stipple_y_origin: Option, pub font: Option, pub subwindow_mode: Option, pub graphics_exposures: Option, pub clip_x_origin: Option, pub clip_y_origin: Option, pub clip_mask: Option, pub dash_offset: Option, pub dashes: Option, pub arc_mode: Option, } // We give now an example on how to allocate a graphic context that specifies that each drawing // function that uses it will draw in foreground with a black color. fn example5() -> Result<(), Box> { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; // Create a black graphic context for drawing in the foreground. let win = screen.root; let black = conn.generate_id()?; let values = CreateGCAux::default().foreground(screen.black_pixel); conn.create_gc(black, win, &values)?; Ok(()) } // [The following is a bit XCB-specific, because CreateGCAux does not exist in libxcb.] // // Note should be taken regarding the role of "value_mask" and "value_list" in the prototype of // `xcb_create_gc()`. Since a graphic context has many attributes, and since we often just want to // define a few of them, we need to be able to tell the `xcb_create_gc()` which attributes we want // to set. This is what the "value_mask" parameter is for. We then use the "value_list" parameter // to specify actual values for the attribute we defined in "value_mask". Thus, for each constant // used in "value_list", we will use the matching constant in "value_mask". In this case, we define // a graphic context with one attribute: when drawing (a point, a line, etc), the foreground color // will be black. The rest of the attributes of this graphic context will be set to their default // values. // // See the next Subsection for more details. // // Changing the attributes of a Graphics Context // --------------------------------------------- // // Once we have allocated a Graphic Context, we may need to change its attributes (for example, // changing the foreground color we use to draw a line, or changing the attributes of the font we // use to display strings. See Subsections Drawing with a color and [Assigning a Font to a Graphic // Context]. This is done by using this function: // // fn change_gc(&self, gc: u32, value_list: &ChangeGCAux) -> Result; // // [Some more XCB-specific explanations skipped] // // Drawing primitives: point, line, box, circle,... // ------------------------------------------------ // // After we have created a Graphic Context, we can draw on a window using this Graphic Context, // with a set of XCB functions, collectively called "drawing primitives". Let see how they are // used. // // To draw a point, or several points, we use // // fn poly_point(&self, coordinate_mode: B, drawable: u32, gc: u32, // points: &[Point]) -> Result // where B: Into; // // The `coordinate_mode` parameter specifies the coordinate mode. Available values are // // pub enum CoordMode { // Origin, // Previous, // } // // If XCB_COORD_MODE_PREVIOUS is used, then all points but the first one are relative to the // immediately previous point. // // The `Point` type is just a structure with two fields (the coordinates of the point): // // #[derive(Debug, Clone, Copy)] // pub struct Point { // pub x: i16, // pub y: i16, // } // // You could see an example in xpoints.c. **TODO** Set the link. // // To draw a line, or a polygonal line, we use // // fn poly_line(&self, coordinate_mode: A, drawable: u32, gc: u32, points: &[Point]) // -> Result // where A: Into // // This function will draw the line between the first and the second points, then the line between // the second and the third points, and so on. // // To draw a segment, or several segments, we use // // fn poly_segment(&self, drawable: u32, gc: u32, segments: &[Segment]) -> Result; // // The `xcb_segment_t` type is just a structure with four fields (the coordinates of the two points that define the segment): // // pub struct Segment { // pub x1: i16, // pub y1: i16, // pub x2: i16, // pub y2: i16, // } // // To draw a rectangle, or several rectangles, we use // // fn poly_rectangle(&self, drawable: u32, gc: u32, rectangles: &[Rectangle]) -> Result; // // The `xcb_rectangle_t` type is just a structure with four fields (the coordinates of the top-left // corner of the rectangle, and its width and height): // // pub struct Rectangle { // pub x: i16, // pub y: i16, // pub width: u16, // pub height: u16, // } // // To draw an elliptical arc, or several elliptical arcs, we use // // fn poly_arc(&self, drawable: u32, gc: u32, arcs: &[Arc]) -> Result; // // The `xcb_arc_t` type is a structure with six fields: // // pub struct Arc { // pub x: i16, // pub y: i16, // pub width: u16, // pub height: u16, // pub angle1: i16, // pub angle2: i16, // } // // Note: the angles are expressed in units of 1/64 of a degree, so to have an angle of 90 degrees, // starting at 0,`angle1 = 0` and `angle2 = 90 << 6`. Positive angles indicate counterclockwise // motion, while negative angles indicate clockwise motion. // // The corresponding function which fill inside the geometrical object are listed below, without // further explanation, as they are used as the above functions. // // To Fill a polygon defined by the points given as arguments , we use // // fn fill_poly(&self, drawable: u32, gc: u32, shape: A, coordinate_mode: B, points: &[Point]) -> Result // where A: Into, B: Into // // The `shape` parameter specifies a shape that helps the server to improve performance. Available values are // // pub enum PolyShape { // Complex, // Nonconvex, // Convex, // } // // To fill one or several rectangles, we use // // fn poly_fill_rectangle(&self, drawable: u32, gc: u32, rectangles: &[Rectangle]) -> Result; // // To fill one or several arcs, we use // // fn poly_fill_arc(&self, drawable: u32, gc: u32, arcs: &[Arc]) -> Result; // // To illustrate these functions, here is an example that draws four points, a polygonal line, two // segments, two rectangles and two arcs. Remark that we use events for the first time, as an // introduction to the next section. fn example6() -> Result<(), Box> { // geometric objects let points = [ Point { x: 10, y: 10 }, Point { x: 10, y: 20 }, Point { x: 20, y: 10 }, Point { x: 20, y: 20 }, ]; let polyline = [ Point { x: 50, y: 10 }, Point { x: 5, y: 20 }, // Rest of points are relative Point { x: 25, y: -20 }, Point { x: 10, y: 10 }, ]; let segments = [ Segment { x1: 100, y1: 10, x2: 140, y2: 30, }, Segment { x1: 110, y1: 25, x2: 130, y2: 60, }, ]; let rectangles = [ Rectangle { x: 10, y: 50, width: 40, height: 20, }, Rectangle { x: 80, y: 50, width: 10, height: 40, }, ]; let arcs = [ Arc { x: 10, y: 100, width: 60, height: 40, angle1: 0, angle2: 90 << 6, }, Arc { x: 90, y: 100, width: 55, height: 40, angle1: 0, angle2: 270 << 6, }, ]; // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; // Create black (foreground) graphic context let win = screen.root; let foreground = conn.generate_id()?; let values = CreateGCAux::default() .foreground(screen.black_pixel) .graphics_exposures(0); conn.create_gc(foreground, win, &values)?; // Ask for our window's Id let win = conn.generate_id()?; // Create the window let values = CreateWindowAux::default() .background_pixel(screen.white_pixel) .event_mask(EventMask::EXPOSURE); conn.create_window( COPY_DEPTH_FROM_PARENT, // depth win, // window Id screen.root, // parent window 0, // x 0, // y 150, // width 150, // height 10, // border_width WindowClass::INPUT_OUTPUT, // class screen.root_visual, // visual &values, )?; // Map the window on the screen conn.map_window(win)?; // We flush the request conn.flush()?; loop { let event = conn.wait_for_event()?; if let Event::Expose(_) = event { // We draw the points conn.poly_point(CoordMode::ORIGIN, win, foreground, &points)?; // We draw the polygonal line conn.poly_line(CoordMode::PREVIOUS, win, foreground, &polyline)?; // We draw the segments conn.poly_segment(win, foreground, &segments)?; // We draw the rectangles conn.poly_rectangle(win, foreground, &rectangles)?; // We draw the arcs conn.poly_arc(win, foreground, &arcs)?; // We flush the request conn.flush()?; } else { // Unknown event type, ignore it } } } // X Events // ======== // // In an X program, everything is driven by events. Event painting on the screen is sometimes done // as a response to an event (an `Expose` event). If part of a program's window that was hidden, // gets exposed (e.g. the window was raised above other widows), the X server will send an "expose" // event to let the program know it should repaint that part of the window. User input (key // presses, mouse movement, etc) is also received as a set of events. // // // Registering for event types using event masks // --------------------------------------------- // // During the creation of a window, you should give it what kind of events it wishes to receive. // Thus, you may register for various mouse (also called pointer) events, keyboard events, expose // events, and so on. This is done for optimizing the server-to-client connection (i.e. why send a // program (that might even be running at the other side of the globe) an event it is not // interested in ?) // // In XCB, you use the "value_mask" and "value_list" data in the `xcb_create_window()` function to // register for events. Here is how we register for `Expose` event when creating a window: // #[allow(unused)] fn example_expose( conn: &C, depth: u8, screen: &Screen, ) -> Result<(), Box> { let values = CreateWindowAux::default().event_mask(EventMask::EXPOSURE); let win = conn.generate_id()?; conn.create_window( depth, win, screen.root, 0, 0, 150, 150, 10, WindowClass::INPUT_OUTPUT, screen.root_visual, &values, )?; Ok(()) } // `XCB_EVENT_MASK_EXPOSURE` is a constant defined in the xcb_event_mask_t enumeration in the // "xproto.h" header file. // // If we wanted to register for several event types, we can logically "or" them, as follows: #[allow(unused)] fn example_or(conn: &C, depth: u8, screen: &Screen) -> Result<(), Box> { let values = CreateWindowAux::default().event_mask(EventMask::EXPOSURE | EventMask::BUTTON_PRESS); let win = conn.generate_id()?; conn.create_window( depth, win, screen.root, 0, 0, 150, 150, 10, WindowClass::INPUT_OUTPUT, screen.root_visual, &values, )?; Ok(()) } // This registers for `Expose` events as well as for mouse button presses inside the created // window. You should note that a mask may represent several event sub-types. // // The values that a mask could take are given by the `xcb_cw_t` enumeration: // // pub enum CW { // BackPixmap, // BackPixel, // BorderPixmap, // BorderPixel, // BitGravity, // WinGravity, // BackingStore, // BackingPlanes, // BackingPixel, // OverrideRedirect, // SaveUnder, // EventMask, // DontPropagate, // Colormap, // Cursor, // } // // // [This note only applies to xcb, not x11rb] // // Note: we must be careful when setting the values of the valwin parameter, as they have to follow // the order the `xcb_cw_t` enumeration. Here is an example: // // [example removed since x11rb does not have this problem] // // If the window has already been created, we can use the `xcb_change_window_attributes()` function // to set the events that the window will receive. The subsection Configuring a window shows its // prototype. As an example, here is a piece of code that configures the window to receive the // `Expose` and `ButtonPress` events: #[allow(unused)] fn example_change_event_mask(conn: &C, win: Window) -> Result<(), Box> { let values = ChangeWindowAttributesAux::default() .event_mask(EventMask::EXPOSURE | EventMask::BUTTON_PRESS); conn.change_window_attributes(win, &values)?; Ok(()) } // Note: A common bug programmers have is adding code to handle new event types in their program, // while forgetting to add the masks for these events in the creation of the window. Such a // programmer would then sit there for hours debugging their program, wondering "Why doesn't my // program notice that I released the button?", only to find that they registered for button press // events but not for button release events. // // // Receiving events: writing the events loop // ----------------------------------------- // // After we have registered for the event types we are interested in, we need to enter a loop of // receiving events and handling them. There are two ways to receive events: a blocking way and a // non-blocking way: // // * `xcb_wait_for_event (xcb_connection_t *c)` is the blocking way. It waits (so blocks...) // until an event is queued in the X server. Then it retrieves it into a newly allocated // structure (it dequeues it from the queue) and returns it. This structure has to be freed. The // function returns `NULL` if an error occurs. // // * `xcb_poll_for_event (xcb_connection_t *c, int *error)` is the non-blocking way. It looks at // the event queue and returns (and dequeues too) an existing event into a newly allocated // structure. This structure has to be freed. It returns `NULL` if there is no event. If an // error occurs, the parameter `error` will be filled with the error status. // // There are various ways to write such a loop. We present two ways to write such a loop, with the // two functions above. The first one uses `xcb_wait_for_event_t`, which is similar to an event // Xlib loop using only `XNextEvent`: #[allow(unused)] fn example_wait_for_event(conn: &C) -> Result<(), Box> { loop { let event = conn.wait_for_event()?; match event { Event::Expose(_event) => { // .... } Event::ButtonPress(_event) => { // .... } _ => { // Unknown event type, ignore it } } } Ok(()) } // You will certainly want to use `xcb_poll_for_event(xcb_connection_t *c, int *error)` if, in // Xlib, you use `XPending` or `XCheckMaskEvent`: // // while (XPending (display)) { // XEvent ev; // // XNextEvent(d, &ev); // // /* Manage your event */ // } // // Such a loop in XCB looks like: // // xcb_generic_event_t *ev; // // while ((ev = xcb_poll_for_event (conn, 0))) { // /* Manage your event */ // } // // The events are managed in the same way as with `xcb_wait_for_event_t`. Obviously, we will need // to give the user some way of terminating the program. This is usually done by handling a special // "quit" event, as we will soon see. // // // Expose events // ------------- // // The `Expose` event is one of the most basic (and most used) events an application may receive. // It will be sent to us in one of several cases: // // * A window that covered part of our window has moved away, exposing part (or all) of our window. // * Our window was raised above other windows. // * Our window mapped for the first time. // * Our window was de-iconified. // // You should note the implicit assumption hidden here: the contents of our window is lost when it // is being obscured (covered) by either windows. One may wonder why the X server does not save // this contents. The answer is: to save memory. After all, the number of windows on a display at a // given time may be very large, and storing the contents of all of them might require a lot of // memory. Actually, there is a way to tell the X server to store the contents of a window in // special cases, as we will see later. // // When we get an `Expose` event, we should take the event's data from the members of the following // structure: #[allow(unused)] pub struct RenamedExposeEvent { /// The Id of the window that receives the event (in case our application /// registered for events in several windows) pub window: u32, /// The x coordinate of the top-left part of the window that needs to be redrawn pub x: u16, /// The y coordinate of the top-left part of the window that needs to be redrawn pub y: u16, /// The width of the part of the window that needs to be redrawn pub width: u16, /// The height of the part of the window that needs to be redrawn pub height: u16, pub count: u16, } // Getting user input // ================== // // User input traditionally comes from two sources: the mouse and the keyboard. Various event types // exist to notify us of user input (a key being presses on the keyboard, a key being released on // the keyboard, the mouse moving over our window, the mouse entering (or leaving) our window, and // so on. // // // Mouse button press and release events // ------------------------------------- // // The first event type we will deal with is a mouse button-press (or button-release) event in our // window. In order to register to such an event type, we should add one (or more) of the following // masks when we create our window: // // * `XCB_EVENT_MASK_BUTTON_PRESS`: notify us of any button that was pressed in one of our windows. // * `XCB_EVENT_MASK_BUTTON_RELEASE`: notify us of any button that was released in one of our windows. // // The structure to be checked for in our events loop is the same for these two events, and is the // following: #[allow(unused)] pub struct RenamedButtonPressEvent { pub detail: u8, /// Time, in milliseconds the event took place in pub time: u32, pub root: u32, pub event: u32, pub child: u32, pub root_x: i16, pub root_y: i16, /// The x coordinate where the mouse has been pressed in the window pub event_x: i16, /// The y coordinate where the mouse has been pressed in the window pub event_y: i16, /// A mask of the buttons (or keys) during the event pub state: u16, pub same_screen: u8, } // The `time` field may be used to calculate "double-click" situations by an application (e.g. if // the mouse button was clicked two times in a duration shorter than a given amount of time, assume // this was a double click). // // The `state` field is a mask of the buttons held down during the event. It is a bitwise OR of any // of the following (from the xcb_button_mask_t and xcb_mod_mask_t enumerations): // // * `XCB_BUTTON_MASK_1` // * `XCB_BUTTON_MASK_2` // * `XCB_BUTTON_MASK_3` // * `XCB_BUTTON_MASK_4` // * `XCB_BUTTON_MASK_5` // * `XCB_MOD_MASK_SHIFT` // * `XCB_MOD_MASK_LOCK` // * `XCB_MOD_MASK_CONTROL` // * `XCB_MOD_MASK_1` // * `XCB_MOD_MASK_2` // * `XCB_MOD_MASK_3` // * `XCB_MOD_MASK_4` // * `XCB_MOD_MASK_5` // // Their names are self explanatory, where the first 5 refer to the mouse buttons that are being // pressed, while the rest refer to various "special keys" that are being pressed (Mod1 is usually // the 'Alt' key or the 'Meta' key). // // **TODO:** Problem: it seems that the state does not change when clicking with various buttons. // // // Mouse movement events // --------------------- // // Similar to mouse button press and release events, we also can be notified of various mouse // movement events. These can be split into two families. One is of mouse pointer movement while no // buttons are pressed, and the second is a mouse pointer motion while one (or more) of the buttons // are pressed (this is sometimes called "a mouse drag operation", or just "dragging"). The // following event masks may be added during the creation of our window: // // * `XCB_EVENT_MASK_POINTER_MOTION`: events of the pointer moving in one of the windows controlled // by our application, while no mouse button is held pressed. // * `XCB_EVENT_MASK_BUTTON_MOTION`: Events of the pointer moving while one or more of the mouse // buttons is held pressed. // * `XCB_EVENT_MASK_BUTTON_1_MOTION`: same as `XCB_EVENT_MASK_BUTTON_MOTION`, but only when the // 1st mouse button is held pressed. // * `XCB_EVENT_MASK_BUTTON_2_MOTION`, `XCB_EVENT_MASK_BUTTON_3_MOTION`, // `XCB_EVENT_MASK_BUTTON_4_MOTION`, `XCB_EVENT_MASK_BUTTON_5_MOTION`: same as // `XCB_EVENT_MASK_BUTTON_1_MOTION`, but respectively for 2nd, 3rd, 4th and 5th mouse button. // // The structure to be checked for in our events loop is the same for these events, and is the // following: #[allow(unused)] pub struct RenamedMotionNotifyEvent { pub detail: u8, /// Time, in milliseconds the event took place in pub time: u32, pub root: u32, pub event: u32, pub child: u32, pub root_x: i16, pub root_y: i16, /// The x coordinate where the mouse has been pressed in the window pub event_x: i16, /// The y coordinate where the mouse has been pressed in the window pub event_y: i16, /// A mask of the buttons (or keys) during the event pub state: u16, pub same_screen: u8, } // Mouse pointer enter and leave events // ------------------------------------ // // Another type of event that applications might be interested in, is a mouse pointer entering a // window the program controls, or leaving such a window. Some programs use these events to show // the user that the application is now in focus. In order to register for such an event type, we // should add one (or more) of the following masks when we create our window: // // * `xcb_event_enter_window_t`: notify us when the mouse pointer enters any of our controlled // windows. // * `xcb_event_leave_window_t`: notify us when the mouse pointer leaves any of our controlled // windows. // // The structure to be checked for in our events loop is the same for these two events, and is the // following: #[allow(unused)] pub struct RenamedEnterNotifyEvent { pub detail: u8, pub time: u32, pub root: u32, pub event: u32, pub child: u32, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub mode: u8, pub same_screen_focus: u8, } // The keyboard focus // ------------------ // // There may be many windows on a screen, but only a single keyboard attached to them. How does the // X server then know which window should be sent a given keyboard input ? This is done using the // keyboard focus. Only a single window on the screen may have the keyboard focus at a given time. // There is a XCB function that allows a program to set the keyboard focus to a given window. The // user can usually set the keyboard focus using the window manager (often by clicking on the title // bar of the desired window). Once our window has the keyboard focus, every key press or key // release will cause an event to be sent to our program (if it registered for these event // types...). // // Keyboard press and release events // --------------------------------- // // If a window controlled by our program currently holds the keyboard focus, it can receive key // press and key release events. So, we should add one (or more) of the following masks when we // create our window: // // * `XCB_EVENT_MASK_KEY_PRESS`: notify us when a key was pressed while any of our controlled // windows had the keyboard focus. // * `XCB_EVENT_MASK_KEY_RELEASE`: notify us when a key was released while any of our controlled // windows had the keyboard focus. // // The structure to be checked for in our events loop is the same for these two events, and is the // following: #[allow(unused)] pub struct RenamedKeyPressEvent { pub detail: u8, /// Time, in milliseconds the event took place in pub time: u32, pub root: u32, pub event: u32, pub child: u32, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub same_screen: u8, } // The `detail` field refers to the physical key on the keyboard. // // **TODO:** Talk about getting the ASCII code from the key code. // // // X events: a complete example // ============================ // // As an example for handling events, we show a program that creates a window, enters an events // loop and checks for all the events described above, and writes on the terminal the relevant // characteristics of the event. With this code, it should be easy to add drawing operations, like // those which have been described above. fn print_modifiers(mask: u16) { let mods = [ (KeyButMask::SHIFT, "Shift"), (KeyButMask::LOCK, "Lock"), (KeyButMask::CONTROL, "Ctrl"), (KeyButMask::MOD1, "Alt"), (KeyButMask::MOD2, "Mod2"), (KeyButMask::MOD3, "Mod3"), (KeyButMask::MOD4, "Mod4"), (KeyButMask::MOD5, "Mod5"), (KeyButMask::BUTTON1, "Button1"), (KeyButMask::BUTTON2, "Button2"), (KeyButMask::BUTTON3, "Button3"), (KeyButMask::BUTTON4, "Button4"), (KeyButMask::BUTTON5, "Button5"), ]; let active = mods .iter() .filter(|(m, _)| mask & u16::from(*m) != 0) // FIXME: This should be made nicer .map(|(_, name)| name) .collect::>(); println!("Modifier mask: {:?}", active); } fn example7() -> Result<(), Box> { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; // Ask for our window's Id let win = conn.generate_id()?; // Create the window let values = CreateWindowAux::default() .background_pixel(screen.white_pixel) .event_mask( EventMask::EXPOSURE | EventMask::BUTTON_PRESS | EventMask::BUTTON_RELEASE | EventMask::POINTER_MOTION | EventMask::ENTER_WINDOW | EventMask::LEAVE_WINDOW | EventMask::KEY_PRESS | EventMask::KEY_RELEASE, ); conn.create_window( COPY_DEPTH_FROM_PARENT, // depth win, // window Id screen.root, // parent window 0, // x 0, // y 150, // width 150, // height 10, // border_width WindowClass::INPUT_OUTPUT, // class screen.root_visual, // visual &values, )?; // Map the window on the screen conn.map_window(win)?; conn.flush()?; loop { let event = conn.wait_for_event()?; match event { Event::Expose(event) => { println!( "Window {} exposed. Region to be redrawn at location ({},{}) with dimensions \ ({},{})", event.window, event.x, event.y, event.width, event.height ); } Event::ButtonPress(event) => { print_modifiers(event.state); match event.detail { 4 => println!( "Wheel Button up in window {}, at coordinates ({},{})", event.event, event.event_x, event.event_y ), 5 => println!( "Wheel Button down in window {}, at coordinates ({},{})", event.event, event.event_x, event.event_y ), _ => println!( "Button {} pressed in window {}, at coordinates ({},{})", event.detail, event.event, event.event_x, event.event_y ), } } Event::ButtonRelease(event) => { print_modifiers(event.state); println!( "Button {} released in window {}, at coordinates ({},{})", event.detail, event.event, event.event_x, event.event_y ); } Event::MotionNotify(event) => { println!( "Mouse moved in window {} at coordinates ({},{})", event.event, event.event_x, event.event_y ); } Event::EnterNotify(event) => { println!( "Mouse entered window {} at coordinates ({},{})", event.event, event.event_x, event.event_y ); } Event::LeaveNotify(event) => { println!( "Mouse left window {} at coordinates ({},{})", event.event, event.event_x, event.event_y ); } Event::KeyPress(event) => { print_modifiers(event.state); println!("Key pressed in window {}", event.event); } Event::KeyRelease(event) => { print_modifiers(event.state); println!("Key released in window {}", event.event); } _ => { // Unknown event type, ignore it println!("Unknown event: {:?}", event); } } } } // Handling text and fonts // // ======================= // // Besides drawing graphics on a window, we often want to draw text. Text strings have two major // properties: the characters to be drawn and the font with which they are drawn. In order to draw // text, we need to first request the X server to load a font. We then assign a font to a Graphic // Context, and finally, we draw the text in a window, using the Graphic Context. // // // The Font structure // ------------------ // // In order to support flexible fonts, a font type is defined. You know what ? It's an Id: // // pub type Font = u32; // // It is used to contain information about a font, and is passed to several functions that handle // fonts selection and text drawing. We ask the X server to attribute an Id to our font with the // function: // // conn.generate_id(); // // // Opening a Font // -------------- // // To open a font, we use the following function: // // pub fn open_font(&self, fid: u32, name: &[u8]) -> Result; // // The `fid` parameter is the font Id defined by `xcb_generate_id()` (see above). The `name` // parameter is the name of the font you want to open. Use the command `xlsfonts` in a terminal to // know which are the fonts available on your computer. The parameter `name_len` is the length of // the name of the font (given by `strlen()`). // // // Assigning a Font to a Graphic Context // ------------------------------------- // // Once a font is opened, you have to create a Graphic Context that will contain the informations // about the color of the foreground and the background used when you draw a text in a Drawable. // Here is an example of a Graphic Context that will allow us to draw an opened font with a black // foreground and a white background: #[allow(unused)] fn example_assign_font( conn: &C, screen: &Screen, window: Window, font: Font, ) -> Result<(), Box> { let gc = conn.generate_id()?; let values = CreateGCAux::default() .foreground(screen.black_pixel) .background(screen.white_pixel) .font(font); conn.create_gc(gc, window, &values)?; // The font is not needed anymore, so we close it conn.close_font(font)?; Ok(()) } // Drawing text in a drawable // -------------------------- // // To draw a text in a drawable, we use the following function: // // pub fn image_text8(&self, drawable: u32, gc: u32, x: i16, y: i16, string: &[u8]) // -> Result; // // The `string` parameter is the text to draw. The location of the drawing is given by the // parameters `x` and `y`. The base line of the text is exactly the parameter `y`. // // // Complete example // ---------------- // // This example draw a text at 10 pixels (for the base line) of the bottom of a window. Pressing // the Esc key exits the program. // // (This whole example uses checked requests in the original, but that does not really seem useful // to me, so I changed it.) fn text_draw( conn: &C, screen: &Screen, window: Window, x1: i16, y1: i16, label: &str, ) -> Result<(), Box> { let gc = gc_font_get(conn, screen, window, "7x13")?; conn.image_text8(window, gc, x1, y1, label.as_bytes())?; conn.free_gc(gc)?; Ok(()) } fn gc_font_get( conn: &C, screen: &Screen, window: Window, font_name: &str, ) -> Result { let font = conn.generate_id()?; conn.open_font(font, font_name.as_bytes())?; let gc = conn.generate_id()?; let values = CreateGCAux::default() .foreground(screen.black_pixel) .background(screen.white_pixel) .font(font); conn.create_gc(gc, window, &values)?; conn.close_font(font)?; Ok(gc) } fn example8() -> Result<(), Box> { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; const WIDTH: u16 = 300; const HEIGHT: u16 = 100; // Creating the window let window = conn.generate_id()?; let values = CreateWindowAux::default() .background_pixel(screen.white_pixel) .event_mask( EventMask::KEY_RELEASE | EventMask::BUTTON_PRESS | EventMask::EXPOSURE | EventMask::POINTER_MOTION, ); conn.create_window( screen.root_depth, window, screen.root, 20, 200, WIDTH, HEIGHT, 0, WindowClass::INPUT_OUTPUT, screen.root_visual, &values, )?; conn.map_window(window)?; conn.flush()?; loop { let event = conn.wait_for_event()?; match event { Event::Expose(_) => { let text = "Press ESC key to exit..."; text_draw(&conn, screen, window, 10, HEIGHT as i16 - 10, text)?; conn.flush()?; } Event::KeyRelease(event) => { if event.detail == 9 { // ESC return Ok(()); } } _ => {} // Unknown event type, ignore it } } } // Interacting with the window manager // =================================== // // After we have seen how to create windows and draw on them, we take one step back, and look at // how our windows are interacting with their environment (the full screen and the other windows). // First of all, our application needs to interact with the window manager. The window manager is // responsible to decorating drawn windows (i.e. adding a frame, an iconify button, a system menu, // a title bar, etc), as well as handling icons shown when windows are being iconified. It also // handles ordering of windows on the screen, and other administrative tasks. We need to give it // various hints as to how we want it to treat our application's windows. // // // Window properties // ----------------- // // Many of the parameters communicated to the window manager are passed using data called // "properties". These properties are attached by the X server to different windows, and are stored // in a format that makes it possible to read them from different machines that may use different // architectures (remember that an X client program may run on a remote machine). // // The property and its type (a string, an integer, etc) are Id. Their type are `xcb_atom_t`: // // pub type ATOM = u32; // // To change the property of a window, we use one of the following functions: // // fn change_property8( // &self, // mode: A, // window: Window, // property: B, // type_: C, // data: &[u8], // ) -> Result, ConnectionError> // where // A: Into, // B: Into, // C: Into // // fn change_property16( // &self, // mode: A, // window: Window, // property: B, // type_: C, // data: &[u16], // ) -> Result, ConnectionError> // where // A: Into, // B: Into, // C: Into // // fn change_property32( // &self, // mode: A, // window: Window, // property: B, // type_: C, // data: &[u32], // ) -> Result, ConnectionError> // where // A: Into, // B: Into, // C: Into // // The `mode` parameter could be one of the following values (defined in enumeration // xcb_prop_mode_t in the xproto.h header file): // // pub enum PropMode { // Replace, // Prepend, // Append, // } // // // // Setting the window name and icon name // ------------------------------------- // // The first thing we want to do would be to set the name for our window. This is done using the // `xcb_change_property()` function. This name may be used by the window manager as the title of // the window (in the title bar), in a task list, etc. The property atom to use to set the name of // a window is `WM_NAME` (and `WM_ICON_NAME` for the iconified window) and its type is `STRING`. // Here is an example of utilization: fn example9() -> Result<(), Box> { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; // Ask for our window's Id let win = conn.generate_id()?; // Create the window conn.create_window( 0, win, screen.root, 0, 0, 250, 150, 10, WindowClass::INPUT_OUTPUT, screen.root_visual, &Default::default(), )?; // Set the title of the window let title = "Hello World !"; conn.change_property8( PropMode::REPLACE, win, AtomEnum::WM_NAME, AtomEnum::STRING, title.as_bytes(), )?; // Set the title of the window icon let title_icon = "Hello World ! (iconified)"; conn.change_property8( PropMode::REPLACE, win, AtomEnum::WM_ICON_NAME, AtomEnum::STRING, title_icon.as_bytes(), )?; // Map the window on the screen conn.map_window(win)?; conn.flush()?; loop { conn.wait_for_event()?; } } // Simple window operations // ======================== // // One more thing we can do to our window is manipulate them on the screen (resize them, move them, // raise or lower them, iconify them, and so on). Some window operations functions are supplied by // XCB for this purpose. // // // Mapping and un-mapping a window // ------------------------------- // // The first pair of operations we can apply on a window is mapping it, or un-mapping it. Mapping a // window causes the window to appear on the screen, as we have seen in our simple window program // example. Un-mapping it causes it to be removed from the screen (although the window as a logical // entity still exists). This gives the effect of making a window hidden (unmapped) and shown again // (mapped). For example, if we have a dialog box window in our program, instead of creating it // every time the user asks to open it, we can create the window once, in an un-mapped mode, and // when the user asks to open it, we simply map the window on the screen. When the user clicked the // 'OK' or 'Cancel' button, we simply un-map the window. This is much faster than creating and // destroying the window, however, the cost is wasted resources, both on the client side, and on // the X server side. // // To map a window, you use the following function: // // fn map_window(&self, window: u32) -> Result; // // To have a simple example, see the examples above. The mapping operation will cause an `Expose` // event to be sent to our application, unless the window is completely covered by other windows. // // Un-mapping a window is also simple. You use the function // // fn unmap_window(&self, window: u32) -> Result; // // The utilization of this function is the same as `xcb_map_window()`. // // // Configuring a window // -------------------- // // As we have seen when we have created our first window, in the X Events subsection, we can set // some attributes for the window (that is, the position, the size, the events the window will // receive, etc). If we want to modify them, but the window is already created, we can change them // by using the following function: // // fn configure_window(&self, window: u32, value_list: &ConfigureWindowAux) -> Result; // // We set the `value_mask` to one or several mask values that are in the xcb_config_window_t enumeration in the xproto.h header: // // * `XCB_CONFIG_WINDOW_X`: new x coordinate of the window's top left corner // * `XCB_CONFIG_WINDOW_Y`: new y coordinate of the window's top left corner // * `XCB_CONFIG_WINDOW_WIDTH`: new width of the window // * `XCB_CONFIG_WINDOW_HEIGHT`: new height of the window // * `XCB_CONFIG_WINDOW_BORDER_WIDTH`: new width of the border of the window // * `XCB_CONFIG_WINDOW_SIBLING` // * `XCB_CONFIG_WINDOW_STACK_MODE`: the new stacking order // // We then give to `value_mask` the new value. We now describe how to use `xcb_configure_window_t` // in some useful situations. // // // Moving a window around the screen // --------------------------------- // // An operation we might want to do with windows is to move them to a different location. This can // be done like this: #[allow(unused)] fn example_move(conn: &C, win: Window) -> Result<(), ReplyError> { // Move the window to coordinates x = 10 and y = 20 let values = ConfigureWindowAux::default().x(10).y(20); conn.configure_window(win, &values)?; Ok(()) } // Note that when the window is moved, it might get partially exposed or partially hidden by other // windows, and thus we might get `Expose` events due to this operation. // // // Resizing a window // ----------------- // // Yet another operation we can do is to change the size of a window. This is done using the // following code: #[allow(unused)] fn example_resize(conn: &C, win: Window) -> Result<(), ReplyError> { // Move the window to coordinates width = 10 and height = 20 let values = ConfigureWindowAux::default().width(10).height(20); conn.configure_window(win, &values)?; Ok(()) } // We can also combine the move and resize operations using one single call to // `xcb_configure_window_t`: #[allow(unused)] fn example_move_resize(conn: &C, win: Window) -> Result<(), ReplyError> { // Move the window to coordinates x = 10 and y = 20 // and resize the window to width = 200 and height = 300 let values = ConfigureWindowAux::default() .x(10) .y(20) .width(200) .height(300); conn.configure_window(win, &values)?; Ok(()) } // Changing windows stacking order: raise and lower // ------------------------------------------------ // // Until now, we changed properties of a single window. We'll see that there are properties that // relate to the window and other windows. One of them is the stacking order. That is, the order in // which the windows are layered on top of each other. The front-most window is said to be on the // top of the stack, while the back-most window is at the bottom of the stack. Here is how to // manipulate our windows stack order: #[allow(unused)] fn example_stack_above(conn: &C, win: Window) -> Result<(), ReplyError> { // Move the window on the top of the stack let values = ConfigureWindowAux::default().stack_mode(StackMode::ABOVE); conn.configure_window(win, &values)?; Ok(()) } #[allow(unused)] fn example_stack_below(conn: &C, win: Window) -> Result<(), ReplyError> { // Move the window to the bottom of the stack let values = ConfigureWindowAux::default().stack_mode(StackMode::BELOW); conn.configure_window(win, &values)?; Ok(()) } // Getting information about a window // ---------------------------------- // // Just like we can set various attributes of our windows, we can also ask the X server supply the // current values of these attributes. For example, we can check where a window is located on the // screen, what is its current size, whether it is mapped or not, etc. The structure that contains // some of this information is pub struct RenamedGetGeometryReply { pub depth: u8, // depth of the window pub root: u32, // Id of the root window pub x: i16, // x coordinate of the window's location pub y: i16, // Y coordinate of the window's location pub width: u16, // Width of the window pub height: u16, // Height of the window pub border_width: u16, // Width of the window's border } // x11rb fills this structure with two functions: // // fn get_geometry(&self, drawable: u32) -> Result, ConnectionError>; // // and the .reply() function on the returned cookie // // You use them as follows: #[allow(unused)] fn example_get_geometry(conn: &C, win: Window) -> Result<(), ReplyError> { let geom = conn.get_geometry(win)?.reply()?; // Do something with the fields of geom Ok(()) } // Remark that you have to free the structure, as `xcb_get_geometry_reply_t` allocates a newly one. // // [Also remark that with x11rb and rust, you do not have to free the structure yourself] // // One problem is that the returned location of the window is relative to its parent window. This // makes these coordinates rather useless for any window manipulation functions, like moving it on // the screen. In order to overcome this problem, we need to take a two-step operation. First, we // find out the Id of the parent window of our window. We then translate the above relative // coordinates to the screen coordinates. // // To get the Id of the parent window, we need this structure: // // pub struct QueryTreeReply { // pub root: u32, // pub parent: u32, // pub children: Vec, // } // // x11rb fills this structure with two functions: // // fn query_tree(&self, window: u32) -> Result, ConnectionError>; // // and the .reply() function on the returned cookie // // The translated coordinates will be found in this structure: // // pub struct TranslateCoordinatesReply { // pub same_screen: u8, // pub child: u32, // pub dst_x: i16, // pub dst_y: i16, // } // // As usual, we need two functions to fill this structure: // // fn translate_coordinates(&self, src_window: u32, dst_window: u32, src_x: i16, src_y: i16) // -> Result, ConnectionError> // // and the .reply() function on the returned cookie // // We use them as follows: #[allow(unused)] fn example_get_and_query(conn: &C, win: Window) -> Result<(), ReplyError> { let geom = conn.get_geometry(win)?; let tree = conn.query_tree(win)?; let geom = geom.reply()?; let tree = tree.reply()?; let trans = conn .translate_coordinates(win, tree.parent, geom.x, geom.y)? .reply()?; // the translated coordinates are in trans.dst_x and trans.dst_y Ok(()) } // Of course, as for `geom`, `tree` and `trans` have to be freed. // [But not in rust / x11rb] // // The work is a bit hard, but XCB is a very low-level library. // // **TODO:** the utilization of these functions should be a prog, which displays the coordinates of the window. // // There is another structure that gives informations about our window: // // pub struct GetWindowAttributesReply { // pub backing_store: u8, // pub visual: u32, // pub class: u16, // pub bit_gravity: u8, // pub win_gravity: u8, // pub backing_planes: u32, // pub backing_pixel: u32, // pub save_under: u8, // pub map_is_installed: u8, // pub map_state: u8, // pub override_redirect: u8, // pub colormap: u32, // pub all_event_masks: u32, // pub your_event_mask: u32, // pub do_not_propagate_mask: u16, // } // // XCB supplies these two functions to fill it: // // fn get_window_attributes(&self, window: u32) -> Result, ConnectionError>; // // and the .reply() function on the returned cookie // // You use them as follows: #[allow(unused)] fn example_get_attributes(conn: &C, win: Window) -> Result<(), ReplyError> { let geom = conn.get_window_attributes(win)?.reply()?; // Do something with the fields of attr Ok(()) } // Using colors to paint the rainbow // ================================= // // Up until now, all our painting operation were done using black and white. We will (finally) see // now how to draw using colors. // // // Color maps // ---------- // // In the beginning, there were not enough colors. Screen controllers could only support a limited // number of colors simultaneously (initially 2, then 4, 16 and 256). Because of this, an // application could not just ask to draw in a "light purple-red" color, and expect that color to // be available. Each application allocated the colors it needed, and when all the color entries // (4, 16, 256 colors) were in use, the next color allocation would fail. // // Thus, the notion of "a color map" was introduced. A color map is a table whose size is the same // as the number of simultaneous colors a given screen controller. Each entry contained the RGB // (Red, Green and Blue) values of a different color (all colors can be drawn using some // combination of red, green and blue). When an application wants to draw on the screen, it does // not specify which color to use. Rather, it specifies which color entry of some color map to be // used during this drawing. Change the value in this color map entry and the drawing will use a // different color. // // In order to be able to draw using colors that got something to do with what the programmer // intended, color map allocation functions are supplied. You could ask to allocate entry for a // color with a set of RGB values. If one already existed, you would get its index in the table. If // none existed, and the table was not full, a new cell would be allocated to contain the given RGB // values, and its index returned. If the table was full, the procedure would fail. You could then // ask to get a color map entry with a color that is closest to the one you were asking for. This // would mean that the actual drawing on the screen would be done using colors similar to what you // wanted, but not the same. // // On today's more modern screens where one runs an X server with support for 16 million colors, // this limitation looks a little silly, but remember that there are still older computers with // older graphics cards out there. Using color map, support for these screen becomes transparent to // you. On a display supporting 16 million colors, any color entry allocation request would // succeed. On a display supporting a limited number of colors, some color allocation requests // would return similar colors. It won't look as good, but your application would still work. // // // Allocating and freeing Color Maps // --------------------------------- // // When you draw using XCB, you can choose to use the standard color map of the screen your window // is displayed on, or you can allocate a new color map and apply it to a window. In the latter // case, each time the mouse moves onto your window, the screen color map will be replaced by your // window's color map, and you'll see all the other windows on screen change their colors into // something quite bizarre. In fact, this is the effect you get with X applications that use the // "-install" command line option. // // In XCB, a color map is (as often in X) an Id: // // type COLORMAP = u32; // // In order to access the screen's default color map, you just have to retrieve the // `default_colormap` field of the `xcb_screen_t` structure (see Section [Checking basic // information about a connection](#screen)): #[allow(unused)] fn example_get_colormap(conn: &C) { let screen = &conn.setup().roots[0]; let _colormap = screen.default_colormap; } // This will return the color map used by default on the first screen (again, remember that an X // server may support several different screens, each of which might have its own resources). // // The other option, that of allocating a new colormap, works as follows. We first ask the X server // to give an Id to our color map, with this function: // // conn.generate_id(); // // Then, we create the color map with // // fn create_colormap(&self, alloc: A, mid: u32, window: u32, visual: u32) // -> Result // where A: Into // // Here is an example of creation of a new color map: #[allow(unused)] fn example_create_colormap( conn: &C, win: Window, screen: &Screen, ) -> Result<(), ReplyOrIdError> { let cmap = conn.generate_id()?; conn.create_colormap(ColormapAlloc::NONE, cmap, win, screen.root_visual)?; Ok(()) } // Note that the window parameter is only used to allow the X server to create the color map for // the given screen. We can then use this color map for any window drawn on the same screen. // // To free a color map, it suffices to use this function: // // fn free_colormap(&self, cmap: u32) -> Result; // // // Allocating and freeing a color entry // ------------------------------------ // // Once we got access to some color map, we can start allocating colors. The informations related // to a color are stored in the following structure: // // pub struct AllocColorReply { // pub red: u16, // pub green: u16, // pub blue: u16, // pub pixel: u32, // } // // XCB supplies these two functions to fill it: // // fn alloc_color(&self, cmap: u32, red: u16, green: u16, blue: u16) -> Result, ConnectionError>; // // and the .reply() function on the returned cookie // // The fuction `xcb_alloc_color()` takes the 3 RGB components as parameters (red, green and blue). // Here is an example of using these functions: #[allow(unused)] fn example_fill_colormap( conn: &C, win: Window, screen: &Screen, ) -> Result<(), ReplyOrIdError> { let cmap = conn.generate_id()?; conn.create_colormap(ColormapAlloc::NONE, cmap, win, screen.root_visual)?; let _rep = conn.alloc_color(cmap, 65535, 0, 0)?.reply()?; // Do something with r.pixel or the components Ok(()) } // As `xcb_alloc_color_reply()` allocates memory, you have to free `rep`. // [But not in rust / x11rb] // // **TODO**: Talk about freeing colors. // // // X Bitmaps and Pixmaps // ===================== // // One thing many so-called "Multi-Media" applications need to do, is display images. In the X // world, this is done using bitmaps and pixmaps. We have already seen some usage of them when // setting an icon for our application. Lets study them further, and see how to draw these images // inside a window, along side the simple graphics and text we have seen so far. // // One thing to note before delving further, is that XCB (nor Xlib) supplies no means of // manipulating popular image formats, such as gif, png, jpeg or tiff. It is up to the programmer // (or to higher level graphics libraries) to translate these image formats into formats that the X // server is familiar with (x bitmaps and x pixmaps). // // // What is a X Bitmap? An X Pixmap? // -------------------------------- // // An X bitmap is a two-color image stored in a format specific to the X window system. When stored // in a file, the bitmap data looks like a C source file. It contains variables defining the width // and the height of the bitmap, an array containing the bit values of the bitmap (the size of the // array is (width+7)/8*height and the bit and byte order are LSB), and an optional hot-spot // location (that will be explained later, when discussing mouse cursors). // // An X pixmap is a format used to stored images in the memory of an X server. This format can // store both black and white images (such as x bitmaps) as well as color images. It is the only // image format supported by the X protocol, and any image to be drawn on screen, should be first // translated into this format. // // In actuality, an X pixmap can be thought of as a window that does not appear on the screen. Many // graphics operations that work on windows, will also work on pixmaps. Indeed, the type of X // pixmap in XCB is an Id like a window: // // type PIXMAP = u32; // // Like Xlib, there is no difference between a Drawable, a Window or a Pixmap: // // type DRAWABLE = u32; // // in order to avoid confusion between a window and a pixmap. The operations that will work the // same on a window or a pixmap will require a `xcb_drawable_t` // // Remark: In Xlib, there is no specific difference between a `Drawable`, a `Pixmap` or a `Window`: // all are 32 bit long integer. XCB wraps all these different IDs in structures to provide some // measure of type-safety. // // // Creating a pixmap // ----------------- // // Sometimes we want to create an un-initialized pixmap, so we can later draw into it. This is // useful for image drawing programs (creating a new empty canvas will cause the creation of a new // pixmap on which the drawing can be stored). It is also useful when reading various image // formats: we load the image data into memory, create a pixmap on the server, and then draw the // decoded image data onto that pixmap. // // To create a new pixmap, we first ask the X server to give an Id to our pixmap, with this // function: // // conn.generate_id(); // // Then, XCB supplies the following function to create new pixmaps: // // fn create_pixmap(&self, depth: u8, pid: u32, drawable: u32, width: u16, height: u16) -> Result // // **TODO**: Explain the drawable parameter, and give an example (like xpoints.c) // // // Drawing a pixmap in a window // ---------------------------- // // Once we got a handle to a pixmap, we can draw it on some window, using the following function: // // fn copy_area(&self, src_drawable: u32, dst_drawable: u32, gc: u32, src_x: i16, // src_y: i16, dst_x: i16, dst_y: i16, width: u16, height: u16) // -> Result; // // As you can see, we could copy the whole pixmap, as well as only a given rectangle of the pixmap. // This is useful to optimize the drawing speed: we could copy only what we have modified in the // pixmap. // // **One important note should be made**: it is possible to create pixmaps with different depths on // the same screen. When we perform copy operations (a pixmap onto a window, etc), we should make // sure that both source and target have the same depth. If they have a different depth, the // operation would fail. The exception to this is if we copy a specific bit plane of the source // pixmap using the `xcb_copy_plane_t` function. In such an event, we can copy a specific plane to // the target window (in actuality, setting a specific bit in the color of each pixel copied). This // can be used to generate strange graphic effects in a window, but that is beyond the scope of // this tutorial. // // // Freeing a pixmap // ---------------- // // Finally, when we are done using a given pixmap, we should free it, in order to free resources of // the X server. This is done using this function: // // fn free_pixmap(&self, pixmap: u32) -> Result; // // Of course, after having freed it, we must not try accessing the pixmap again. // // **TODO**: Give an example, or a link to xpoints.c // // // Messing with the mouse cursor // ============================= // // It it possible to modify the shape of the mouse pointer (also called the X pointer) when in // certain states, as we often see in programs. For example, a busy application would often display // the hourglass cursor over its main window, to give the user a visual hint that they should wait. // Let's see how we can change the mouse cursor of our windows. // // // Creating and destroying a mouse cursor // -------------------------------------- // // There are two methods for creating cursors. One of them is by using a set of predefined cursors, // that are supplied by the X server, the other is by using a user-supplied bitmap. // // In the first method, we use a special font named "cursor", and the function // `xcb_create_glyph_cursor`: // // fn create_glyph_cursor(&self, cid: u32, source_font: u32, mask_font: u32, // source_char: u16, mask_char: u16, fore_red: u16, fore_green: u16, // fore_blue: u16, back_red: u16, back_green: u16, back_blue: u16) // -> Result; // // **TODO**: Describe `source_char` and `mask_char`, for example by giving an example on how to get // the values. There is a list there: [X Font Cursors](http://tronche.com/gui/x/xlib/appendix/b/) // // So we first open that font (see 'Loading a Font') and create the new cursor. As for // every X resource, we have to ask for an X id with `xcb_generate_id` first: #[allow(unused)] fn example_create_glyph_cursor( conn: &C, win: Window, screen: &Screen, ) -> Result<(), ReplyOrIdError> { let font = conn.generate_id()?; conn.open_font(font, b"cursor")?; let cursor = conn.generate_id()?; conn.create_glyph_cursor(cursor, font, font, 58, 58 + 1, 0, 0, 0, 0, 0, 0)?; Ok(()) } // We have created the cursor "right hand" by specifying 58 to the `source_fon`t argument and 58 + // 1 to the `mask_font`. // // The cursor is destroyed by using the function // // fn free_cursor(&self, cursor: u32) -> Result; // // In the second method, we create a new cursor by using a pair of pixmaps, with depth of one (that // is, two colors pixmaps). One pixmap defines the shape of the cursor, while the other works as a // mask, specifying which pixels of the cursor will be actually drawn. The rest of the pixels will // be transparent. // // **TODO**: give an example. // // // Setting a window's mouse cursor // ------------------------------- // // Once the cursor is created, we can modify the cursor of our window by using // `xcb_change_window_attributes` and using the `XCB_CWCURSOR` attribute: #[allow(unused)] fn example_change_window_cursor( conn: &C, win: Window, cursor: Cursor, ) -> Result<(), ReplyError> { let values = ChangeWindowAttributesAux::default().cursor(cursor); conn.change_window_attributes(win, &values)?; Ok(()) } // Of course, the cursor and the font must be freed. // // // Complete example // ---------------- // // The following example displays a window with a button. When entering the window, the window // cursor is changed to an arrow. When clicking once on the button, the cursor is changed to a // hand. When clicking again on the button, the cursor window gets back to the arrow. The Esc key // exits the application. fn button_draw( conn: &C, screen: &Screen, window: Window, x1: i16, y1: i16, label: &str, ) -> Result<(), ReplyOrIdError> { let inset = 2; let gc = gc_font_get(conn, screen, window, "7x13")?; let width = 7 * label.len() + 2 * (inset + 1); let height = 13 + 2 * (inset + 1); let (width, height) = (width as i16, height as i16); let inset = inset as i16; let points = [ Point { x: x1, y: y1 }, Point { x: x1 + width, y: y1, }, Point { x: x1 + width, y: y1 - height, }, Point { x: x1, y: y1 - height, }, Point { x: x1, y: y1 }, ]; conn.poly_line(CoordMode::ORIGIN, window, gc, &points)?; conn.image_text8(window, gc, x1 + inset + 1, y1 - inset - 1, label.as_bytes())?; conn.free_gc(gc)?; Ok(()) } // text_draw and gc_font_get were already defined above fn cursor_set( conn: &C, screen: &Screen, window: Window, cursor_id: u16, ) -> Result<(), ReplyOrIdError> { let font = conn.generate_id()?; conn.open_font(font, b"cursor")?; let cursor = conn.generate_id()?; conn.create_glyph_cursor( cursor, font, font, cursor_id, cursor_id + 1, 0, 0, 0, 0, 0, 0, )?; let gc = conn.generate_id()?; let values = CreateGCAux::default() .foreground(screen.black_pixel) .background(screen.black_pixel) .font(font); conn.create_gc(gc, window, &values)?; let values = ChangeWindowAttributesAux::default().cursor(cursor); conn.change_window_attributes(window, &values)?; conn.free_cursor(cursor)?; conn.close_font(font)?; Ok(()) } fn example10() -> Result<(), Box> { const WIDTH: i16 = 300; const HEIGHT: i16 = 300; // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None)?; // Get the screen #screen_num let screen = &conn.setup().roots[screen_num]; // Creating the window let window = conn.generate_id()?; let values = CreateWindowAux::default() .background_pixel(screen.white_pixel) .event_mask(EventMask::KEY_RELEASE | EventMask::BUTTON_PRESS | EventMask::EXPOSURE); conn.create_window( screen.root_depth, window, screen.root, 20, 200, WIDTH as u16, HEIGHT as u16, 0, WindowClass::INPUT_OUTPUT, screen.root_visual, &values, )?; conn.map_window(window)?; cursor_set(&conn, screen, window, 68)?; conn.flush()?; let mut is_hand = false; loop { let event = conn.wait_for_event()?; match event { Event::Expose(_) => { let text = "click here to change cursor"; button_draw( &conn, screen, window, (WIDTH - 7 * text.len() as i16) / 2, (HEIGHT - 16) / 2, text, )?; let text = "Press ESC key to exit..."; text_draw(&conn, screen, window, 10, HEIGHT - 10, text)?; conn.flush()?; } Event::ButtonPress(event) => { let length = "click here to change cursor".len() as i16; if (event.event_x >= (WIDTH - 7 * length) / 2) && (event.event_x <= ((WIDTH - 7 * length) / 2 + 7 * length + 6)) && (event.event_y >= (HEIGHT - 16) / 2 - 19) && (event.event_y <= ((HEIGHT - 16) / 2)) { is_hand = !is_hand; } if is_hand { cursor_set(&conn, screen, window, 58)?; } else { cursor_set(&conn, screen, window, 68)?; } conn.flush()?; } Event::KeyRelease(event) => { if event.detail == 9 { // ESC return Ok(()); } } _ => {} // Unknown event type, ignore it } } } // Translation of basic Xlib functions and macros // // The problem when you want to port an Xlib program to XCB is that you don't know if the Xlib // function that you want to "translate" is a X Window one or an Xlib macro. In that section, we // describe a way to translate the usual functions or macros that Xlib provides. It's usually just // a member of a structure. // // // Members of the Display structure // -------------------------------- // // In this section, we look at how to translate the macros that return some members of the // `Display` structure. They are obtained by using a function that requires a `xcb_connection_t *` // or a member of the `xcb_setup_t` structure (via the function `xcb_get_setup`), or a function // that requires that structure. // // // ConnectionNumber // // This number is the file descriptor that connects the client to the server. You just have to use // the trait `std::os::unix::io::AsRawFd`. // // // DefaultScreen // // That number is not stored by XCB. It is returned in the second parameter of the function // `connect`. Hence, you have to store it yourself if you want to use it. Then, to get the // `xcb_screen_t` structure, you have to iterate on the screens. The equivalent function of the // Xlib's `ScreenOfDisplay` function can be found below at ScreenOfDisplay. This is also provided // in the xcb_aux_t library as `xcb_aux_get_screen()`. OK, here is the small piece of code to get // that number: #[allow(unused)] fn example_get_screen_number() { let (conn, screen_num) = x11rb::connect(None).unwrap(); // screen_num now contains the number of the default screen } // QLength // // Not documented yet. // // However, this points out a basic difference in philosophy between Xlib and XCB. Xlib has several // functions for filtering and manipulating the incoming and outgoing X message queues. XCB wishes // to hide this as much as possible from the user, which allows for more freedom in implementation // strategies. // // // ScreenCount // // You get the count of screens with the functions `xcb_get_setup` and `xcb_setup_roots_iterator` // (if you need to iterate): #[allow(unused)] fn example_get_screen_count() { let (conn, screen_num) = x11rb::connect(None).unwrap(); let _screen_count = conn.setup().roots.len(); // screen_num now contains the number of the default screen } // ServerVendor // // You get the name of the vendor of the server hardware with the functions `xcb_get_setup` and // `xcb_setup_vendor`. See the next example. // // // ProtocolVersion // // You get the major version of the protocol in the `xcb_setup_t` structure, with the function // `xcb_get_setup`. See the next example. // // // ProtocolRevision // // You get the minor version of the protocol in the `xcb_setup_t` structure, with the function // `xcb_get_setup`. See the next example. // // // VendorRelease // // You get the number of the release of the server hardware in the `xcb_setup_t` structure, with // the function `xcb_get_setup`. See the next example // // // DisplayString // // The name of the display is not stored in XCB. You have to store it by yourself. // // // BitmapUnit // // You get the bitmap scanline unit in the `xcb_setup_t` structure, with the function // `xcb_get_setup`. See the next example. // // // BitmapBitOrder // // You get the bitmap bit order in the `xcb_setup_t` structure, with the function `xcb_get_setup`. // See the next example. // // // BitmapPad // // You get the bitmap scanline pad in the `xcb_setup_t` structure, with the function // `xcb_get_setup`. See the next example. // // // ImageByteOrder // // You get the image byte order in the `xcb_setup_t` structure, with the function `xcb_get_setup`. // See the next example. fn example11() -> Result<(), Box> { let (conn, _) = x11rb::connect(None)?; let setup = conn.setup(); println!( "Name of server vendor is {}", String::from_utf8_lossy(&setup.vendor) ); println!("Release number is {}", setup.release_number); println!( "Protocol version is {}.{}", setup.protocol_major_version, setup.protocol_minor_version ); println!( "Bitmap format scanline unit is {}", setup.bitmap_format_scanline_unit ); println!( "Bitmap format bit order is {:?}", setup.bitmap_format_bit_order ); println!( "Bitmap format scanline pad is {}", setup.bitmap_format_scanline_pad ); println!("Image byte order is {:?}", setup.image_byte_order); Ok(()) } // ScreenOfDisplay related functions // --------------------------------- // // In Xlib, `ScreenOfDisplay` returns a `Screen` structure that contains several characteristics of // your screen. XCB has a similar structure (`xcb_screen_t`), but the way to obtain it is a bit // different. With Xlib, you just provide the number of the screen and you grab it from an array. // With XCB, you iterate over all the screens to obtain the one you want. The complexity of this // operation is O(n). So the best is to store this structure if you use it often. See // ScreenOfDisplay just below. // // Xlib provides generally two functions to obtain the characteristics related to the screen. One // with the display and the number of the screen, which calls `ScreenOfDisplay`, and the other that // uses the `Screen` structure. This might be a bit confusing. As mentioned above, with XCB, it is // better to store the `xcb_screen_t` structure. Then, you have to read the members of this // structure. That's why the Xlib functions are put by pairs (or more) as, with XCB, you will use // the same code. // // // ScreenOfDisplay // // This function returns the Xlib `Screen` structure. With XCB, you iterate over all the screens // and once you get the one you want, you return it: #[allow(unused)] fn example_get_screen(conn: &C, index: usize) -> &Screen { &conn.setup().roots[index] } // As mentioned above, you might want to store the value returned by this function. // // All the functions below will use the result of that function, as they just grab a specific // member of the `xcb_screen_t` structure. // // // DefaultScreenOfDisplay // // It is the default screen that you obtain when you connect to the X server. It suffices to call // the example_get_screen() function above with the connection and the number of the default // screen. #[allow(unused)] fn example_get_screen2(conn: &C, index: usize) { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None).unwrap(); let _default_screen = &conn.setup().roots[screen_num]; } // RootWindow / RootWindowOfScreen // // Just use the .root member of `Screen`. #[allow(unused)] fn example_get_root(conn: &C, index: usize) -> Window { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None).unwrap(); let default_screen = &conn.setup().roots[screen_num]; default_screen.root } // DefaultRootWindow // // It is the root window of the default screen. So, you call `ScreenOfDisplay` with the default // screen number and you get the root window as above in example_get_root(). // // // DefaultVisual / DefaultVisualOfScreen // // While a Visual is, in Xlib, a structure, in XCB, there are two types: `xcb_visualid_t`, which is // the Id of the visual, and `xcb_visualtype_t`, which corresponds to the Xlib Visual. To get the // Id of the visual of a screen, just get the `root_visual` member of a `xcb_screen_t`: #[allow(unused)] fn example_get_visual() { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None).unwrap(); let screen = &conn.setup().roots[screen_num]; let _root_visual = screen.root_visual; } // To get the `xcb_visualtype_t` structure, it's a bit less easy. You have to get the // `xcb_screen_t` structure that you want, get its `root_visual` member, then iterate over the // `xcb_depth_t`s and the `xcb_visualtype_t`s, and compare the `xcb_visualid_t` of these // `xcb_visualtype_t`s: with `root_visual`: #[allow(unused)] fn example_get_visual2(conn: &C, screen_num: usize) { // Open the connection to the X server. Use the DISPLAY environment variable. let (conn, screen_num) = x11rb::connect(None).unwrap(); let screen = &conn.setup().roots[screen_num]; for depth in &screen.allowed_depths { for visualtype in &depth.visuals { if visualtype.visual_id == screen.root_visual { println!("Found: {:?}", visualtype); } } } } // DefaultGC / DefaultGCOfScreen // // This default Graphic Context is just a newly created Graphic Context, associated to the root // window of a `xcb_screen_t`, using the black white pixels of that screen: #[allow(unused)] fn example_create_default_gc( conn: &C, screen_num: usize, ) -> Result { let screen = &conn.setup().roots[screen_num]; let values = CreateGCAux::default() .foreground(screen.black_pixel) .background(screen.white_pixel); let gc = conn.generate_id()?; conn.create_gc(gc, screen.root, &values)?; Ok(gc) } // BlackPixel / BlackPixelOfScreen // // It is the Id of the black pixel, which is in the structure of an `xcb_screen_t`. #[allow(unused)] fn example_black_pixel(conn: &C, screen_num: usize) { let _black_pixel = conn.setup().roots[screen_num].black_pixel; } // WhitePixel / WhitePixelOfScreen // // It is the Id of the white pixel, which is in the structure of an `xcb_screen_t`. #[allow(unused)] fn example_white_pixel(conn: &C, screen_num: usize) { let _white_pixel = conn.setup().roots[screen_num].white_pixel; } // DisplayWidth / WidthOfScreen // // It is the width in pixels of the screen that you want, and which is in the structure of the // corresponding `xcb_screen_t`. #[allow(unused)] fn example_display_width(conn: &C, screen_num: usize) { let _width = conn.setup().roots[screen_num].width_in_pixels; } // DisplayHeight / HeightOfScreen // // It is the height in pixels of the screen that you want, and which is in the structure of the // corresponding `xcb_screen_t`. #[allow(unused)] fn example_display_height(conn: &C, screen_num: usize) { let _height = conn.setup().roots[screen_num].height_in_pixels; } // DisplayWidthMM / WidthMMOfScreen // // It is the width in millimeters of the screen that you want, and which is in the structure of the // corresponding `xcb_screen_t`. #[allow(unused)] fn example_display_width_mm(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _width = screen.width_in_millimeters; } // DisplayHeightMM / HeightMMOfScreen // // It is the height in millimeters of the screen that you want, and which is in the structure of // the corresponding `xcb_screen_t`. #[allow(unused)] fn example_display_height_mm(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _height = screen.height_in_millimeters; } // DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen // // It is the depth (in bits) of the root window of the screen. You get it from the `xcb_screen_t` // structure. #[allow(unused)] fn example_display_depth(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _depth = screen.root_depth; } // DefaultColormap / DefaultColormapOfScreen // // This is the default colormap of the screen (and not the (default) colormap of the default screen // !). As usual, you get it from the `xcb_screen_t` structure: #[allow(unused)] fn example_display_colormap(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _map = screen.default_colormap; } // MinCmapsOfScreen // // You get the minimum installed colormaps in the `xcb_screen_t` structure: #[allow(unused)] fn example_display_min_installed_maps(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _min_installed = screen.min_installed_maps; } // MaxCmapsOfScreen // // You get the maximum installed colormaps in the `xcb_screen_t` structure: #[allow(unused)] fn example_display_max_installed_maps(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _max_installed = screen.max_installed_maps; } // DoesSaveUnders // // You know if `save_unders` is set, by looking in the `xcb_screen_t` structure: #[allow(unused)] fn example_save_unders(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _save_unders = screen.save_unders; } // DoesBackingStore // // You know the value of `backing_stores`, by looking in the `xcb_screen_t` structure: #[allow(unused)] fn example_backing_store(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _backing_stores = screen.backing_stores; } // EventMaskOfScreen // // To get the current input masks, you look in the `xcb_screen_t` structure: #[allow(unused)] fn example_input_masks(conn: &C, screen_num: usize) { let screen = &conn.setup().roots[screen_num]; let _input_masks = screen.current_input_masks; } // Miscellaneous macros // -------------------- // // // DisplayOfScreen // // in Xlib, the `Screen` structure stores its associated `Display` structure. This is not the case in the X Window protocol, hence, it's also not the case in XCB. So you have to store it by yourself. // // // DisplayCells / CellsOfScreen // // To get the colormap entries, you look in the `xcb_visualtype_t` structure, that you grab as // shown above: #[allow(unused)] fn example_visual_colormap_entries(visual: &Visualtype) -> u16 { visual.colormap_entries } fn main() { example1().unwrap(); example2().unwrap(); example3().unwrap(); example4().unwrap(); example5().unwrap(); example6().unwrap(); example7().unwrap(); example8().unwrap(); example9().unwrap(); example10().unwrap(); example11().unwrap(); } x11rb-0.8.1/examples/xclock_utc.rs010064400017500001750000000224371402220031600151560ustar 00000000000000use std::convert::TryFrom; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; use x11rb::atom_manager; use x11rb::connection::Connection; use x11rb::errors::{ConnectionError, ReplyOrIdError}; use x11rb::protocol::xproto::*; use x11rb::protocol::Event; use x11rb::rust_connection::RustConnection; use x11rb::wrapper::ConnectionExt as _; atom_manager! { pub Atoms: AtomsCookie { UTF8_STRING, WM_DELETE_WINDOW, WM_PROTOCOLS, _NET_WM_NAME, } } fn create_window( conn: &impl Connection, screen: &Screen, atoms: &Atoms, (width, height): (u16, u16), ) -> Result { let win_id = conn.generate_id()?; let win_aux = CreateWindowAux::new().event_mask(EventMask::EXPOSURE | EventMask::STRUCTURE_NOTIFY); conn.create_window( screen.root_depth, win_id, screen.root, 0, 0, width, height, 0, WindowClass::INPUT_OUTPUT, 0, &win_aux, )?; let title = "xclock"; conn.change_property8( PropMode::REPLACE, win_id, AtomEnum::WM_NAME, AtomEnum::STRING, title.as_bytes(), )?; conn.change_property8( PropMode::REPLACE, win_id, atoms._NET_WM_NAME, atoms.UTF8_STRING, title.as_bytes(), )?; conn.change_property32( PropMode::REPLACE, win_id, atoms.WM_PROTOCOLS, AtomEnum::ATOM, &[atoms.WM_DELETE_WINDOW], )?; conn.map_window(win_id)?; Ok(win_id) } fn redraw( conn: &impl Connection, screen: &Screen, win_id: Window, gc_id: Gcontext, (width, height): (u16, u16), ) -> Result<(), ConnectionError> { let (hour, minute, second) = get_time(); let center = ((width as f32) / 2.0, (height as f32) / 2.0); let size = (width.min(height) as f32) / 2.0; // Transform a value between 0 and 60 to a position on the clock (relative to the center) let minute_to_outer_position = |minute: f32| { let angle = (30.0 - minute) * 2.0 * std::f32::consts::PI / 60.0; let (sin, cos) = angle.sin_cos(); (size * sin, size * cos) }; // Create a line segment fn create_line(center: (f32, f32), from: (f32, f32), to: (f32, f32)) -> Segment { Segment { x1: (center.0 + from.0).round() as _, y1: (center.1 + from.1).round() as _, x2: (center.0 + to.0).round() as _, y2: (center.1 + to.1).round() as _, } } // Draw the background conn.change_gc(gc_id, &ChangeGCAux::new().foreground(screen.white_pixel))?; conn.poly_fill_rectangle( win_id, gc_id, &[Rectangle { x: 0, y: 0, width, height, }], )?; conn.change_gc(gc_id, &ChangeGCAux::new().foreground(screen.black_pixel))?; // Get a list of lines for the clock's face let mut lines = (0..60) .map(|minute| { let outer = minute_to_outer_position(minute as _); let length_factor = if minute % 5 == 0 { 0.8 } else { 0.9 }; create_line( center, outer, (outer.0 * length_factor, outer.1 * length_factor), ) }) .collect::>(); // ... and also the hand for seconds lines.push(create_line( center, (0.0, 0.0), minute_to_outer_position(second as _), )); // Draw everything conn.poly_segment(win_id, gc_id, &lines)?; // Now draw the hands let point = |pos: (f32, f32), factor: f32| Point { x: (center.0 + pos.0 * factor).round() as _, y: (center.1 + pos.1 * factor).round() as _, }; let hour_to_60 = (hour % 12) as f32 * 60.0 / 12.0; for &(position, hand_length, hand_width) in &[(hour_to_60, 0.6, 0.08), (minute as f32, 0.8, 0.05)] { let outer = minute_to_outer_position(position); let ortho1 = (outer.1, -outer.0); let ortho2 = (-outer.1, outer.0); let opposite = (-outer.0, -outer.1); let polygon = [ point(ortho1, hand_width), point(opposite, hand_width), point(ortho2, hand_width), point(outer, hand_length), ]; conn.fill_poly( win_id, gc_id, PolyShape::COMPLEX, CoordMode::ORIGIN, &polygon, )?; } Ok(()) } #[cfg(unix)] fn poll_with_timeout( conn: &RustConnection, timeout: Duration, ) -> Result<(), Box> { use std::os::raw::c_int; use std::os::unix::io::AsRawFd; use nix::poll::{poll, PollFd, PollFlags}; let start_instant = Instant::now(); let fd = conn.stream().as_raw_fd(); let mut poll_fds = [PollFd::new(fd, PollFlags::POLLIN)]; loop { let timeout_millis = timeout .checked_sub(start_instant.elapsed()) .map(|remaining| c_int::try_from(remaining.as_millis()).unwrap_or(c_int::max_value())) .unwrap_or(0); match poll(&mut poll_fds, timeout_millis) { Ok(_) => { if poll_fds[0] .revents() .unwrap_or_else(PollFlags::empty) .contains(PollFlags::POLLIN) { break; } } // try again Err(nix::Error::Sys(nix::errno::Errno::EINTR)) => {} Err(e) => return Err(e.into()), } if start_instant.elapsed() >= timeout { break; } } // We do not really care about the result of poll. Either there was a timeout, in which case we // try to handle events (there are none) and then redraw. Or there was an event, in which case // we handle it and then still redraw. Ok(()) } #[cfg(windows)] fn poll_with_timeout( conn: &RustConnection, timeout: Duration, ) -> Result<(), Box> { use std::os::windows::io::AsRawSocket; use winapi::shared::minwindef::INT; use winapi::um::winsock2::{POLLRDNORM, SOCKET, WSAPOLLFD}; use winapi_wsapoll::wsa_poll; let start_instant = Instant::now(); let raw_socket = conn.stream().as_raw_socket(); let mut poll_fds = [WSAPOLLFD { fd: raw_socket as SOCKET, events: POLLRDNORM, revents: 0, }]; loop { let timeout_millis = timeout .checked_sub(start_instant.elapsed()) .map(|remaining| INT::try_from(remaining.as_millis()).unwrap_or(INT::max_value())) .unwrap_or(0); match wsa_poll(&mut poll_fds, timeout_millis) { Ok(_) => { if (poll_fds[0].revents & POLLRDNORM) != 0 { break; } } Err(e) => return Err(e.into()), } if start_instant.elapsed() >= timeout { break; } } // We do not really care about the result of poll. Either there was a timeout, in which case we // try to handle events (there are none) and then redraw. Or there was an event, in which case // we handle it and then still redraw. Ok(()) } fn main() -> Result<(), Box> { let (conn, screen_num) = RustConnection::connect(None)?; // The following is only needed for start_timeout_thread(), which is used for 'tests' let conn1 = std::sync::Arc::new(conn); let conn = &*conn1; let screen = &conn.setup().roots[screen_num]; let atoms = Atoms::new(conn)?.reply()?; let (mut width, mut height) = (100, 100); let win_id = create_window(conn, &screen, &atoms, (width, height))?; let gc_id = conn.generate_id().unwrap(); conn.create_gc(gc_id, win_id, &CreateGCAux::default())?; util::start_timeout_thread(conn1.clone(), win_id); conn.flush()?; loop { poll_with_timeout(conn, Duration::from_millis(1_000))?; while let Some(event) = conn.poll_for_event()? { println!("{:?})", event); match event { Event::ConfigureNotify(event) => { width = event.width; height = event.height; } Event::ClientMessage(event) => { let data = event.data.as_data32(); if event.format == 32 && event.window == win_id && data[0] == atoms.WM_DELETE_WINDOW { println!("Window was asked to close"); return Ok(()); } } Event::Error(_) => println!("Got an unexpected error"), _ => println!("Got an unknown event"), } } redraw(conn, &screen, win_id, gc_id, (width, height))?; conn.flush()?; } } /// Get the current time as (hour, minute, second) fn get_time() -> (u8, u8, u8) { let total_secs = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs(); let (second, total_minutes) = (total_secs % 60, total_secs / 60); let (minute, total_hours) = (total_minutes % 60, total_minutes / 60); let hour = total_hours % 24; // This is in UTC. Getting local time is complicated and not important for us. (hour as _, minute as _, second as _) } include!("integration_test_util/util.rs"); x11rb-0.8.1/examples/xeyes.rs010064400017500001750000000261631402220031600141550ustar 00000000000000// This is (quite loosely) based on the original xeyes extern crate x11rb; use x11rb::connection::{Connection, RequestConnection as _}; use x11rb::errors::{ConnectionError, ReplyOrIdError}; use x11rb::protocol::shape::{self, ConnectionExt as _}; use x11rb::protocol::xproto::*; use x11rb::protocol::Event; use x11rb::wrapper::ConnectionExt as _; use x11rb::COPY_DEPTH_FROM_PARENT; const PUPIL_SIZE: i16 = 50; const EYE_SIZE: i16 = 50; // Draw the big background of the eyes fn draw_eyes( conn: &C, win_id: Window, black: Gcontext, white: Gcontext, window_size: (u16, u16), ) -> Result<(), ConnectionError> { // Draw the black outlines let mut arc1 = Arc { x: 0, y: 0, width: window_size.0 / 2, height: window_size.1, angle1: 0, angle2: 360 * 64, }; let mut arc2 = arc1; arc2.x = arc2.width as _; conn.poly_fill_arc(win_id, black, &[arc1, arc2])?; // Draw the white inner part for mut arc in [&mut arc1, &mut arc2].iter_mut() { arc.x += EYE_SIZE; arc.y += EYE_SIZE; arc.width -= 2 * EYE_SIZE as u16; arc.height -= 2 * EYE_SIZE as u16; } conn.poly_fill_arc(win_id, white, &[arc1, arc2])?; Ok(()) } // Draw the pupils inside the eye fn draw_pupils( conn: &C, win_id: Window, gc: Gcontext, ((x1, y1), (x2, y2)): ((i16, i16), (i16, i16)), ) -> Result<(), ConnectionError> { // Transform center to top left corner let (x1, y1) = (x1 - PUPIL_SIZE / 2, y1 - PUPIL_SIZE / 2); let (x2, y2) = (x2 - PUPIL_SIZE / 2, y2 - PUPIL_SIZE / 2); let arc1 = Arc { x: x1, y: y1, width: PUPIL_SIZE as _, height: PUPIL_SIZE as _, angle1: 90 * 64, angle2: 360 * 64, }; let mut arc2 = arc1; arc2.x = x2; arc2.y = y2; // Do the drawing conn.poly_fill_arc(win_id, gc, &[arc1, arc2])?; Ok(()) } // Given two points, return their squared distance fn distance_squared(p1: (f64, f64), p2: (f64, f64)) -> f64 { let dx = p1.0 - p2.0; let dy = p1.1 - p2.1; dx * dx + dy * dy } // Compute the position of a pupil inside of the given area. fn compute_pupil(area: (i16, i16, i16, i16), mouse: (i16, i16)) -> (i16, i16) { // What is the center of the eye? let center_x = area.0 + area.2 / 2; let center_y = area.1 + area.3 / 2; let (w, h) = (f64::from(area.2) / 2.0, f64::from(area.3) / 2.0); // Is the mouse exactly on the center? if (center_x, center_y) == mouse { return mouse; } let center = (f64::from(center_x), f64::from(center_y)); let mouse = (f64::from(mouse.0), f64::from(mouse.1)); // Calculate the offset of the mouse position from the center let diff = (mouse.0 - center.0, mouse.1 - center.1); // An eclipse is described by this equation, where the angle 'a' is varied over all values, but // does not actually describe the angle from the center due to the different scaling in x and y // direction. // // x = w * cos(a) // y = h * sin(a) // // With tan(a) = sin(a)/cos(a), we get // // tan(a) * x = w * sin(a) => sin(a) = tan(a) * x / w // y = h * sin(a) => sin(a) = y / h // // and thus // // tan(a) * x / w = y / h // // which we can rearrange to // // tan(a) = (y * w) / (x * h) // // And thus, the angle we are looking for is: // // a = arctan((y * w) / (x * h)) // // However, due to tan() being the way it is, we actually need: let angle = (diff.1 * w).atan2(diff.0 * h); // Now compute the corresponding point on the ellipse (relative to the center) let (cx, cy) = (w * angle.cos(), h * angle.sin()); // ...and also compute the actual point let (x, y) = ((center.0 + cx) as _, (center.1 + cy) as _); // Return the point that is closer to the center if distance_squared(center, mouse) < distance_squared(center, (x, y)) { (mouse.0 as _, mouse.1 as _) } else { (x as _, y as _) } } // Compute the position of both pupils. fn compute_pupils(window_size: (u16, u16), mouse_position: (i16, i16)) -> ((i16, i16), (i16, i16)) { let border = PUPIL_SIZE + EYE_SIZE; let half_width = window_size.0 as i16 / 2; let width = half_width - 2 * border; let height = window_size.1 as i16 - 2 * border; ( compute_pupil((border, border, width, height), mouse_position), compute_pupil((border + half_width, border, width, height), mouse_position), ) } struct FreePixmap<'c, C: Connection>(&'c C, Pixmap); impl Drop for FreePixmap<'_, C> { fn drop(&mut self) { self.0.free_pixmap(self.1).unwrap(); } } struct FreeGC<'c, C: Connection>(&'c C, Gcontext); impl Drop for FreeGC<'_, C> { fn drop(&mut self) { self.0.free_gc(self.1).unwrap(); } } fn create_pixmap_wrapper( conn: &C, depth: u8, drawable: Drawable, size: (u16, u16), ) -> Result, ReplyOrIdError> { let pixmap = conn.generate_id()?; conn.create_pixmap(depth, pixmap, drawable, size.0, size.1)?; Ok(FreePixmap(conn, pixmap)) } fn shape_window( conn: &C, win_id: Window, window_size: (u16, u16), ) -> Result<(), ReplyOrIdError> { // Create a pixmap for the shape let pixmap = create_pixmap_wrapper(conn, 1, win_id, window_size)?; // Fill the pixmap with what will indicate "transparent" let gc = create_gc_with_foreground(conn, pixmap.1, 0)?; let _free_gc = FreeGC(conn, gc); let rect = Rectangle { x: 0, y: 0, width: window_size.0, height: window_size.1, }; conn.poly_fill_rectangle(pixmap.1, gc, &[rect])?; // Draw the eyes as "not transparent" let values = ChangeGCAux::new().foreground(1); conn.change_gc(gc, &values)?; draw_eyes(conn, pixmap.1, gc, gc, window_size)?; // Set the shape of the window conn.shape_mask(shape::SO::SET, shape::SK::BOUNDING, win_id, 0, 0, pixmap.1)?; Ok(()) } fn setup_window( conn: &C, screen: &Screen, window_size: (u16, u16), wm_protocols: Atom, wm_delete_window: Atom, ) -> Result { let win_id = conn.generate_id()?; let win_aux = CreateWindowAux::new() .event_mask(EventMask::EXPOSURE | EventMask::STRUCTURE_NOTIFY | EventMask::POINTER_MOTION) .background_pixel(screen.white_pixel); conn.create_window( COPY_DEPTH_FROM_PARENT, win_id, screen.root, 0, 0, window_size.0, window_size.1, 0, WindowClass::INPUT_OUTPUT, 0, &win_aux, )?; let title = "xeyes"; conn.change_property8( PropMode::REPLACE, win_id, AtomEnum::WM_NAME, AtomEnum::STRING, title.as_bytes(), ) .unwrap(); conn.change_property32( PropMode::REPLACE, win_id, wm_protocols, AtomEnum::ATOM, &[wm_delete_window], ) .unwrap(); conn.map_window(win_id).unwrap(); Ok(win_id) } fn create_gc_with_foreground( conn: &C, win_id: Window, foreground: u32, ) -> Result { let gc = conn.generate_id()?; let gc_aux = CreateGCAux::new() .graphics_exposures(0) .foreground(foreground); conn.create_gc(gc, win_id, &gc_aux)?; Ok(gc) } fn main() { let (conn, screen_num) = x11rb::connect(None).expect("Failed to connect to the X11 server"); // The following is only needed for start_timeout_thread(), which is used for 'tests' let conn1 = std::sync::Arc::new(conn); let conn = &*conn1; let screen = &conn.setup().roots[screen_num]; let wm_protocols = conn.intern_atom(false, b"WM_PROTOCOLS").unwrap(); let wm_delete_window = conn.intern_atom(false, b"WM_DELETE_WINDOW").unwrap(); let mut window_size = (700, 500); let has_shape = conn .extension_information(shape::X11_EXTENSION_NAME) .expect("failed to get extension information") .is_some(); let (wm_protocols, wm_delete_window) = ( wm_protocols.reply().unwrap().atom, wm_delete_window.reply().unwrap().atom, ); let win_id = setup_window(conn, screen, window_size, wm_protocols, wm_delete_window).unwrap(); let mut pixmap = create_pixmap_wrapper(conn, screen.root_depth, win_id, window_size).unwrap(); let black_gc = create_gc_with_foreground(conn, win_id, screen.black_pixel).unwrap(); let white_gc = create_gc_with_foreground(conn, win_id, screen.white_pixel).unwrap(); conn.flush().unwrap(); let mut need_repaint = false; let mut need_reshape = false; let mut mouse_position = (0, 0); util::start_timeout_thread(conn1.clone(), win_id); loop { let event = conn.wait_for_event().unwrap(); let mut event_option = Some(event); while let Some(event) = event_option { match event { Event::Expose(event) => { if event.count == 0 { need_repaint = true; } } Event::ConfigureNotify(event) => { window_size = (event.width, event.height); pixmap = create_pixmap_wrapper(conn, screen.root_depth, win_id, window_size) .unwrap(); need_reshape = true; } Event::MotionNotify(event) => { mouse_position = (event.event_x, event.event_y); need_repaint = true; } Event::MapNotify(_) => { need_reshape = true; } Event::ClientMessage(event) => { let data = event.data.as_data32(); if event.format == 32 && event.window == win_id && data[0] == wm_delete_window { println!("Window was asked to close"); return; } } Event::Error(error) => { println!("Unknown error {:?}", error); } event => { println!("Unknown event {:?}", event); } } event_option = conn.poll_for_event().unwrap(); } if need_reshape && has_shape { shape_window(conn, win_id, window_size).unwrap(); need_reshape = false; } if need_repaint { // Draw new pupils let pos = compute_pupils(window_size, mouse_position); draw_eyes(conn, pixmap.1, black_gc, white_gc, window_size).unwrap(); draw_pupils(conn, pixmap.1, black_gc, pos).unwrap(); // Copy drawing from pixmap to window conn.copy_area( pixmap.1, win_id, white_gc, 0, 0, 0, 0, window_size.0, window_size.1, ) .unwrap(); conn.flush().unwrap(); need_repaint = false; } } } include!("integration_test_util/util.rs"); x11rb-0.8.1/src/connection.rs010064400017500001750000000552771402220031600141400ustar 00000000000000//! Generic connection-related types and definitions. //! //! This module contains the `Connection` trait and related definitions. The code in this module is //! used by each concrete implementation of the X11 protocol. use std::borrow::Cow; use std::convert::{TryFrom, TryInto}; use std::io::IoSlice; use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError, ReplyError, ReplyOrIdError}; use crate::protocol::xproto::Setup; use crate::protocol::Event; use crate::utils::RawFdContainer; use crate::x11_utils::{ExtensionInformation, TryParse, TryParseFd, X11Error}; /// Number type used for referring to things that were sent to the server in responses from the /// server. /// /// Each request sent to the X11 server is implicitly assigned a monotonically increasing sequence /// number. Replies, events, and errors contain the sequence number of the last request that the /// server received. This allows to map replies to their requests and to figure out which request /// caused an error. pub type SequenceNumber = u64; // Used to avoid too-complex types. /// A combination of a buffer and a list of file descriptors. pub type BufWithFds = (B, Vec); /// An event and its sequence number. pub type EventAndSeqNumber = (Event, SequenceNumber); /// The raw bytes of an event and its sequence number. pub type RawEventAndSeqNumber = (B, SequenceNumber); /// A buffer that is logically continuous, but presented in a number of pieces. pub type PiecewiseBuf<'a> = Vec>; /// Either a raw reply or a raw error response to an X11 request. #[derive(Debug)] pub enum ReplyOrError where R: std::fmt::Debug, E: AsRef<[u8]> + std::fmt::Debug, { /// The reply to an X11 request. Reply(R), /// An error caused by an X11 request. Error(E), } /// A connection to an X11 server for sending requests. /// /// This trait only contains functions that are used by other parts of this library. This means /// that users of this library will most likely not need these functions, unless they want to /// implement their own X11 connection. pub trait RequestConnection { /// Type used as buffer to store raw replies or events before /// they are parsed. type Buf: AsRef<[u8]> + std::fmt::Debug + Send + Sync + 'static; /// Send a request with a reply to the server. /// /// The `bufs` parameter describes the raw bytes that should be sent. The returned cookie /// allows to get the response. /// /// The `fds` parameter contains a list of file descriptors that should be sent with the /// request. Ownership of these FDs is transferred to the connection. This means that the /// connection will close the FDs after they were sent. /// /// Users of this library will most likely not want to use this function directly. Instead, the /// generated code will take the supplied arguments, construct byte buffers, and call this /// method. /// /// The provided buffers must contain at least a single element and the first buffer must have /// at least four bytes. The length field must be set correctly, unless the request is larger /// than 2^18 bytes, because in this case, the length field would overflow. The connection /// automatically uses the BIG-REQUESTS extension for such large requests. /// /// In any case, the request may not be larger than the server's maximum request length. fn send_request_with_reply( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> where R: TryParse; /// Send a request with a reply containing file descriptors to the server. /// /// The `bufs` parameter describes the raw bytes that should be sent. The returned cookie /// allows to get the response. /// /// The `fds` parameter contains a list of file descriptors that should be sent with the /// request. Ownership of these FDs is transferred to the connection. This means that the /// connection will close the FDs after they were sent. /// /// Users of this library will most likely not want to use this function directly. Instead, the /// generated code will take the supplied arguments, construct byte buffers, and call this /// method. /// /// The provided buffers must contain at least a single element and the first buffer must have /// at least four bytes. The length field must be set correctly, unless the request is larger /// than 2^18 bytes, because in this case, the length field would overflow. The connection /// automatically uses the BIG-REQUESTS extension for such large requests. /// /// In any case, the request may not be larger than the server's maximum request length. fn send_request_with_reply_with_fds( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> where R: TryParseFd; /// Send a request without a reply to the server. /// /// The `bufs` parameter describes the raw bytes that should be sent. The sequence number of /// the request is returned, but most likely not useful to users. /// /// The `fds` parameter contains a list of file descriptors that should be sent with the /// request. Ownership of these FDs is transferred to the connection. This means that the /// connection will close the FDs after they were sent. /// /// Users of this library will most likely not want to use this function directly. Instead, the /// generated code will take the supplied arguments, construct byte buffers, and call this /// method. /// /// The provided buffers must contain at least a single element and the first buffer must have /// at least four bytes. The length field must be set correctly, unless the request is larger /// than 2^18 bytes, because in this case, the length field would overflow. The connection /// automatically uses the BIG-REQUESTS extension for such large requests. /// /// In any case, the request may not be larger than the server's maximum request length. fn send_request_without_reply( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError>; /// A reply to an error should be discarded. /// /// This method is automatically called by the `Drop` implementation on `Cookie` so that any /// replies that are received later can be ignored. /// /// Users of this library will most likely not want to use this function directly. fn discard_reply(&self, sequence: SequenceNumber, kind: RequestKind, mode: DiscardMode); /// Prefetches information about an extension. /// /// If the information of a extension is not cached yet, this function sends a /// `QueryExtension` request, but it does not wait for the reply. /// /// You can use `extension_information()` to get the reply of such request. /// /// Using this function can help to reduce round-trip latency, but you can use /// `extension_information()` directly without calling this function first. fn prefetch_extension_information( &self, extension_name: &'static str, ) -> Result<(), ConnectionError>; /// Get information about an extension. /// /// To send a request for some extension, information about the extension (major opcode, /// first event code and first error code) is necessary. This function provides this /// information. /// /// The returned object is guaranteed to have a non-zero `present` field. Extensions that are /// not present are instead returned as `None`. fn extension_information( &self, extension_name: &'static str, ) -> Result, ConnectionError>; /// Wait for the reply to a request. /// /// The given sequence number identifies the request for which replies are expected. If the X11 /// server answered the request with an error, that error is returned as an `Err`. /// /// Users of this library will most likely not want to use this function directly. fn wait_for_reply_or_error(&self, sequence: SequenceNumber) -> Result { match self.wait_for_reply_or_raw_error(sequence)? { ReplyOrError::Reply(reply) => Ok(reply), ReplyOrError::Error(error) => { Err(ReplyError::X11Error(self.parse_error(error.as_ref())?)) } } } /// Wait for the reply to a request. /// /// The given sequence number identifies the request for which replies are expected. If the X11 /// server answered the request with an error, that error is returned as an `Err`. /// /// Users of this library will most likely not want to use this function directly. fn wait_for_reply_or_raw_error( &self, sequence: SequenceNumber, ) -> Result, ConnectionError>; /// Wait for the reply to a request. /// /// The given sequence number identifies the request for which replies are expected. If the X11 /// server answered the request with an error, this function returns `None` and the error is /// instead returned by `wait_for_event()` or `poll_for_event()`. /// /// Users of this library will most likely not want to use this function directly. fn wait_for_reply( &self, sequence: SequenceNumber, ) -> Result, ConnectionError>; /// Wait for the reply to a request that has FDs. /// /// The given sequence number identifies the request for which replies are expected. /// /// Users of this library will most likely not want to use this function directly. fn wait_for_reply_with_fds( &self, sequence: SequenceNumber, ) -> Result, ReplyError> { match self.wait_for_reply_with_fds_raw(sequence)? { ReplyOrError::Reply(reply) => Ok(reply), ReplyOrError::Error(error) => { Err(ReplyError::X11Error(self.parse_error(error.as_ref())?)) } } } /// Wait for the reply to a request that has FDs. /// /// The given sequence number identifies the request for which replies are expected. /// /// Users of this library will most likely not want to use this function directly. fn wait_for_reply_with_fds_raw( &self, sequence: SequenceNumber, ) -> Result, Self::Buf>, ConnectionError>; /// Check whether a request that does not have a reply caused an X11 error. /// /// The given sequence number identifies the request for which the check should be performed. /// /// Users of this library will most likely not want to use this function directly. fn check_for_error(&self, sequence: SequenceNumber) -> Result<(), ReplyError> { match self.check_for_raw_error(sequence)? { Some(err) => Err(self.parse_error(err.as_ref())?.into()), None => Ok(()), } } /// Check whether a request that does not have a reply caused an X11 error. /// /// The given sequence number identifies the request for which the check should be performed. /// /// Users of this library will most likely not want to use this function directly. fn check_for_raw_error( &self, sequence: SequenceNumber, ) -> Result, ConnectionError>; /// Prefetches the maximum request length. /// /// If the maximum request length is not cached yet, this function sends a `BigRequests::Enable` /// request, but it does not wait for the reply. /// /// You can use `maximum_request_bytes()` to get the result of this request. /// /// Using this function can help to reduce round-trip latency, but you can use /// `maximum_request_bytes()` directly without calling this function first. /// /// Since this uses the `BigRequests` extension, the information about that extension needs to /// available. Otherwise, this has to wait for the reply when calling /// `extension_information()`. /// /// To prefetch the necessary information, you can do the following: /// ```no_run /// use x11rb::connection::RequestConnection; /// use x11rb::errors::ConnectionError; /// use x11rb::protocol::bigreq; /// # fn do_it(conn: impl RequestConnection) -> Result<(), ConnectionError> { /// // conn is a RequestConnection /// conn.prefetch_extension_information(bigreq::X11_EXTENSION_NAME)?; /// # Ok(()) /// # } /// ``` fn prefetch_maximum_request_bytes(&self); /// The maximum number of bytes that the X11 server accepts in a request. fn maximum_request_bytes(&self) -> usize; /// Parse a generic error. fn parse_error(&self, error: &[u8]) -> Result; /// Parse a generic event. fn parse_event(&self, event: &[u8]) -> Result; } /// A connection to an X11 server. pub trait Connection: RequestConnection { /// Wait for a new event from the X11 server. fn wait_for_event(&self) -> Result { Ok(self.wait_for_event_with_sequence()?.0) } /// Wait for a new raw/unparsed event from the X11 server. fn wait_for_raw_event(&self) -> Result { Ok(self.wait_for_raw_event_with_sequence()?.0) } /// Wait for a new event from the X11 server. fn wait_for_event_with_sequence(&self) -> Result { let (event, seq) = self.wait_for_raw_event_with_sequence()?; let event = self.parse_event(event.as_ref())?; Ok((event, seq)) } /// Wait for a new raw/unparsed event from the X11 server. fn wait_for_raw_event_with_sequence( &self, ) -> Result, ConnectionError>; /// Poll for a new event from the X11 server. fn poll_for_event(&self) -> Result, ConnectionError> { Ok(self.poll_for_event_with_sequence()?.map(|r| r.0)) } /// Poll for a new raw/unparsed event from the X11 server. fn poll_for_raw_event(&self) -> Result, ConnectionError> { Ok(self.poll_for_raw_event_with_sequence()?.map(|r| r.0)) } /// Poll for a new event from the X11 server. fn poll_for_event_with_sequence(&self) -> Result, ConnectionError> { Ok(match self.poll_for_raw_event_with_sequence()? { Some((event, seq)) => Some((self.parse_event(event.as_ref())?, seq)), None => None, }) } /// Poll for a new unparsed/raw event from the X11 server. fn poll_for_raw_event_with_sequence( &self, ) -> Result>, ConnectionError>; /// Send all pending requests to the server. /// /// Implementations of this trait may buffer requests for batched sending. When this method is /// called, all pending requests are sent. /// /// You do not have to call this method before `wait_for_reply()`. If the request you want to /// wait for was not yet sent, it will be sent by `wait_for_reply()`. fn flush(&self) -> Result<(), ConnectionError>; /// Get the setup information sent by the X11 server. /// /// The setup information contains X11 server, for example the window id of the root window. fn setup(&self) -> &Setup; /// Generate a new X11 identifier. /// /// This method can, for example, be used for creating a new window. First, this method is /// called to generate an identifier. Next, `xproto::create_window` can be called to /// actually create the window. fn generate_id(&self) -> Result; } /// Does a request have a response? #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum RequestKind { /// The request has no response, i.e. its type is "void". IsVoid, /// The request has a response. HasResponse, } /// Variants describing which responses to a request should be discarded. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum DiscardMode { /// Only discard the actual reply. Errors go to the main loop. DiscardReply, /// Ignore any kind of response that this request generates. DiscardReplyAndError, } /// Check the request length and use BIG-REQUESTS if necessary. /// /// Users of this library will most likely not want to use this function directly. /// /// This function is used by implementations of `RequestConnection` for sending requests. It /// examines the given request buffers and checks that the length field is set correctly. /// /// If the request has more than 2^18 bytes, this function handles using the BIG-REQUESTS /// extension. The request is rewritten to include the correct length field. For this case, the /// `storage` parameter is needed. This function uses it to store the necessary buffers. /// /// When using this function, it is recommended to allocate the `storage` parameter with /// `Default::default()`. /// /// Example usage: /// ``` /// use std::io::IoSlice; /// use x11rb::connection::{BufWithFds, RequestConnection, SequenceNumber, compute_length_field}; /// use x11rb::cookie::{Cookie, CookieWithFds, VoidCookie}; /// use x11rb::errors::{ParseError, ConnectionError}; /// use x11rb::utils::RawFdContainer; /// use x11rb::x11_utils::{ExtensionInformation, TryParse, TryParseFd}; /// # use x11rb::connection::ReplyOrError; /// /// struct MyConnection(); /// /// impl RequestConnection for MyConnection { /// type Buf = Vec; /// /// // [snip, other functions here] /// # fn discard_reply(&self, sequence: SequenceNumber, /// # kind: x11rb::connection::RequestKind, /// # mode: x11rb::connection::DiscardMode) { /// # unimplemented!() /// # } /// # fn prefetch_extension_information( /// # &self, /// # extension_name: &'static str, /// # ) -> Result<(), ConnectionError> { /// # unimplemented!() /// # } /// # fn extension_information(&self, ext: &'static str) /// # -> Result, ConnectionError> { /// # unimplemented!() /// # } /// # fn wait_for_reply_or_raw_error(&self, sequence: SequenceNumber) /// # -> Result>, ConnectionError> { /// # unimplemented!() /// # } /// # fn wait_for_reply(&self, sequence: SequenceNumber) /// # -> Result>, x11rb::errors::ConnectionError> { /// # unimplemented!() /// # } /// # fn wait_for_reply_with_fds_raw(&self, sequence: SequenceNumber) /// # -> Result>, Vec>, ConnectionError> { /// # unimplemented!() /// # } /// # fn check_for_raw_error(&self, sequence: SequenceNumber) /// # ->Result>, ConnectionError> { /// # unimplemented!() /// # } /// # fn maximum_request_bytes(&self) -> usize { /// # unimplemented!() /// # } /// # fn prefetch_maximum_request_bytes(&self) { /// # unimplemented!() /// # } /// # fn parse_error(&self, _error: &[u8]) -> Result { /// # unimplemented!() /// # } /// # fn parse_event(&self, _event: &[u8]) -> Result { /// # unimplemented!() /// # } /// /// fn send_request_with_reply(&self, bufs: &[IoSlice], fds: Vec) /// -> Result, ConnectionError> /// where R: TryParse { /// Ok(Cookie::new(self, self.send_request(bufs, fds, true, false)?)) /// } /// /// fn send_request_with_reply_with_fds(&self, bufs: &[IoSlice], fds: Vec) /// -> Result, ConnectionError> /// where R: TryParseFd { /// Ok(CookieWithFds::new(self, self.send_request(bufs, fds, true, true)?)) /// } /// /// fn send_request_without_reply(&self, bufs: &[IoSlice], fds: Vec) /// -> Result, ConnectionError> { /// Ok(VoidCookie::new(self, self.send_request(bufs, fds, false, false)?)) /// } /// } /// /// impl MyConnection { /// fn send_request(&self, bufs: &[IoSlice], fds: Vec, /// has_reply: bool, reply_has_fds: bool) /// -> Result /// { /// let mut storage = Default::default(); /// let bufs = compute_length_field(self, bufs, &mut storage)?; /// unimplemented!("Now send bufs and fds to the X11 server"); /// } /// } /// ``` pub fn compute_length_field<'b>( conn: &impl RequestConnection, request_buffers: &'b [IoSlice<'b>], storage: &'b mut (Vec>, [u8; 8]), ) -> Result<&'b [IoSlice<'b>], ConnectionError> { // Compute the total length of the request let length: usize = request_buffers.iter().map(|buf| buf.len()).sum(); assert_eq!( length % 4, 0, "The length of X11 requests must be a multiple of 4, got {}", length ); let wire_length = length / 4; let first_buf = &request_buffers[0]; // If the length fits into an u16, just return the request as-is if let Ok(wire_length) = u16::try_from(wire_length) { // Check that the request contains the correct length field let length_field = u16::from_ne_bytes([first_buf[2], first_buf[3]]); assert_eq!( wire_length, length_field, "Length field contains incorrect value" ); return Ok(request_buffers); } // Check that the total length is not too large if length > conn.maximum_request_bytes() { return Err(ConnectionError::MaximumRequestLengthExceeded); } // Okay, we need to use big requests (thus four extra bytes, "+1" below) let wire_length: u32 = wire_length .checked_add(1) .ok_or(ConnectionError::MaximumRequestLengthExceeded)? .try_into() .expect("X11 request larger than 2^34 bytes?!?"); let wire_length = wire_length.to_ne_bytes(); // Now construct the new IoSlices // Replacement for the first four bytes of the request storage.1.copy_from_slice(&[ // First part of the request first_buf[0], first_buf[1], // length field zero indicates big requests 0, 0, // New bytes: extended length wire_length[0], wire_length[1], wire_length[2], wire_length[3], ]); storage.0.push(IoSlice::new(&storage.1)); // The remaining part of the first buffer of the request storage.0.push(IoSlice::new(&first_buf[4..])); // and the rest of the request storage.0.extend( request_buffers[1..] .iter() .map(std::ops::Deref::deref) .map(IoSlice::new), ); Ok(&storage.0[..]) } x11rb-0.8.1/src/cookie.rs010064400017500001750000000326571402220031600132470ustar 00000000000000//! Cookies are handles to future replies or errors from the X11 server. //! //! When sending a request, you get back a cookie. There are different cookies for different //! kinds of requests. //! //! For requests without a reply, you get a [`VoidCookie`]. Requests with a reply are represented //! by a [`Cookie`] or a [`CookieWithFds`] if the reply also contains file descriptors. //! Additionally, there are two special cases for requests which generate more than one reply: //! [`ListFontsWithInfoCookie`] and [`RecordEnableContextCookie`]. //! //! # Handling X11 errors //! //! The X11 server can answer requests with an error packet for various reasons, e.g. because an //! invalid window ID was given. There are three options what can be done with errors: //! //! - Errors can appear as X11 events in `wait_for_event()` (in XCB, this is called "unchecked") //! - Errors can be checked for locally after a request was sent (in XCB, this is called "checked") //! - Errors can be completely ignored (the closest analog in XCB would be `xcb_discard_reply()`) //! //! There is an additional difference between requests with and without replies. //! //! ## Requests without a reply //! //! For requests that do not have a reply, you get an instance of `VoidCookie` after sending the //! request. The different behaviors can be achieved via interacting with this cookie as foolows: //! //! | What? | How? | //! | --------------- | -------------------------- | //! | Treat as events | Just drop the cookie | //! | Check locally | `VoidCookie::check` | //! | Ignore | `VoidCookie::ignore_error` | //! //! ## Requests with a reply //! //! For requests with a reply, an additional option is what should happen to the reply. You can get //! the reply, but any errors are still treated as events. This allows to centralise X11 error //! handling a bit in case you only want to log errors. //! //! The following things can be done with the `Cookie` that you get after sending a request with an //! error. //! //! | Reply | Errors locally/ignored | Errors as events | //! | ------ | ---------------------------------- | ------------------------- | //! | Get | `Cookie::reply` | `Cookie::reply_unchecked` | //! | Ignore | `Cookie::discard_reply_and_errors` | Just drop the cookie | use std::marker::PhantomData; use crate::connection::{BufWithFds, DiscardMode, RequestConnection, RequestKind, SequenceNumber}; use crate::errors::{ConnectionError, ReplyError}; #[cfg(feature = "record")] use crate::protocol::record::EnableContextReply; use crate::protocol::xproto::ListFontsWithInfoReply; use crate::x11_utils::{TryParse, TryParseFd}; /// A handle to a possible error from the X11 server. /// /// When sending a request for which no reply is expected, this library returns a `VoidCookie`. /// This `VoidCookie` can then later be used to check if the X11 server sent an error. /// /// See [crate::cookie#requests-without-a-reply] for infos on the different ways to handle X11 /// errors in response to a request. #[derive(Debug)] pub struct VoidCookie<'a, C> where C: RequestConnection + ?Sized, { connection: &'a C, sequence_number: SequenceNumber, } impl<'a, C> VoidCookie<'a, C> where C: RequestConnection + ?Sized, { /// Construct a new cookie. /// /// This function should only be used by implementations of /// `Connection::send_request_without_reply`. pub fn new(connection: &C, sequence_number: SequenceNumber) -> VoidCookie<'_, C> { VoidCookie { connection, sequence_number, } } /// Get the sequence number of the request that generated this cookie. pub fn sequence_number(&self) -> SequenceNumber { self.sequence_number } fn consume(self) -> (&'a C, SequenceNumber) { let result = (self.connection, self.sequence_number); std::mem::forget(self); result } /// Check if the original request caused an X11 error. pub fn check(self) -> Result<(), ReplyError> { let (connection, sequence) = self.consume(); connection.check_for_error(sequence) } /// Ignore all errors to this request. /// /// Without calling this method, an error becomes available on the connection as an event after /// this cookie was dropped. This function causes errors to be ignored instead. pub fn ignore_error(self) { let (connection, sequence) = self.consume(); connection.discard_reply( sequence, RequestKind::IsVoid, DiscardMode::DiscardReplyAndError, ) } } impl Drop for VoidCookie<'_, C> where C: RequestConnection + ?Sized, { fn drop(&mut self) { self.connection.discard_reply( self.sequence_number, RequestKind::IsVoid, DiscardMode::DiscardReply, ) } } /// Internal helper for a cookie with an response #[derive(Debug)] struct RawCookie<'a, C> where C: RequestConnection + ?Sized, { connection: &'a C, sequence_number: SequenceNumber, } impl RawCookie<'_, C> where C: RequestConnection + ?Sized, { /// Construct a new raw cookie. /// /// This function should only be used by implementations of /// `RequestConnection::send_request_with_reply`. fn new(connection: &C, sequence_number: SequenceNumber) -> RawCookie<'_, C> { RawCookie { connection, sequence_number, } } /// Consume this instance and get the contained sequence number out. fn into_sequence_number(self) -> SequenceNumber { let number = self.sequence_number; // Prevent drop() from running std::mem::forget(self); number } } impl Drop for RawCookie<'_, C> where C: RequestConnection + ?Sized, { fn drop(&mut self) { self.connection.discard_reply( self.sequence_number, RequestKind::HasResponse, DiscardMode::DiscardReply, ); } } /// A handle to a response from the X11 server. /// /// When sending a request to the X11 server, this library returns a `Cookie`. This `Cookie` can /// then later be used to get the response that the server sent. /// /// See [crate::cookie#requests-with-a-reply] for infos on the different ways to handle X11 /// errors in response to a request. #[derive(Debug)] pub struct Cookie<'a, C, R> where C: RequestConnection + ?Sized, { raw_cookie: RawCookie<'a, C>, phantom: PhantomData, } impl Cookie<'_, C, R> where R: TryParse, C: RequestConnection + ?Sized, { /// Construct a new cookie. /// /// This function should only be used by implementations of /// `RequestConnection::send_request_with_reply`. pub fn new(connection: &C, sequence_number: SequenceNumber) -> Cookie<'_, C, R> { Cookie { raw_cookie: RawCookie::new(connection, sequence_number), phantom: PhantomData, } } /// Get the sequence number of the request that generated this cookie. pub fn sequence_number(&self) -> SequenceNumber { self.raw_cookie.sequence_number } /// Get the raw reply that the server sent. pub fn raw_reply(self) -> Result { let conn = self.raw_cookie.connection; conn.wait_for_reply_or_error(self.raw_cookie.into_sequence_number()) } /// Get the raw reply that the server sent, but have errors handled as events. pub fn raw_reply_unchecked(self) -> Result, ConnectionError> { let conn = self.raw_cookie.connection; conn.wait_for_reply(self.raw_cookie.into_sequence_number()) } /// Get the reply that the server sent. pub fn reply(self) -> Result { Ok(R::try_parse(self.raw_reply()?.as_ref())?.0) } /// Get the reply that the server sent, but have errors handled as events. pub fn reply_unchecked(self) -> Result, ConnectionError> { self.raw_reply_unchecked()? .map(|buf| R::try_parse(buf.as_ref()).map(|r| r.0)) .transpose() .map_err(Into::into) } /// Discard all responses to the request this cookie represents, even errors. /// /// Without this function, errors are treated as events after the cookie is dropped. pub fn discard_reply_and_errors(self) { let conn = self.raw_cookie.connection; conn.discard_reply( self.raw_cookie.into_sequence_number(), RequestKind::HasResponse, DiscardMode::DiscardReplyAndError, ) } /// Consume this instance and get the contained sequence number out. pub(crate) fn into_sequence_number(self) -> SequenceNumber { self.raw_cookie.into_sequence_number() } } /// A handle to a response containing `RawFd` from the X11 server. /// /// When sending a request to the X11 server, this library returns a `Cookie`. This `Cookie` can /// then later be used to get the response that the server sent. /// /// This variant of `Cookie` represents a response that can contain `RawFd`s. /// /// See [crate::cookie#requests-with-a-reply] for infos on the different ways to handle X11 /// errors in response to a request. #[derive(Debug)] pub struct CookieWithFds<'a, C, R> where C: RequestConnection + ?Sized, { raw_cookie: RawCookie<'a, C>, phantom: PhantomData, } impl CookieWithFds<'_, C, R> where R: TryParseFd, C: RequestConnection + ?Sized, { /// Construct a new cookie. /// /// This function should only be used by implementations of /// `RequestConnection::send_request_with_reply`. pub fn new(connection: &C, sequence_number: SequenceNumber) -> CookieWithFds<'_, C, R> { CookieWithFds { raw_cookie: RawCookie::new(connection, sequence_number), phantom: PhantomData, } } /// Get the sequence number of the request that generated this cookie. pub fn sequence_number(&self) -> SequenceNumber { self.raw_cookie.sequence_number } /// Get the raw reply that the server sent. pub fn raw_reply(self) -> Result, ReplyError> { let conn = self.raw_cookie.connection; conn.wait_for_reply_with_fds(self.raw_cookie.into_sequence_number()) } /// Get the reply that the server sent. pub fn reply(self) -> Result { let (buffer, mut fds) = self.raw_reply()?; Ok(R::try_parse_fd(buffer.as_ref(), &mut fds)?.0) } } macro_rules! multiple_reply_cookie { ( $(#[$meta:meta])* pub struct $name:ident for $reply:ident ) => { $(#[$meta])* #[derive(Debug)] pub struct $name<'a, C: RequestConnection + ?Sized>(Option>); impl<'c, C> $name<'c, C> where C: RequestConnection + ?Sized, { pub(crate) fn new( cookie: Cookie<'c, C, $reply>, ) -> Self { Self(Some(cookie.raw_cookie)) } /// Get the sequence number of the request that generated this cookie. pub fn sequence_number(&self) -> Option { self.0.as_ref().map(|x| x.sequence_number) } } impl Iterator for $name<'_, C> where C: RequestConnection + ?Sized, { type Item = Result<$reply, ReplyError>; fn next(&mut self) -> Option { let cookie = match self.0.take() { None => return None, Some(cookie) => cookie, }; let reply = cookie .connection .wait_for_reply_or_error(cookie.sequence_number); let reply = match reply { Err(e) => return Some(Err(e)), Ok(v) => v, }; let reply = $reply::try_parse(reply.as_ref()); match reply { // Is this an indicator that no more replies follow? Ok(ref reply) if Self::is_last(&reply.0) => None, Ok(reply) => { self.0 = Some(cookie); Some(Ok(reply.0)) } Err(e) => Some(Err(e.into())), } } } } } multiple_reply_cookie!( /// A handle to the replies to a `ListFontsWithInfo` request. /// /// `ListFontsWithInfo` generated more than one reply, but `Cookie` only allows getting one reply. /// This structure implements `Iterator` and allows to get all the replies. pub struct ListFontsWithInfoCookie for ListFontsWithInfoReply ); impl ListFontsWithInfoCookie<'_, C> where C: RequestConnection + ?Sized, { fn is_last(reply: &ListFontsWithInfoReply) -> bool { reply.name.is_empty() } } #[cfg(feature = "record")] multiple_reply_cookie!( /// A handle to the replies to a `record::EnableContext` request. /// /// `EnableContext` generated more than one reply, but `Cookie` only allows getting one reply. /// This structure implements `Iterator` and allows to get all the replies. pub struct RecordEnableContextCookie for EnableContextReply ); #[cfg(feature = "record")] impl RecordEnableContextCookie<'_, C> where C: RequestConnection + ?Sized, { fn is_last(reply: &EnableContextReply) -> bool { // FIXME: There does not seem to be an enumeration of the category values, (value 5 is // EndOfData) reply.category == 5 } } x11rb-0.8.1/src/cursor/find_cursor.rs010064400017500001750000000272501402220031600156210ustar 00000000000000//! Find the right cursor file from a cursor name // Based on libxcb-cursor's load_cursor.c which has: // // Copyright © 2013 Michael Stapelberg // Copyright © 2002 Keith Packard // // and is licensed under MIT/X Consortium License use std::env::{var, var_os}; use std::ffi::OsStr; use std::fs::File; use std::io::{BufRead, BufReader, Error as IOError}; use std::path::{Path, PathBuf}; static CORE_CURSORS: &[(&str, u16)] = &[ ("X_cursor", 0), ("arrow", 1), ("based_arrow_down", 2), ("based_arrow_up", 3), ("boat", 4), ("bogosity", 5), ("bottom_left_corner", 6), ("bottom_right_corner", 7), ("bottom_side", 8), ("bottom_tee", 9), ("box_spiral", 10), ("center_ptr", 11), ("circle", 12), ("clock", 13), ("coffee_mug", 14), ("cross", 15), ("cross_reverse", 16), ("crosshair", 17), ("diamond_cross", 18), ("dot", 19), ("dotbox", 20), ("double_arrow", 21), ("draft_large", 22), ("draft_small", 23), ("draped_box", 24), ("exchange", 25), ("fleur", 26), ("gobbler", 27), ("gumby", 28), ("hand1", 29), ("hand2", 30), ("heart", 31), ("icon", 32), ("iron_cross", 33), ("left_ptr", 34), ("left_side", 35), ("left_tee", 36), ("leftbutton", 37), ("ll_angle", 38), ("lr_angle", 39), ("man", 40), ("middlebutton", 41), ("mouse", 42), ("pencil", 43), ("pirate", 44), ("plus", 45), ("question_arrow", 46), ("right_ptr", 47), ("right_side", 48), ("right_tee", 49), ("rightbutton", 50), ("rtl_logo", 51), ("sailboat", 52), ("sb_down_arrow", 53), ("sb_h_double_arrow", 54), ("sb_left_arrow", 55), ("sb_right_arrow", 56), ("sb_up_arrow", 57), ("sb_v_double_arrow", 58), ("shuttle", 59), ("sizing", 60), ("spider", 61), ("spraycan", 62), ("star", 63), ("target", 64), ("tcross", 65), ("top_left_arrow", 66), ("top_left_corner", 67), ("top_right_corner", 68), ("top_side", 69), ("top_tee", 70), ("trek", 71), ("ul_angle", 72), ("umbrella", 73), ("ur_angle", 74), ("watch", 75), ("xterm", 76), ]; /// Find a core cursor based on its name /// /// This function checks a built-in list of known names. fn cursor_shape_to_id(name: &str) -> Option { CORE_CURSORS .iter() .filter(|&(name2, _)| name == *name2) .map(|&(_, id)| id) .next() } /// An error that occurred while searching #[derive(Debug)] pub(crate) enum Error { /// `$HOME` is not set NoHomeDir, /// No cursor file could be found NothingFound, } /// The result of finding a cursor #[derive(Debug)] pub(crate) enum Cursor { /// The cursor is a core cursor that can be created with xproto's `CreateGlyphCursor` CoreChar(u16), /// A cursor file was opened File(F), } // Get the 'Inherits' entry from an index.theme file fn parse_inherits(filename: &Path) -> Result, IOError> { let file = File::open(filename)?; parse_inherits_impl(&mut BufReader::new(file)) } // Get the 'Inherits' entry from an index.theme file fn parse_inherits_impl(input: &mut impl BufRead) -> Result, IOError> { let mut buffer = Vec::new(); loop { buffer.clear(); // Read a line if 0 == input.read_until(b'\n', &mut buffer)? { // End of file, return an empty result return Ok(Default::default()); } // Remove end of line marker if buffer.last() == Some(&b'\n') { let _ = buffer.pop(); } let begin = b"Inherits"; if buffer.starts_with(begin) { let mut result = Vec::new(); let mut to_parse = &buffer[begin.len()..]; fn skip_while(mut slice: &[u8], f: impl Fn(u8) -> bool) -> &[u8] { while !slice.is_empty() && f(slice[0]) { slice = &slice[1..] } slice } // Skip all spaces to_parse = skip_while(to_parse, |c| c == b' '); // Now we need an equal sign if to_parse.get(0) == Some(&b'=') { to_parse = &to_parse[1..]; fn should_skip(c: u8) -> bool { match c { b' ' | b'\t' | b'\n' | b';' | b',' => true, _ => false, } } // Iterate over the pieces for mut part in to_parse.split(|&x| x == b':') { // Skip all leading whitespace part = skip_while(part, should_skip); // Skip all trailing whitespace while let Some((&last, rest)) = part.split_last() { if !should_skip(last) { break; } part = rest; } if !part.is_empty() { if let Ok(part) = std::str::from_utf8(part) { result.push(part.to_string()); } } } } return Ok(result); } } } #[cfg(test)] mod test_parse_inherits { use super::parse_inherits_impl; use std::io::Cursor; #[test] fn parse_inherits_successful() { let input = b"Hi\nInherits = \t ; whatever ;,::; stuff : i s ,: \tthis \t \nInherits=ignored\n"; let mut input = Cursor::new(&input[..]); let result = parse_inherits_impl(&mut input).unwrap(); assert_eq!(result, vec!["whatever", "stuff", "i s", "this"]); } } /// Find a cursor file based on the name of a cursor theme and the name of the cursor. pub(crate) fn find_cursor(theme: &str, name: &str) -> Result, Error> { let home = match var_os("HOME") { Some(home) => home, None => return Err(Error::NoHomeDir), }; let cursor_path = var("XCURSOR_PATH").unwrap_or_else(|_| { "~/.icons:/usr/share/icons:/usr/share/pixmaps:/usr/X11R6/lib/X11/icons".into() }); let open_cursor = |file: &Path| File::open(file); let parse_inherits = |file: &Path| parse_inherits(file); find_cursor_impl( &home, &cursor_path, theme, name, open_cursor, parse_inherits, ) } fn find_cursor_impl( home: &OsStr, cursor_path: &str, theme: &str, name: &str, mut open_cursor: G, mut parse_inherits: H, ) -> Result, Error> where G: FnMut(&Path) -> Result, H: FnMut(&Path) -> Result, IOError>, { if theme == "core" { if let Some(id) = cursor_shape_to_id(name) { return Ok(Cursor::CoreChar(id)); } } let cursor_path = cursor_path.split(':').collect::>(); let mut next_inherits = Vec::new(); let mut last_inherits = vec![theme.into()]; while !last_inherits.is_empty() { for theme in last_inherits { for path in &cursor_path { // Calculate the path to the theme's directory let mut theme_dir = PathBuf::new(); // Does the path begin with '~'? if path.starts_with('~') { theme_dir.push(&home); let mut path = &path[1..]; // Skip a path separator if there is one if path.chars().next().map(std::path::is_separator) == Some(true) { path = &path[1..]; } theme_dir.push(path); } else { theme_dir.push(path); } theme_dir.push(&theme); // Find the cursor in the theme let mut cursor_file = theme_dir.clone(); cursor_file.push("cursors"); cursor_file.push(name); if let Ok(file) = open_cursor(&cursor_file) { return Ok(Cursor::File(file)); } // Get the theme's index.theme file and parse its 'Inherits' line let mut index = theme_dir; index.push("index.theme"); if let Ok(res) = parse_inherits(&index) { next_inherits.extend(res); } } } last_inherits = next_inherits; next_inherits = Vec::new(); } Err(Error::NothingFound) } // FIXME: Make these tests pass on Windows; problem is "/" vs "\\" in paths #[cfg(all(test, unix))] mod test_find_cursor { use super::{find_cursor_impl, Cursor, Error}; use crate::errors::ConnectionError; use std::io::{Error as IOError, ErrorKind}; use std::path::Path; #[test] fn core_cursor() { let cb1 = |_: &Path| -> Result<(), _> { unimplemented!() }; let cb2 = |_: &Path| unimplemented!(); match find_cursor_impl("unused".as_ref(), "unused", "core", "heart", cb1, cb2).unwrap() { Cursor::CoreChar(31) => {} e => panic!("Unexpected result {:?}", e), } } #[test] fn nothing_found() { let mut opened = Vec::new(); let mut inherit_parsed = Vec::new(); let cb1 = |path: &Path| -> Result<(), _> { opened.push(path.to_str().unwrap().to_owned()); Err(IOError::new( ErrorKind::Other, ConnectionError::UnknownError, )) }; let cb2 = |path: &Path| { inherit_parsed.push(path.to_str().unwrap().to_owned()); Ok(Vec::new()) }; match find_cursor_impl( "home".as_ref(), "path:~/some/:/entries", "theme", "theCursor", cb1, cb2, ) { Err(Error::NothingFound) => {} e => panic!("Unexpected result {:?}", e), } assert_eq!( opened, &[ "path/theme/cursors/theCursor", "home/some/theme/cursors/theCursor", "/entries/theme/cursors/theCursor", ] ); assert_eq!( inherit_parsed, &[ "path/theme/index.theme", "home/some/theme/index.theme", "/entries/theme/index.theme", ] ); } #[test] fn inherit() { let mut opened = Vec::new(); let cb1 = |path: &Path| -> Result<(), _> { opened.push(path.to_str().unwrap().to_owned()); Err(IOError::new( ErrorKind::Other, ConnectionError::UnknownError, )) }; let cb2 = |path: &Path| { if path.starts_with("base/theTheme") { Ok(vec!["inherited".into()]) } else if path.starts_with("path/inherited") { Ok(vec!["theEnd".into()]) } else { Ok(vec![]) } }; match find_cursor_impl( "home".as_ref(), "path:base:tail", "theTheme", "theCursor", cb1, cb2, ) { Err(Error::NothingFound) => {} e => panic!("Unexpected result {:?}", e), } assert_eq!( opened, &[ "path/theTheme/cursors/theCursor", "base/theTheme/cursors/theCursor", "tail/theTheme/cursors/theCursor", "path/inherited/cursors/theCursor", "base/inherited/cursors/theCursor", "tail/inherited/cursors/theCursor", "path/theEnd/cursors/theCursor", "base/theEnd/cursors/theCursor", "tail/theEnd/cursors/theCursor", ] ); } } x11rb-0.8.1/src/cursor/mod.rs010064400017500001750000000262431402220031600140640ustar 00000000000000//! Utility functions for working with X11 cursors //! //! The code in this module is only available when the `cursor` feature of the library is enabled. use crate::connection::Connection; use crate::cookie::Cookie as X11Cookie; use crate::errors::{ConnectionError, ReplyOrIdError}; use crate::protocol::render::{self, Pictformat}; use crate::protocol::xproto::{self, Font, Window}; use crate::resource_manager::Database; use crate::NONE; use std::fs::File; mod find_cursor; mod parse_cursor; /// The level of cursor support of the X11 server #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum RenderSupport { /// Render extension not available None, /// Static cursor support (CreateCursor added in RENDER 0.5) StaticCursor, /// Animated cursor support (CreateAnimCursor added in RENDER 0.8) AnimatedCursor, } /// A cookie for creating a `Handle` #[derive(Debug)] pub struct Cookie<'a, 'b, C: Connection> { conn: &'a C, screen: &'a xproto::Screen, resource_database: &'b Database, render_info: Option<( X11Cookie<'a, C, render::QueryVersionReply>, X11Cookie<'a, C, render::QueryPictFormatsReply>, )>, } impl Cookie<'_, '_, C> { /// Get the handle from the replies from the X11 server pub fn reply(self) -> Result { let mut render_version = (0, 0); let mut picture_format = NONE; if let Some((version, formats)) = self.render_info { let version = version.reply()?; render_version = (version.major_version, version.minor_version); picture_format = find_format(&formats.reply()?); } Self::from_replies( self.conn, self.screen, self.resource_database, render_version, picture_format, ) } /// Get the handle from the replies from the X11 server pub fn reply_unchecked(self) -> Result, ReplyOrIdError> { let mut render_version = (0, 0); let mut picture_format = NONE; if let Some((version, formats)) = self.render_info { match (version.reply_unchecked()?, formats.reply_unchecked()?) { (Some(version), Some(formats)) => { render_version = (version.major_version, version.minor_version); picture_format = find_format(&formats); } _ => return Ok(None), } } Ok(Some(Self::from_replies( self.conn, self.screen, self.resource_database, render_version, picture_format, )?)) } fn from_replies( conn: &C, screen: &xproto::Screen, resource_database: &Database, render_version: (u32, u32), picture_format: Pictformat, ) -> Result { let render_support = if render_version.0 >= 1 || render_version.1 >= 8 { RenderSupport::AnimatedCursor } else if render_version.0 >= 1 || render_version.1 >= 5 { RenderSupport::StaticCursor } else { RenderSupport::None }; let theme = resource_database .get_string("Xcursor.theme", "") .map(|theme| theme.to_string()); let cursor_size = match resource_database.get_value("Xcursor.size", "") { Ok(Some(value)) => value, _ => 0, }; let xft_dpi = match resource_database.get_value("Xft.dpi", "") { Ok(Some(value)) => value, _ => 0, }; let cursor_size = get_cursor_size(cursor_size, xft_dpi, screen); let cursor_font = conn.generate_id()?; let _ = xproto::open_font(conn, cursor_font, b"cursor")?; Ok(Handle { root: screen.root, cursor_font, picture_format, render_support, theme, cursor_size, }) } } /// A handle necessary for loading cursors #[derive(Debug)] pub struct Handle { root: Window, cursor_font: Font, picture_format: Pictformat, render_support: RenderSupport, theme: Option, cursor_size: u32, } impl Handle { /// Create a new cursor handle for creating cursors on the given screen. /// /// The `resource_database` is used to look up settings like the current cursor theme and the /// cursor size to use. /// /// This function returns a cookie that can be used to later get the actual handle. /// /// If you want this function not to block, you should prefetch the RENDER extension's data on /// the connection. #[allow(clippy::new_ret_no_self)] pub fn new<'a, 'b, C: Connection>( conn: &'a C, screen: usize, resource_database: &'b Database, ) -> Result, ConnectionError> { let screen = &conn.setup().roots[screen]; let render_info = if conn .extension_information(render::X11_EXTENSION_NAME)? .is_some() { let render_version = render::query_version(conn, 0, 8)?; let render_pict_format = render::query_pict_formats(conn)?; Some((render_version, render_pict_format)) } else { None }; Ok(Cookie { conn, screen, resource_database, render_info, }) } /// Loads the specified cursor, either from the cursor theme or by falling back to the X11 /// "cursor" font. pub fn load_cursor(&self, conn: &C, name: &str) -> Result where C: Connection, { load_cursor(conn, self, name) } } fn open_cursor(theme: &Option, name: &str) -> Option> { if let Some(theme) = theme { if let Ok(cursor) = find_cursor::find_cursor(theme, name) { return Some(cursor); } } if let Ok(cursor) = find_cursor::find_cursor("default", name) { Some(cursor) } else { None } } fn create_core_cursor( conn: &C, cursor_font: Font, cursor: u16, ) -> Result { let result = conn.generate_id()?; let _ = xproto::create_glyph_cursor( conn, result, cursor_font, cursor_font, cursor, cursor + 1, // foreground color 0, 0, 0, // background color u16::max_value(), u16::max_value(), u16::max_value(), )?; Ok(result) } fn create_render_cursor( conn: &C, handle: &Handle, image: &parse_cursor::Image, storage: &mut Option<(xproto::Pixmap, xproto::Gcontext, u16, u16)>, ) -> Result { let (cursor, picture) = (conn.generate_id()?, conn.generate_id()?); // Get a pixmap of the right size and a gc for it let (pixmap, gc) = if storage.map(|(_, _, w, h)| (w, h)) == Some((image.width, image.height)) { storage.map(|(pixmap, gc, _, _)| (pixmap, gc)).unwrap() } else { let (pixmap, gc) = if let Some((pixmap, gc, _, _)) = storage { let _ = xproto::free_gc(conn, *gc)?; let _ = xproto::free_pixmap(conn, *pixmap)?; (*pixmap, *gc) } else { (conn.generate_id()?, conn.generate_id()?) }; let _ = xproto::create_pixmap(conn, 32, pixmap, handle.root, image.width, image.height)?; let _ = xproto::create_gc(conn, gc, pixmap, &Default::default())?; *storage = Some((pixmap, gc, image.width, image.height)); (pixmap, gc) }; // Sigh. We need the pixel data as a bunch of bytes. let pixels = crate::x11_utils::Serialize::serialize(&image.pixels[..]); let _ = xproto::put_image( conn, xproto::ImageFormat::Z_PIXMAP, pixmap, gc, image.width, image.height, 0, 0, 0, 32, &pixels, )?; let _ = render::create_picture( conn, picture, pixmap, handle.picture_format, &Default::default(), )?; let _ = render::create_cursor(conn, cursor, picture, image.x_hot, image.y_hot)?; let _ = render::free_picture(conn, picture)?; Ok(render::Animcursorelt { cursor, delay: image.delay, }) } fn load_cursor( conn: &C, handle: &Handle, name: &str, ) -> Result { // Find the right cursor, load it directly if it is a core cursor let cursor_file = match open_cursor(&handle.theme, name) { None => return Ok(NONE), Some(find_cursor::Cursor::CoreChar(c)) => { return create_core_cursor(conn, handle.cursor_font, c) } Some(find_cursor::Cursor::File(f)) => f, }; // We have to load a file and use RENDER to create a cursor if handle.render_support == RenderSupport::None { return Ok(NONE); } // Load the cursor from the file use std::io::BufReader; let images = parse_cursor::parse_cursor(&mut BufReader::new(cursor_file), handle.cursor_size) .or(Err(crate::errors::ParseError::InvalidValue))?; let mut images = &images[..]; // No animated cursor support? Only use the first image if handle.render_support == RenderSupport::StaticCursor { images = &images[0..1]; } // Now transfer the cursors to the X11 server let mut storage = None; let cursors = images .iter() .map(|image| create_render_cursor(conn, handle, image, &mut storage)) .collect::, _>>()?; if let Some((pixmap, gc, _, _)) = storage { let _ = xproto::free_gc(conn, gc)?; let _ = xproto::free_pixmap(conn, pixmap)?; } if cursors.len() == 1 { Ok(cursors[0].cursor) } else { let result = conn.generate_id()?; let _ = render::create_anim_cursor(conn, result, &cursors)?; for elem in cursors { let _ = xproto::free_cursor(conn, elem.cursor)?; } Ok(result) } } fn find_format(reply: &render::QueryPictFormatsReply) -> Pictformat { reply .formats .iter() .filter(|format| { format.type_ == render::PictType::DIRECT && format.depth == 32 && format.direct.red_shift == 16 && format.direct.red_mask == 0xff && format.direct.green_shift == 8 && format.direct.green_mask == 0xff && format.direct.blue_shift == 0 && format.direct.blue_mask == 0xff && format.direct.alpha_shift == 24 && format.direct.alpha_mask == 0xff }) .map(|format| format.id) .next() .expect("The X11 server is missing the RENDER ARGB_32 standard format!") } fn get_cursor_size(rm_cursor_size: u32, rm_xft_dpi: u32, screen: &xproto::Screen) -> u32 { if let Some(size) = std::env::var("XCURSOR_SIZE") .ok() .and_then(|s| s.parse().ok()) { return size; } if rm_cursor_size > 0 { return rm_cursor_size; } if rm_xft_dpi > 0 { return rm_xft_dpi * 16 / 72; } u32::from(screen.height_in_pixels.min(screen.width_in_pixels) / 48) } x11rb-0.8.1/src/cursor/parse_cursor.rs010064400017500001750000000423641402220031600160160ustar 00000000000000//! Parse the contents of a cursor file // This code is loosely based on parse_cursor_file.c from libxcb-cursor, which is: // Copyright © 2013 Michael Stapelberg // and is covered by MIT/X Consortium License use std::convert::TryInto; use std::io::{Read, Seek, SeekFrom}; const FILE_MAGIC: u32 = 0x7275_6358; const IMAGE_TYPE: u32 = 0xfffd_0002; const IMAGE_MAX_SIZE: u16 = 0x7fff; /// An error that occurred while parsing #[derive(Debug)] pub(crate) enum Error { /// An I/O error occurred IO(std::io::Error), /// The file did not begin with the expected magic InvalidMagic, /// The file contained unrealistically many images TooManyEntries, /// The file contains no images NoImages, /// Some image's entry is corrupt and not self-consistent CorruptImage, /// An entry is larger than the maximum size ImageTooLarge, } impl From for Error { fn from(value: std::io::Error) -> Self { Error::IO(value) } } /// Read a single `u32` from a cursor file /// /// The file stores these entries in little endian. fn read_u32(read: &mut R) -> Result { let mut buffer = [0; 4]; read.read_exact(&mut buffer)?; Ok(u32::from_le_bytes(buffer)) } /// A single cursor image #[derive(Debug)] pub(crate) struct Image { pub(crate) width: u16, pub(crate) height: u16, pub(crate) x_hot: u16, pub(crate) y_hot: u16, pub(crate) delay: u32, pub(crate) pixels: Vec, } impl Image { /// Read an `Image` from a reader fn read(read: &mut R, expected_kind: u32, expected_size: u32) -> Result { let (_header, kind, size, _version) = ( read_u32(read)?, read_u32(read)?, read_u32(read)?, read_u32(read)?, ); if (kind, size) != (expected_kind, expected_size) { return Err(Error::CorruptImage); } fn convert_size(size: u32) -> Result { size.try_into() .ok() .filter(|&size| size <= IMAGE_MAX_SIZE) .ok_or(Error::ImageTooLarge) } let (width, height) = ( convert_size(read_u32(read)?)?, convert_size(read_u32(read)?)?, ); let (x_hot, y_hot) = (read_u32(read)?, read_u32(read)?); let delay = read_u32(read)?; let x_hot = x_hot.try_into().or(Err(Error::ImageTooLarge))?; let y_hot = y_hot.try_into().or(Err(Error::ImageTooLarge))?; let num_pixels = u32::from(width) * u32::from(height); let pixels = (0..num_pixels) .map(|_| read_u32(read)) .collect::, _>>()?; Ok(Image { width, height, x_hot, y_hot, delay, pixels, }) } } /// A TOC entry in a cursor file #[derive(Debug)] struct TocEntry { kind: u32, size: u32, position: u32, } impl TocEntry { /// Read a `TocEntry` from a reader fn read(read: &mut R) -> Result { Ok(TocEntry { kind: read_u32(read)?, size: read_u32(read)?, position: read_u32(read)?, }) } } /// Find the size of the image in the toc with a size as close as possible to the desired size. fn find_best_size(toc: &[TocEntry], desired_size: u32) -> Result { fn distance(a: u32, b: u32) -> u32 { a.max(b) - a.min(b) } fn is_better(desired_size: u32, entry: &TocEntry, result: &Result) -> bool { match result { Err(_) => true, Ok(size) => distance(entry.size, desired_size) < distance(*size, desired_size), } } let mut result = Err(Error::NoImages); for entry in toc { // If this is better than the best so far, replace best if entry.kind == IMAGE_TYPE && is_better(desired_size, entry, &result) { result = Ok(entry.size) } } result } /// Parse a complete cursor file pub(crate) fn parse_cursor( input: &mut R, desired_size: u32, ) -> Result, Error> { let (magic, header, _version, ntoc) = ( read_u32(input)?, read_u32(input)?, read_u32(input)?, read_u32(input)?, ); if magic != FILE_MAGIC { return Err(Error::InvalidMagic); } if ntoc > 0x1_0000 { return Err(Error::TooManyEntries); } // Read the table of contents let _ = input.seek(SeekFrom::Start(header.into()))?; let toc = (0..ntoc) .map(|_| TocEntry::read(input)) .collect::, _>>()?; // Find the cursor size that we should load let size = find_best_size(&toc, desired_size)?; // Now load all cursors that have the right size let mut result = Vec::new(); for entry in toc { if entry.kind != IMAGE_TYPE || entry.size != size { continue; } let _ = input.seek(SeekFrom::Start(entry.position.into()))?; result.push(Image::read(input, entry.kind, entry.size)?); } Ok(result) } #[cfg(test)] mod test { use super::{find_best_size, parse_cursor, Error, Image, TocEntry, IMAGE_TYPE}; use std::io::{Cursor, ErrorKind}; #[test] fn read_3x5_image() { let data = [ 0x00, 0x00, 0x00, 0x00, // header(?) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x00, 0x00, 0x00, 0x00, // version(?) 0x03, 0x00, 0x00, 0x00, // width 3 0x05, 0x00, 0x00, 0x00, // height 5 0x07, 0x00, 0x00, 0x00, // x_hot 7 0x08, 0x00, 0x00, 0x00, // y_hot 8 0x2a, 0x00, 0x00, 0x00, // delay 42 // pixels 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, ]; let image = Image::read(&mut Cursor::new(&data[..]), IMAGE_TYPE, 4).unwrap(); assert_eq!(image.width, 3); assert_eq!(image.height, 5); assert_eq!(image.x_hot, 7); assert_eq!(image.y_hot, 8); assert_eq!(image.delay, 42); assert_eq!( image.pixels, &[ 0x0403_0201, 0x0807_0605, 0x0c0b_0a09, 0x100f_0e0d, 0x1413_1211, 0x1817_1615, 0x1c1b_1a19, 0x201f_1e1d, 0x2423_2221, 0x2827_2625, 0x2c2b_2a29, 0x302f_2e2d, 0x3433_3231, 0x3837_3635, 0x3c3b_3a39, ] ); } #[test] fn read_corrupt_image_wrong_kind() { let data = [ 0x00, 0x00, 0x00, 0x00, // header(?) 0x01, 0x00, 0xfd, 0xff, // IMAGE_TYPE - 1 0x04, 0x00, 0x00, 0x00, // size 4 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x00, 0x00, 0x00, // width 0 0x00, 0x00, 0x00, 0x00, // height 0 0x00, 0x00, 0x00, 0x00, // x_hot 0 0x00, 0x00, 0x00, 0x00, // y_hot 0 0x00, 0x00, 0x00, 0x00, // delay 0 ]; match Image::read(&mut Cursor::new(&data[..]), IMAGE_TYPE, 4) { Err(Error::CorruptImage) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn read_corrupt_image_wrong_size() { let data = [ 0x00, 0x00, 0x00, 0x00, // header(?) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x00, 0x00, 0x00, // width 0 0x00, 0x00, 0x00, 0x00, // height 0 0x00, 0x00, 0x00, 0x00, // x_hot 0 0x00, 0x00, 0x00, 0x00, // y_hot 0 0x00, 0x00, 0x00, 0x00, // delay 0 ]; match Image::read(&mut Cursor::new(&data[..]), IMAGE_TYPE, 42) { Err(Error::CorruptImage) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn read_image_too_large_width() { let data = [ 0x00, 0x00, 0x00, 0x00, // header(?) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x80, 0x00, 0x00, // width IMAGE_MAX_SIZE + 1 0x00, 0x00, 0x00, 0x00, // height 0 0x00, 0x00, 0x00, 0x00, // x_hot 0 0x00, 0x00, 0x00, 0x00, // y_hot 0 0x00, 0x00, 0x00, 0x00, // delay 0 ]; match Image::read(&mut Cursor::new(&data[..]), IMAGE_TYPE, 4) { Err(Error::ImageTooLarge) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn read_image_too_large_height() { let data = [ 0x00, 0x00, 0x00, 0x00, // header(?) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x00, 0x00, 0x00, // width 0 0x00, 0x80, 0x00, 0x00, // height IMAGE_MAX_SIZE + 1 0x00, 0x00, 0x00, 0x00, // x_hot 0 0x00, 0x00, 0x00, 0x00, // y_hot 0 0x00, 0x00, 0x00, 0x00, // delay 0 ]; match Image::read(&mut Cursor::new(&data[..]), IMAGE_TYPE, 4) { Err(Error::ImageTooLarge) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn read_image_too_short() { let data = []; match Image::read(&mut Cursor::new(&data[..]), IMAGE_TYPE, 4) { Err(Error::IO(ref e)) if e.kind() == ErrorKind::UnexpectedEof => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn find_best_size_empty_input() { let res = find_best_size(&[], 42); match res { Err(Error::NoImages) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn find_best_size_one_input() { let input = [TocEntry { kind: IMAGE_TYPE, size: 42, position: 42, }]; assert_eq!(42, find_best_size(&input, 10).unwrap()); } #[test] fn find_best_size_selects_better() { let input = [ TocEntry { kind: IMAGE_TYPE, size: 42, position: 42, }, TocEntry { kind: IMAGE_TYPE, size: 32, position: 42, }, TocEntry { kind: IMAGE_TYPE, size: 3, position: 42, }, TocEntry { kind: IMAGE_TYPE, size: 22, position: 42, }, TocEntry { kind: 0, size: 10, position: 42, }, ]; assert_eq!(3, find_best_size(&input, 10).unwrap()); } #[test] fn parse_cursor_too_short() { let data = []; match parse_cursor(&mut Cursor::new(&data[..]), 10) { Err(Error::IO(ref e)) if e.kind() == ErrorKind::UnexpectedEof => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn parse_cursor_incorrect_magic() { let data = [ 0x00, 0x00, 0x00, 0x00, // magic 0x00, 0x00, 0x00, 0x00, // header file offset 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x00, 0x00, 0x00, // num TOC entries ]; match parse_cursor(&mut Cursor::new(&data[..]), 10) { Err(Error::InvalidMagic) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn parse_cursor_too_many_entries() { let data = [ b'X', b'c', b'u', b'r', // magic 0x00, 0x00, 0x00, 0x00, // header file offset 0x00, 0x00, 0x00, 0x00, // version(?) 0x01, 0x00, 0x01, 0x00, // num TOC entries, limit + 1 ]; match parse_cursor(&mut Cursor::new(&data[..]), 10) { Err(Error::TooManyEntries) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn parse_cursor_empty_toc() { let data = [ b'X', b'c', b'u', b'r', // magic 0x10, 0x00, 0x00, 0x00, // header file offset (16) 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x00, 0x00, 0x00, // num TOC entries, 0 ]; match parse_cursor(&mut Cursor::new(&data[..]), 10) { Err(Error::NoImages) => {} r => panic!("Unexpected result {:?}", r), } } #[test] fn parse_cursor_one_image() { let data = [ b'X', b'c', b'u', b'r', // magic 0x10, 0x00, 0x00, 0x00, // header file offset (16) 0x00, 0x00, 0x00, 0x00, // version(?) 0x01, 0x00, 0x00, 0x00, // num TOC entries, 1 // TOC 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x1c, 0x00, 0x00, 0x00, // image offset (28) // image 0x00, 0x00, 0x00, 0x00, // header(?) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x00, 0x00, 0x00, // width 0 0x00, 0x00, 0x00, 0x00, // height 0 0x00, 0x00, 0x00, 0x00, // x_hot 0 0x00, 0x00, 0x00, 0x00, // y_hot 0 0x00, 0x00, 0x00, 0x00, // delay 0 ]; let expected = [Image { width: 0, height: 0, x_hot: 0, y_hot: 0, delay: 0, pixels: vec![], }]; let actual = parse_cursor(&mut Cursor::new(&data[..]), 10).unwrap(); assert_same_images(&expected, &actual); } #[test] fn parse_cursor_two_images_plus_one_ignored() { let data = [ b'X', b'c', b'u', b'r', // magic 0x10, 0x00, 0x00, 0x00, // header file offset (16) 0x00, 0x00, 0x00, 0x00, // version(?) 0x03, 0x00, 0x00, 0x00, // num TOC entries, 3 // TOC 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x34, 0x00, 0x00, 0x00, // image offset (52) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x03, 0x00, 0x00, 0x00, // size 3 0x34, 0x00, 0x00, 0x00, // image offset (52) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x34, 0x00, 0x00, 0x00, // image offset (52) // image 0x00, 0x00, 0x00, 0x00, // header(?) 0x02, 0x00, 0xfd, 0xff, // IMAGE_TYPE 0x04, 0x00, 0x00, 0x00, // size 4 0x00, 0x00, 0x00, 0x00, // version(?) 0x00, 0x00, 0x00, 0x00, // width 0 0x00, 0x00, 0x00, 0x00, // height 0 0x00, 0x00, 0x00, 0x00, // x_hot 0 0x00, 0x00, 0x00, 0x00, // y_hot 0 0x00, 0x00, 0x00, 0x00, // delay 0 ]; let expected = [ Image { width: 0, height: 0, x_hot: 0, y_hot: 0, delay: 0, pixels: vec![], }, Image { width: 0, height: 0, x_hot: 0, y_hot: 0, delay: 0, pixels: vec![], }, ]; let actual = parse_cursor(&mut Cursor::new(&data[..]), 10).unwrap(); assert_same_images(&expected, &actual); } fn assert_same_images(a: &[Image], b: &[Image]) { assert_eq!(a.len(), b.len(), "{:?} == {:?}", a, b); for (i, (im1, im2)) in a.iter().zip(b.iter()).enumerate() { assert_eq!( im1.width, im2.width, "Width image {}: {} == {}", i + 1, im1.width, im2.width ); assert_eq!( im1.height, im2.height, "Height image {}: {} == {}", i + 1, im1.height, im2.height ); assert_eq!( im1.x_hot, im2.x_hot, "X-hot image {}: {} == {}", i + 1, im1.x_hot, im2.x_hot ); assert_eq!( im1.y_hot, im2.y_hot, "Y-hot image {}: {} == {}", i + 1, im1.y_hot, im2.y_hot ); assert_eq!( im1.delay, im2.delay, "Delay image {}: {} == {}", i + 1, im1.delay, im2.delay ); assert_eq!( im1.pixels, im2.pixels, "Pixels image {}: {:?} == {:?}", i + 1, im1.pixels, im2.pixels ); } } } x11rb-0.8.1/src/errors.rs010064400017500001750000000267161402220031600133110ustar 00000000000000//! This module contains the current mess that is error handling. use crate::protocol::xproto::{SetupAuthenticate, SetupFailed}; use crate::x11_utils::X11Error; /// An error occurred while dynamically loading libxcb. #[cfg(feature = "dl-libxcb")] #[derive(Debug, Clone)] pub enum LibxcbLoadError { /// Could not open the library. The `OsString` is the library /// file name and the string is the reason. OpenLibError(std::ffi::OsString, String), /// Could not get a symbol from the library. The byte vector is the /// symbol name and the string is the reason. GetSymbolError(Vec, String), } #[cfg(feature = "dl-libxcb")] impl std::fmt::Display for LibxcbLoadError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { LibxcbLoadError::OpenLibError(lib_name, e) => { write!(f, "failed to open library {:?}: {}", lib_name, e) } LibxcbLoadError::GetSymbolError(symbol, e) => write!( f, "failed to get symbol \"{}\": {}", symbol .iter() .map(|&c| std::ascii::escape_default(c)) .flatten() .map(char::from) .collect::(), e, ), } } } #[cfg(feature = "dl-libxcb")] impl std::error::Error for LibxcbLoadError {} /// An error occurred while parsing some data #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum ParseError { /// Not enough data was provided. InsufficientData, /// A value did not fit. /// /// This error can e.g. happen when a value that was received from the X11 server does not fit /// into an `usize`. ConversionFailed, /// The value of an expression could not be computed. /// /// As an example, the length of the data in `xproto`'s `GetPropertyReply` is described by /// `value_len * (format / 8)`. The multiplication could cause an overflow, which would be /// represented by this error. InvalidExpression, /// A value was outside of its valid range. /// /// There are two kinds of situations where this error can happen: /// /// 1. The protocol was violated and a nonsensical value was found. /// 2. The user of the API called the wrong parsing function. /// /// Examples for the first kind of error: /// /// - One of a set of values should be present (a `` in xcb-proto-speak), but none of /// the `` matched. This can e.g. happen when parsing /// [`crate::protocol::xinput::InputInfo`]. /// - Parsing a request with a length field that is too small for the request header to fit. /// /// Examples for the second kind of error: /// /// - Parsing an X11 error with `response_type != 0`. /// - Parsing an X11 reply with `response_type != 1`. /// - Parsing an X11 request with the wrong value for its `minor_opcode`. InvalidValue, /// Some file descriptors were expected, but not enough were received. MissingFileDescriptors, } impl std::error::Error for ParseError {} impl std::fmt::Display for ParseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ParseError::InsufficientData => write!(f, "Insufficient data was provided"), ParseError::ConversionFailed => { write!(f, "A value conversion failed due to out of range data") } ParseError::InvalidExpression => write!( f, "An expression could not be computed, e.g. due to overflow" ), ParseError::InvalidValue => { write!(f, "A value could not be parsed into an enumeration") } ParseError::MissingFileDescriptors => write!(f, "Missing file descriptors"), } } } /// An error that occurred while connecting to an X11 server #[derive(Debug)] #[non_exhaustive] pub enum ConnectError { /// An unknown error occurred. /// /// One situation were this error is used when libxcb indicates an error that does not match /// any of the defined error conditions. Thus, libxcb is violating its own API (or new error /// cases were defined, but are not yet handled by x11rb). UnknownError, /// Error while parsing some data, see `ParseError`. ParseError(ParseError), /// Out of memory. /// /// This is `XCB_CONN_CLOSED_MEM_INSUFFICIENT`. InsufficientMemory, /// Error during parsing of display string. /// /// This is `XCB_CONN_CLOSED_PARSE_ERR`. DisplayParsingError, /// Server does not have a screen matching the display. /// /// This is `XCB_CONN_CLOSED_INVALID_SCREEN`. InvalidScreen, /// An I/O error occurred on the connection. IOError(std::io::Error), /// Invalid ID mask provided by the server. /// /// The value of `resource_id_mask` in the `Setup` provided by the server was zero. ZeroIDMask, /// The server rejected the connection with a `SetupAuthenticate` message. SetupAuthenticate(SetupAuthenticate), /// The server rejected the connection with a `SetupFailed` message. SetupFailed(SetupFailed), } impl std::error::Error for ConnectError {} impl std::fmt::Display for ConnectError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn display( f: &mut std::fmt::Formatter<'_>, prefix: &str, value: &[u8], ) -> std::fmt::Result { match std::str::from_utf8(value).ok() { Some(value) => write!(f, "{}: '{}'", prefix, value), None => write!(f, "{}: {:?} [message is not utf8]", prefix, value), } } match self { ConnectError::UnknownError => write!(f, "Unknown connection error"), ConnectError::InsufficientMemory => write!(f, "Insufficient memory"), ConnectError::DisplayParsingError => write!(f, "Display parsing error"), ConnectError::InvalidScreen => write!(f, "Invalid screen"), ConnectError::ParseError(err) => err.fmt(f), ConnectError::IOError(err) => err.fmt(f), ConnectError::ZeroIDMask => write!(f, "XID mask was zero"), ConnectError::SetupFailed(err) => display(f, "X11 setup failed", &err.reason), ConnectError::SetupAuthenticate(err) => { display(f, "X11 authentication failed", &err.reason) } } } } impl From for ConnectError { fn from(err: ParseError) -> Self { ConnectError::ParseError(err) } } impl From for ConnectError { fn from(err: std::io::Error) -> Self { ConnectError::IOError(err) } } /// An error that occurred on an already established X11 connection #[derive(Debug)] #[non_exhaustive] pub enum ConnectionError { /// An unknown error occurred. /// /// One situation were this error is used when libxcb indicates an error that does not match /// any of the defined error conditions. Thus, libxcb is violating its own API (or new error /// cases were defined, but are not yet handled by x11rb). UnknownError, /// An X11 extension was not supported by the server. /// /// This corresponds to `XCB_CONN_CLOSED_EXT_NOTSUPPORTED`. UnsupportedExtension, /// A request larger than the maximum request length was sent. /// /// This corresponds to `XCB_CONN_CLOSED_REQ_LEN_EXCEED`. MaximumRequestLengthExceeded, /// File descriptor passing failed. /// /// This corresponds to `XCB_CONN_CLOSED_FDPASSING_FAILED`. FDPassingFailed, /// Error while parsing some data, see `ParseError`. ParseError(ParseError), /// Out of memory. /// /// This is `XCB_CONN_CLOSED_MEM_INSUFFICIENT`. InsufficientMemory, /// An I/O error occurred on the connection. IOError(std::io::Error), } impl std::error::Error for ConnectionError {} impl std::fmt::Display for ConnectionError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ConnectionError::UnknownError => write!(f, "Unknown connection error"), ConnectionError::UnsupportedExtension => write!(f, "Unsupported extension"), ConnectionError::InsufficientMemory => write!(f, "Insufficient memory"), ConnectionError::MaximumRequestLengthExceeded => { write!(f, "Maximum request length exceeded") } ConnectionError::FDPassingFailed => write!(f, "FD passing failed"), ConnectionError::ParseError(err) => err.fmt(f), ConnectionError::IOError(err) => err.fmt(f), } } } impl From for ConnectionError { fn from(err: ParseError) -> Self { ConnectionError::ParseError(err) } } impl From for ConnectionError { fn from(err: std::io::Error) -> Self { ConnectionError::IOError(err) } } /// An error that occurred with some request. #[derive(Debug)] pub enum ReplyError { /// Some error occurred on the X11 connection. ConnectionError(ConnectionError), /// The X11 server sent an error in response to a request. X11Error(X11Error), } impl std::error::Error for ReplyError {} impl std::fmt::Display for ReplyError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ReplyError::ConnectionError(e) => write!(f, "{}", e), ReplyError::X11Error(e) => write!(f, "X11 error {:?}", e), } } } impl From for ReplyError { fn from(err: ParseError) -> Self { Self::from(ConnectionError::from(err)) } } impl From for ReplyError { fn from(err: std::io::Error) -> Self { ConnectionError::from(err).into() } } impl From for ReplyError { fn from(err: ConnectionError) -> Self { Self::ConnectionError(err) } } impl From for ReplyError { fn from(err: X11Error) -> Self { Self::X11Error(err) } } /// An error caused by some request or by the exhaustion of IDs. #[derive(Debug)] pub enum ReplyOrIdError { /// All available IDs have been exhausted. IdsExhausted, /// Some error occurred on the X11 connection. ConnectionError(ConnectionError), /// The X11 server sent an error in response to a request. X11Error(X11Error), } impl std::fmt::Display for ReplyOrIdError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ReplyOrIdError::IdsExhausted => f.write_str("X11 IDs have been exhausted"), ReplyOrIdError::ConnectionError(e) => write!(f, "{}", e), ReplyOrIdError::X11Error(e) => write!(f, "X11 error {:?}", e), } } } impl std::error::Error for ReplyOrIdError {} impl From for ReplyOrIdError { fn from(err: ParseError) -> Self { ConnectionError::from(err).into() } } impl From for ReplyOrIdError { fn from(err: ConnectionError) -> Self { ReplyOrIdError::ConnectionError(err) } } impl From for ReplyOrIdError { fn from(err: X11Error) -> Self { ReplyOrIdError::X11Error(err) } } impl From for ReplyOrIdError { fn from(err: ReplyError) -> Self { match err { ReplyError::ConnectionError(err) => ReplyOrIdError::ConnectionError(err), ReplyError::X11Error(err) => ReplyOrIdError::X11Error(err), } } } x11rb-0.8.1/src/event_loop_integration.rs010064400017500001750000000075611402220031600165470ustar 00000000000000//! # Integrating x11rb with an Event Loop //! //! To integrate x11rb with an event loop, //! [`std::os::unix::io::AsRawFd`](https://doc.rust-lang.org/std/os/unix/io/trait.AsRawFd.html) is //! implemented by [`RustConnection`](../rust_connection/struct.RustConnection.html)'s //! [`DefaultStream`](../rust_connection/struct.DefaultStream.html#impl-AsRawFd) and //! [`XCBConnection`](../xcb_ffi/struct.XCBConnection.html#impl-AsRawFd). This allows to integrate //! with an event loop that also handles timeouts or network I/O. See //! [`xclock_utc`](https://github.com/psychon/x11rb/blob/master/examples/xclock_utc.rs) for an //! example. //! //! The general form of such an integration could be as follows: //! ```no_run //! #[cfg(unix)] //! use std::os::unix::io::{AsRawFd, RawFd}; //! #[cfg(windows)] //! use std::os::windows::io::{AsRawSocket, RawSocket}; //! use x11rb::connection::Connection; //! use x11rb::rust_connection::RustConnection; //! use x11rb::errors::ConnectionError; //! //! fn main_loop(conn: &RustConnection) -> Result<(), ConnectionError> { //! #[cfg(unix)] //! let raw_handle = conn.stream().as_raw_fd(); //! #[cfg(windows)] //! let raw_handle = conn.stream().as_raw_socket(); //! loop { //! while let Some(event) = conn.poll_for_event()? { //! handle_event(event); //! } //! //! poll_for_readable(raw_handle); //! //! // Do other work here. //! } //! } //! # fn handle_event(event: T) {} //! # fn poll_for_readable(event: T) {} //! ``` //! The function `poll_for_readable` could wait for any number of I/O streams (besides the one from //! x11rb) to become readable. It can also implement timeouts, as seen in the //! [`xclock_utc` example](https://github.com/psychon/x11rb/blob/master/examples/xclock_utc.rs). //! //! //! ## Threads and Races //! //! Both [`RustConnection`](../rust_connection/struct.RustConnection.html) and //! [`XCBConnection`](../xcb_ffi/struct.XCBConnection.html) are `Sync+Send`. However, it is still //! possible to see races in the presence of threads and an event loop. //! //! The underlying problem is that the following two points are not equivalent: //! //! 1. A new event is available and can be returned from `conn.poll_for_event()`. //! 2. The underlying I/O stream is readable. //! //! The reason for this is an internal buffer that is required: When an event is received from the //! X11 server, but we are currently not in `conn.poll_for_event()`, then this event is added to an //! internal buffer. Thus, it can happen that there is an event available, but the stream is not //! readable. //! //! An example for such an other function is `conn.get_input_focus()?.reply()?`: The //! `GetInputFocus` request is sent to the server and then `reply()` waits for the reply. It does //! so by reading X11 packets from the X11 server until the right reply arrives. Any events that //! are read during this are buffered internally in the `Connection`. //! //! If this race occurs, the main loop would sit in `poll_for_readable` and wait, while the already //! buffered event is available. When something else wakes up the main loop and //! `conn.poll_for_event()` is called the next time, the event is finally processed. //! //! There are two ways around this: //! //! 1. Only interact with x11rb from one thread. //! 2. Use a dedicated thread for waiting for event. //! //! In case (1), one can call `conn.poll_for_event()` before waiting for the underlying I/O stream //! to be readable. Since there are no other threads, nothing can read a new event from the stream //! after `conn.poll_for_event()` returned `None`. //! //! Option (2) is to start a thread that calls `conn.wait_for_event()` in a loop. This is basically //! a dedicated event loop for fetching events from the X11 server. All other threads can now //! freely use the X11 connection without events possibly getting stuck and only being processed //! later. x11rb-0.8.1/src/extension_manager.rs010064400017500001750000000253721402220031600155000ustar 00000000000000//! Helper for implementing `RequestConnection::extension_information()`. use std::collections::{hash_map::Entry as HashMapEntry, HashMap}; use crate::connection::{RequestConnection, SequenceNumber}; use crate::cookie::Cookie; use crate::errors::{ConnectionError, ReplyError}; use crate::protocol::xproto::{ConnectionExt, QueryExtensionReply}; use crate::x11_utils::{ExtInfoProvider, ExtensionInformation}; /// Helper for implementing `RequestConnection::extension_information()`. /// /// This helps with implementing `RequestConnection`. Most likely, you do not need this in your own /// code, unless you really want to implement your own X11 connection. #[derive(Debug, Default)] pub struct ExtensionManager(HashMap<&'static str, CheckState>); #[derive(Debug)] enum CheckState { Prefetched(SequenceNumber), Present(ExtensionInformation), Missing, Error, } impl ExtensionManager { /// If the extension has not prefetched yet, sends a `QueryExtension` /// requests, adds a field to the hash map and returns a reference to it. fn prefetch_extension_information_aux( &mut self, conn: &C, extension_name: &'static str, ) -> Result<&mut CheckState, ConnectionError> { match self.0.entry(extension_name) { // Extension already checked, return the cached value HashMapEntry::Occupied(entry) => Ok(entry.into_mut()), HashMapEntry::Vacant(entry) => { let cookie = conn.query_extension(extension_name.as_bytes())?; Ok(entry.insert(CheckState::Prefetched(cookie.into_sequence_number()))) } } } /// Prefetchs an extension sending a `QueryExtension` without waiting for /// the reply. pub fn prefetch_extension_information( &mut self, conn: &C, extension_name: &'static str, ) -> Result<(), ConnectionError> { // We are not interested on the reference to the entry. let _ = self.prefetch_extension_information_aux(conn, extension_name)?; Ok(()) } /// An implementation of `RequestConnection::extension_information()`. /// /// The given connection is used for sending a `QueryExtension` request if needed. pub fn extension_information( &mut self, conn: &C, extension_name: &'static str, ) -> Result, ConnectionError> { let entry = self.prefetch_extension_information_aux(conn, extension_name)?; match entry { CheckState::Prefetched(sequence_number) => { match Cookie::::new(conn, *sequence_number).reply() { Err(err) => { *entry = CheckState::Error; match err { ReplyError::ConnectionError(e) => Err(e), // The X11 protocol specification does not specify any error // for the QueryExtension request, so this should not happen. ReplyError::X11Error(_) => Err(ConnectionError::UnknownError), } } Ok(info) => { if info.present { let info = ExtensionInformation { major_opcode: info.major_opcode, first_event: info.first_event, first_error: info.first_error, }; *entry = CheckState::Present(info); Ok(Some(info)) } else { *entry = CheckState::Missing; Ok(None) } } } } CheckState::Present(info) => Ok(Some(*info)), CheckState::Missing => Ok(None), CheckState::Error => Err(ConnectionError::UnknownError), } } } impl ExtInfoProvider for ExtensionManager { fn get_from_major_opcode(&self, major_opcode: u8) -> Option<(&str, ExtensionInformation)> { self.0 .iter() .filter_map(|(name, state)| { if let CheckState::Present(info) = state { Some((*name, *info)) } else { None } }) .find(|(_, info)| info.major_opcode == major_opcode) } fn get_from_event_code(&self, event_code: u8) -> Option<(&str, ExtensionInformation)> { self.0 .iter() .filter_map(|(name, state)| { if let CheckState::Present(info) = state { if info.first_event <= event_code { Some((*name, *info)) } else { None } } else { None } }) .max_by_key(|(_, info)| info.first_event) } fn get_from_error_code(&self, error_code: u8) -> Option<(&str, ExtensionInformation)> { self.0 .iter() .filter_map(|(name, state)| { if let CheckState::Present(info) = state { if info.first_error <= error_code { Some((*name, *info)) } else { None } } else { None } }) .max_by_key(|(_, info)| info.first_error) } } #[cfg(test)] mod test { use std::cell::RefCell; use std::io::IoSlice; use crate::connection::{ BufWithFds, DiscardMode, ReplyOrError, RequestConnection, RequestKind, SequenceNumber, }; use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use crate::utils::RawFdContainer; use crate::x11_utils::{ExtInfoProvider, ExtensionInformation, TryParse, TryParseFd}; use super::{CheckState, ExtensionManager}; struct FakeConnection(RefCell); impl RequestConnection for FakeConnection { type Buf = Vec; fn send_request_with_reply( &self, _bufs: &[IoSlice<'_>], _fds: Vec, ) -> Result, ConnectionError> where R: TryParse, { Ok(Cookie::new(self, 1)) } fn send_request_with_reply_with_fds( &self, _bufs: &[IoSlice<'_>], _fds: Vec, ) -> Result, ConnectionError> where R: TryParseFd, { unimplemented!() } fn send_request_without_reply( &self, _bufs: &[IoSlice<'_>], _fds: Vec, ) -> Result, ConnectionError> { unimplemented!() } fn discard_reply(&self, _sequence: SequenceNumber, _kind: RequestKind, _mode: DiscardMode) { unimplemented!() } fn prefetch_extension_information( &self, _extension_name: &'static str, ) -> Result<(), ConnectionError> { unimplemented!(); } fn extension_information( &self, _extension_name: &'static str, ) -> Result, ConnectionError> { unimplemented!() } fn wait_for_reply_or_raw_error( &self, sequence: SequenceNumber, ) -> Result>, ConnectionError> { // Code should only ask once for the reply to a request. Check that this is the case // (by requiring monotonically increasing sequence numbers here). let mut last = self.0.borrow_mut(); assert!( *last < sequence, "Last sequence number that was awaited was {}, but now {}", *last, sequence ); *last = sequence; // Then return an error, because that's what the #[test] below needs. Err(ConnectionError::UnknownError) } fn wait_for_reply( &self, _sequence: SequenceNumber, ) -> Result>, ConnectionError> { unimplemented!() } fn wait_for_reply_with_fds_raw( &self, _sequence: SequenceNumber, ) -> Result>, Vec>, ConnectionError> { unimplemented!() } fn check_for_raw_error( &self, _sequence: SequenceNumber, ) -> Result>, ConnectionError> { unimplemented!() } fn maximum_request_bytes(&self) -> usize { 0 } fn prefetch_maximum_request_bytes(&self) { unimplemented!() } fn parse_error(&self, _error: &[u8]) -> Result { unimplemented!() } fn parse_event(&self, _event: &[u8]) -> Result { unimplemented!() } } #[test] fn test_double_await() { let conn = FakeConnection(RefCell::new(0)); let mut ext_info = ExtensionManager::default(); // Ask for an extension info. FakeConnection will return an error. match ext_info.extension_information(&conn, "whatever") { Err(ConnectionError::UnknownError) => {} r => panic!("Unexpected result: {:?}", r), } // Ask again for the extension information. ExtensionInformation should not try to get the // reply again, because that would just hang. Once upon a time, this caused a hang. match ext_info.extension_information(&conn, "whatever") { Err(ConnectionError::UnknownError) => {} r => panic!("Unexpected result: {:?}", r), } } #[test] fn test_info_provider() { let info = ExtensionInformation { major_opcode: 4, first_event: 5, first_error: 6, }; let mut ext_info = ExtensionManager::default(); let _ = ext_info.0.insert("prefetched", CheckState::Prefetched(42)); let _ = ext_info.0.insert("present", CheckState::Present(info)); let _ = ext_info.0.insert("missing", CheckState::Missing); let _ = ext_info.0.insert("error", CheckState::Error); assert_eq!(ext_info.get_from_major_opcode(4), Some(("present", info))); assert_eq!(ext_info.get_from_event_code(5), Some(("present", info))); assert_eq!(ext_info.get_from_error_code(6), Some(("present", info))); } } x11rb-0.8.1/src/image.rs010064400017500001750000001221201402220031600130410ustar 00000000000000//! Utility code for working with images. //! //! This module contains the [`Image`] struct which represents an arbitrary image in //! `ImageFormat::ZPixmap`. If you do not know what `ZPixmap` means, then rest assured that you do //! not want to know the details. It suffices to know that the values of the individual pixels are //! saved one after another in memory. //! //! An [`Image`] can be converted to a different internal representation. [`Image::native`] //! converts it to the native format of the X11 server. These conversions do not change the actual //! content of the image, but only the way that it is laid out in memory (e.g. byte order and //! padding). Specifically, there is no support for converting an image to another `depth`. //! //! The code in this module is only available when the `image` feature of the library is //! enabled. // For future readers: // // - Z-Pixmap means that the pixels are right next to each other. I.e. first you have the value of // the pixel at (0, 0), then (1, 0), .... At the end of the row, there might be some padding // before the next row begins. // - XY-Bitmap consists of individual bits. The bits are assigned colors via a GC's foreground and // background color when uploading to the X11 server. // - XY-Pixmap consists of bit planes. This means you first get the first bit of each pixel, // stuffed together into bytes. After all of the first pixels are represented, the second plane // begins with the second bit of each pixel etc. use std::borrow::Cow; use std::convert::{TryFrom, TryInto}; use crate::connection::Connection; use crate::cookie::VoidCookie; use crate::errors::{ConnectionError, ParseError, ReplyError}; use crate::protocol::xproto::{ Drawable, Format, Gcontext, GetImageReply, GetImageRequest, ImageFormat, ImageOrder as XprotoImageOrder, PutImageRequest, Setup, VisualClass, Visualtype, }; /// The description of a single color component. /// /// For example, in an RGB image, pixels are often saved as `0xRRGGBB`, where each letter /// represents the respective color component. In the example, green has a `width` of 8 (it takes /// up 8 bits) and a `shift` of `16` (there are 16 less significant bits beyond it). This info is /// represented as a `ColorComponent`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ColorComponent { /// Number of bits for the component width: u8, /// Offset in an u32 of the component shift: u8, } impl ColorComponent { /// Create a new color component with the given information. /// /// The following conditions must be satisfied: /// - `width <= 16`: color components have at most 16 bits. /// - `shift < 32`: pixel values have at most 32 bits. /// - `shift + width <= 32`: pixel values have at most 32 bits. pub fn new(width: u8, shift: u8) -> Result { if width > 16 || shift >= 32 || shift + width > 32 { Err(ParseError::InvalidValue) } else { Ok(Self { width, shift }) } } /// Get the bit width of the color component. pub fn width(self) -> u8 { self.width } /// Get the bit shift of the color component. pub fn shift(self) -> u8 { self.shift } /// Get the pixel mask representing this color component. /// /// The mask can be used to mask off other colors in a pixel value. Only the bits that /// correspond to this color component are set. /// ``` /// # use x11rb::image::ColorComponent; /// let red = ColorComponent::new(8, 16)?; /// assert_eq!(red.mask(), 0xff0000); /// # Ok::<(), x11rb::errors::ParseError>(()) /// ``` pub fn mask(self) -> u32 { // Get a mask with 'width' set bits. let mask = (1u32 << self.width) - 1; // Shift the mask into the right position mask << self.shift } /// Create a new color component from a color mask. /// /// This turns a color mask into its individual components. /// ``` /// # use x11rb::image::ColorComponent; /// let red1 = ColorComponent::new(8, 16); /// let red2 = ColorComponent::from_mask(0xff0000); /// ``` /// /// # Errors /// /// This function fails if the given value is not a well-formed mask. This means that at least /// one bit must be set and the set bits must be consecutive. pub fn from_mask(mask: u32) -> Result { let width = mask.count_ones(); let shift = mask.trailing_zeros(); // Both width and shift can be at most 32, which should fit into u8. let result = Self::new(width.try_into().unwrap(), shift.try_into().unwrap())?; if mask != result.mask() { Err(ParseError::InvalidValue) } else { Ok(result) } } /// Get this color component out of a pixel value. /// /// This function gets a single pixel value and returns this color component's value in that /// pixel value, expanded to width 16. /// ``` /// # use x11rb::image::ColorComponent; /// let red = ColorComponent::new(8, 16)?; /// assert_eq!(0xABAB, red.decode(0x78AB_4321)); /// # Ok::<(), x11rb::errors::ParseError>(()) /// ``` pub fn decode(self, pixel: u32) -> u16 { // Get the color component out let value = (pixel & self.mask()) >> self.shift; // Now expand from with `self.width` to width 16. let mut width = self.width; let mut value = value << (16 - width); // Add some low bits by using the high bits while width < 16 { value |= value >> width; width <<= 1; } value.try_into().unwrap() } /// Encode a color value according to this pixel format. /// /// ``` /// # use x11rb::image::ColorComponent; /// let red = ColorComponent::new(8, 16)?; /// assert_eq!(0xAB0000, red.encode(0xABCD)); /// # Ok::<(), x11rb::errors::ParseError>(()) /// ``` pub fn encode(self, intensity: u16) -> u32 { // First truncate to width `self.width`, then place at the correct offset. (u32::from(intensity) >> (16 - self.width)) << self.shift } } /// A collection of color components describing the red, green, and blue components of a pixel. /// /// A [`ColorComponent`] describes a single color component in an image. This structure describes /// the `red`, `green`, and `blue` color components by containing a [`ColorComponent`] for each of /// them. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PixelLayout { red: ColorComponent, green: ColorComponent, blue: ColorComponent, } impl PixelLayout { /// Create a new pixel layout from the description of each component pub fn new(red: ColorComponent, green: ColorComponent, blue: ColorComponent) -> Self { Self { red, green, blue } } /// Create a new pixel layout /// /// This function errors if the visual has a different class than `TrueColor` or `DirectColor`, /// because color pallets and grayscales are not supported. This function also errors if the /// mask components of the visual are malformed. pub fn from_visual_type(visual: Visualtype) -> Result { if visual.class != VisualClass::TRUE_COLOR && visual.class != VisualClass::DIRECT_COLOR { Err(ParseError::InvalidValue) } else { Ok(Self::new( ColorComponent::from_mask(visual.red_mask)?, ColorComponent::from_mask(visual.green_mask)?, ColorComponent::from_mask(visual.blue_mask)?, )) } } /// Get the depth of this pixel layout. /// /// The depth is the number of significant bits of each pixel value. pub fn depth(self) -> u8 { // TODO: I am not quite sure this implementation is correct. The protocol seems to allow // unused bits in the middle..? self.red.width + self.green.width + self.blue.width } /// Decode a pixel value into its red, green, and blue components. /// /// This function returns each component expanded to width 16. /// ``` /// # use x11rb::image::{ColorComponent, PixelLayout}; /// let layout = PixelLayout::new( /// ColorComponent::new(8, 16)?, /// ColorComponent::new(8, 8)?, /// ColorComponent::new(8, 0)?, /// ); /// assert_eq!((0xABAB, 0x4343, 0x2121), layout.decode(0x78AB_4321)); /// # Ok::<(), x11rb::errors::ParseError>(()) /// ``` pub fn decode(self, pixel: u32) -> (u16, u16, u16) { let red = self.red.decode(pixel); let green = self.green.decode(pixel); let blue = self.blue.decode(pixel); (red, green, blue) } /// Encode a color value according to this layout. /// /// ``` /// # use x11rb::image::{ColorComponent, PixelLayout}; /// let layout = PixelLayout::new( /// ColorComponent::new(8, 16)?, /// ColorComponent::new(8, 8)?, /// ColorComponent::new(8, 0)?, /// ); /// assert_eq!(0x00AB_4321, layout.encode((0xABAB, 0x4343, 0x2121))); /// # Ok::<(), x11rb::errors::ParseError>(()) /// ``` pub fn encode(self, (red, green, blue): (u16, u16, u16)) -> u32 { let red = self.red.encode(red); let green = self.green.encode(green); let blue = self.blue.encode(blue); red | green | blue } } // Compute the stride based on some information of the image fn compute_stride(width: u16, bits_per_pixel: BitsPerPixel, scanline_pad: ScanlinePad) -> usize { let value = usize::from(width) * usize::from(bits_per_pixel); scanline_pad.round_to_multiple(value) / 8 } #[cfg(test)] mod test_stride { use super::compute_stride; use std::convert::TryInto; #[test] fn test_stride() { for &(width, bpp, pad, stride) in &[ // bpp=pad=8 (0, 8, 8, 0), (1, 8, 8, 1), (2, 8, 8, 2), (3, 8, 8, 3), (41, 8, 8, 41), // bpp=8, pad=16 (0, 8, 16, 0), (1, 8, 16, 2), (2, 8, 16, 2), (3, 8, 16, 4), (41, 8, 16, 42), // bpp=16, pad=16 (0, 16, 16, 0), (1, 16, 16, 2), (2, 16, 16, 4), (3, 16, 16, 6), (41, 16, 16, 82), // bpp=16, pad=32 (0, 16, 32, 0), (1, 16, 32, 4), (2, 16, 32, 4), (3, 16, 32, 8), (41, 16, 32, 84), // bpp=32, pad=32 (0, 32, 32, 0), (1, 32, 32, 4), (2, 32, 32, 8), (3, 32, 32, 12), (41, 32, 32, 164), ] { let actual = compute_stride(width, bpp.try_into().unwrap(), pad.try_into().unwrap()); assert_eq!(stride, actual, "width={}, bpp={}, pad={}", width, bpp, pad); } } } // Find the format with the given depth in `setup.pixmap_formats`. fn find_format(setup: &Setup, depth: u8) -> Result<&Format, ParseError> { setup .pixmap_formats .iter() .find(|f| f.depth == depth) .ok_or(ParseError::InvalidValue) } macro_rules! number_enum { { $(#[$meta:meta])* $vis:vis enum $enum_name:ident { $( $(#[$variant_meta:meta])* $variant_name:ident = $value:literal, )* } } => { $(#[$meta])* #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] $vis enum $enum_name { $( $(#[$variant_meta])* $variant_name = $value, )* } impl TryFrom for $enum_name { type Error = ParseError; fn try_from(value: u8) -> Result { match value { $($value => Ok(Self::$variant_name),)* _ => Err(ParseError::InvalidValue), } } } impl From<$enum_name> for u8 { fn from(value: $enum_name) -> u8 { match value { $($enum_name::$variant_name => $value,)* } } } impl From<$enum_name> for usize { fn from(value: $enum_name) -> usize { u8::from(value).into() } } } } number_enum! { /// The padding of scanlines. /// /// Each line of an image is padded to a multiple of some value. This value is the scanline /// padding, which this enum represents. #[non_exhaustive] pub enum ScanlinePad { /// Padding to multiples of 8 bits, i.e. no padding. Pad8 = 8, /// Padding to multiples of 16 bits, i.e. the next even number of bytes. Pad16 = 16, /// Padding to multiples of 32 bits, i.e. the next multiple of 4. Pad32 = 32, } } impl ScanlinePad { fn round_to_multiple(self, value: usize) -> usize { let value = value + usize::from(self) - 1; value - value % usize::from(self) } } #[cfg(test)] mod test_scanline_pad { use super::ScanlinePad; use std::convert::TryInto; #[test] fn number_conversions() { assert_eq!(8_u8, ScanlinePad::Pad8.into()); assert_eq!(16_u8, ScanlinePad::Pad16.into()); assert_eq!(32_u8, ScanlinePad::Pad32.into()); assert_eq!(8.try_into(), Ok(ScanlinePad::Pad8)); assert_eq!(16.try_into(), Ok(ScanlinePad::Pad16)); assert_eq!(32.try_into(), Ok(ScanlinePad::Pad32)); } #[test] fn test_round_to_multiple() { for &(value, pad8, pad16, pad32) in [ (0, 0, 0, 0), (1, 8, 16, 32), (2, 8, 16, 32), (3, 8, 16, 32), (4, 8, 16, 32), (5, 8, 16, 32), (6, 8, 16, 32), (7, 8, 16, 32), (8, 8, 16, 32), (9, 16, 16, 32), (10, 16, 16, 32), (11, 16, 16, 32), (12, 16, 16, 32), (13, 16, 16, 32), (14, 16, 16, 32), (15, 16, 16, 32), (16, 16, 16, 32), (17, 24, 32, 32), (33, 40, 48, 64), (47, 48, 48, 64), (48, 48, 48, 64), (49, 56, 64, 64), ] .iter() { assert_eq!( pad8, ScanlinePad::Pad8.round_to_multiple(value), "value={} for pad8", value, ); assert_eq!( pad16, ScanlinePad::Pad16.round_to_multiple(value), "value={} for pad16", value, ); assert_eq!( pad32, ScanlinePad::Pad32.round_to_multiple(value), "value={} for pad32", value, ); } } } number_enum! { /// The number of bits required to store one pixel. /// /// This value is only about the size of one pixel in memory. Other names for it include /// `bits_per_pixel` or `bpp`. It may be larger than the number of meaningful bits for a pixel /// value, which is its `depth`. #[non_exhaustive] pub enum BitsPerPixel { /// Each pixel takes one bit of memory. B1 = 1, /// Each pixel takes four bits of memory. B4 = 4, /// Each pixel takes one byte of memory. B8 = 8, /// Each pixel takes two bytes of memory. B16 = 16, /// Each pixel takes three bytes of memory. /// /// This is most likely not what you want to use, even if you have RGB data with 8 bits per /// channel. This corresponds to `depth=24`, but is almost always stored as four bytes /// per pixel, which is `BitsPerPixel::B32`. B24 = 24, /// Each pixel takes four bytes of memory. B32 = 32, } } /// Order in which bytes are stored in memory. /// /// If the numberof bits per pixel is less than 8, then this is the /// order in which bits are packed into bytes. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum ImageOrder { /// Least significant byte first LSBFirst, /// Most significant byte first MSBFirst, } impl TryFrom for ImageOrder { type Error = ParseError; fn try_from(value: XprotoImageOrder) -> Result { match value { XprotoImageOrder::LSB_FIRST => Ok(Self::LSBFirst), XprotoImageOrder::MSB_FIRST => Ok(Self::MSBFirst), _ => Err(ParseError::InvalidValue), } } } /// The description of an image. #[derive(Debug, PartialEq, Eq)] pub struct Image<'a> { /// Width in pixels. width: u16, /// Height in pixels. height: u16, /// Right padding on each scanline. scanline_pad: ScanlinePad, /// Color depth in bits. depth: u8, /// Storage per pixel in bits. Must be >= depth. bits_per_pixel: BitsPerPixel, /// Byte order of components. /// /// This is the nibble order when bits_per_pixel is 4. byte_order: ImageOrder, /// The image data. data: Cow<'a, [u8]>, } impl<'a> ToOwned for Image<'a> { // TODO: Can this somehow be turned into Image<'static>? type Owned = Self; fn to_owned(&self) -> Self::Owned { Image { width: self.width, height: self.height, scanline_pad: self.scanline_pad, depth: self.depth, bits_per_pixel: self.bits_per_pixel, byte_order: self.byte_order, data: self.data.to_owned(), } } } impl<'a> Image<'a> { /// The width in pixels. pub fn width(&self) -> u16 { self.width } /// The height in pixels. pub fn height(&self) -> u16 { self.height } /// The padding on the right side of each scanline. /// /// Each scanline is rounded up to some multiple of the `scanline_pad`. pub fn scanline_pad(&self) -> ScanlinePad { self.scanline_pad } /// Color depth in bits. pub fn depth(&self) -> u8 { self.depth } /// Number of bits required to store one pixel. /// /// This is always `>= depth`. pub fn bits_per_pixel(&self) -> BitsPerPixel { self.bits_per_pixel } /// Order in which bytes are stored in memory. /// /// If `bits_per_pixel()` is smaller than 8, then this is the order in which bits are packed /// into bytes. pub fn byte_order(&self) -> ImageOrder { self.byte_order } /// Raw pixel data. pub fn data(&self) -> &[u8] { &self.data } /// Mutable access to the raw pixel data. /// /// If the `Image` was constructed with `Cow::Borrowed`-access to its pixel data, then a copy /// is made when this method is called. pub fn data_mut(&mut self) -> &mut [u8] { self.data.to_mut() } /// Construct a new image from existing data. /// /// This constructs a new `Image` from given `data` without copying this data around. The other /// parameters describe the format that the image data is in. /// /// See [`Image::allocate`] for a variant that allocates memory for you and /// [`Image::allocate_native`] for allocating an image that is in an X11 server's native /// format. /// /// # Errors /// /// The only possible error is that `data.len()` is too short for an image as described by the /// other parameters. pub fn new( width: u16, height: u16, scanline_pad: ScanlinePad, depth: u8, bits_per_pixel: BitsPerPixel, byte_order: ImageOrder, data: Cow<'a, [u8]>, ) -> Result { let stride = compute_stride(width, bits_per_pixel, scanline_pad); let expected_size = usize::from(height) * stride; if data.len() < expected_size { Err(ParseError::InsufficientData) } else { Ok(Self { width, height, scanline_pad, depth, bits_per_pixel, byte_order, data, }) } } /// Construct a new, empty image. /// /// This function allocates memory for a new image in the format that is described by the /// parameters. /// /// See [`Image::new`] for a variant that wraps an existing in-memory image in an `Image` and /// [`Image::allocate_native`] for allocating an image that is in an X11 server's native /// format. pub fn allocate( width: u16, height: u16, scanline_pad: ScanlinePad, depth: u8, bits_per_pixel: BitsPerPixel, byte_order: ImageOrder, ) -> Self { let stride = compute_stride(width, bits_per_pixel, scanline_pad); let data = Cow::Owned(vec![0; usize::from(height) * stride]); Self { width, height, scanline_pad, depth, bits_per_pixel, byte_order, data, } } /// Construct a new, empty image. /// /// This function allocates memory for a new image in the format that the X11 server expects. /// The image will have size `width`x`height` and a depth of `depth`. /// /// See [`Image::new`] for a variant that wraps an existing in-memory image in an `Image` and /// [`Image::allocate`] for allocating an image that is in a more general format, not /// necessarily what the X11 server wants. pub fn allocate_native( width: u16, height: u16, depth: u8, setup: &Setup, ) -> Result { let format = find_format(setup, depth)?; Ok(Self::allocate( width, height, format.scanline_pad.try_into()?, depth, format.bits_per_pixel.try_into()?, setup.image_byte_order.try_into()?, )) } /// The stride is the number of bytes that each row of pixel data occupies in memory. fn stride(&self) -> usize { compute_stride(self.width, self.bits_per_pixel, self.scanline_pad) } /// Get an image from the X11 server. /// /// This function sends a [`GetImage`](crate::protocol::xproto::GetImageRequest) request, waits /// for its response and wraps it in a new `Image`. /// /// The returned image contains the rectangle with top left corner `(x, y)` and size `(width, /// height)` of the given `drawable`. pub fn get( conn: &impl Connection, drawable: Drawable, x: i16, y: i16, width: u16, height: u16, ) -> Result { let reply = GetImageRequest { drawable, x, y, width, height, format: ImageFormat::Z_PIXMAP, plane_mask: !0, } .send(conn)? .reply()?; Ok(Self::get_from_reply(&conn.setup(), width, height, reply)?) } /// Construct an `Image` from a `GetImageReply`. /// /// This function takes a `GetImageReply` and wraps it in an `Image`. The given `width` and /// `height` describe the corresponding values of the `GetImage` request that was used to get /// the `GetImageReply`. pub fn get_from_reply( setup: &Setup, width: u16, height: u16, reply: GetImageReply, ) -> Result { let format = find_format(setup, reply.depth)?; Self::new( width, height, format.scanline_pad.try_into()?, reply.depth, format.bits_per_pixel.try_into()?, ImageOrder::MSBFirst, Cow::Owned(reply.data), ) } /// Put an image to the X11 server. /// /// This function sends a [`PutImage`](crate::protocol::xproto::PutImageRequest) request. This /// will upload this image to the given `drawable` to position `(dst_x, dst_y)`. /// /// The server's maximum request size is honored. This means that a too large `PutImage` /// request is automatically split up into smaller pieces. Thus, if this function returns an /// error, the image could already be partially sent. pub fn put<'c, Conn: Connection>( &self, conn: &'c Conn, drawable: Drawable, gc: Gcontext, dst_x: i16, dst_y: i16, ) -> Result>, ConnectionError> { // Upload the image without exceeding the server's maximum request size let max_bytes = conn.maximum_request_bytes(); let put_image_header = 24; let stride = self.stride(); let lines_per_request = (max_bytes - put_image_header) / stride; let mut result = Vec::with_capacity( (usize::from(self.height()) + lines_per_request - 1) / lines_per_request, ); let lines_per_request = lines_per_request.try_into().unwrap_or(u16::max_value()); assert!(lines_per_request > 0); let (mut y_offset, mut byte_offset) = (0, 0); while y_offset < self.height { let next_lines = lines_per_request.min(self.height - y_offset); let next_byte_offset = byte_offset + usize::from(next_lines) * stride; let data = &self.data[byte_offset..next_byte_offset]; let request = PutImageRequest { format: ImageFormat::Z_PIXMAP, drawable, gc, width: self.width, height: next_lines, dst_x, dst_y: dst_y + i16::try_from(y_offset).unwrap(), left_pad: 0, // Must always be 0 for ZPixmap depth: self.depth, data: Cow::Borrowed(&data), }; result.push(request.send(conn)?); y_offset += next_lines; byte_offset = next_byte_offset; } Ok(result) } /// Convert this image into the format specified by the other parameters. /// /// This function may need to copy the image, hence returns a `Cow`. pub fn convert( &self, scanline_pad: ScanlinePad, bits_per_pixel: BitsPerPixel, byte_order: ImageOrder, ) -> Cow<'_, Self> { let already_converted = scanline_pad == self.scanline_pad && bits_per_pixel == self.bits_per_pixel && byte_order == self.byte_order; if already_converted { Cow::Borrowed(self) } else { let mut copy = Image::allocate( self.width, self.height, scanline_pad, self.depth, bits_per_pixel, byte_order, ); // This is the slowest possible way to do this. But also the easiest one to implement. for y in 0..self.height { for x in 0..self.width { copy.put_pixel(x, y, self.get_pixel(x, y)) } } Cow::Owned(copy) } } /// Convert this image into the native format of the X11 server. /// /// This function may need to copy the image, hence returns a `Cow`. pub fn native(&self, setup: &Setup) -> Result, ParseError> { let format = find_format(setup, self.depth)?; Ok(self.convert( format.scanline_pad.try_into()?, format.bits_per_pixel.try_into()?, setup.image_byte_order.try_into()?, )) } /// Reencode this image to a different pixel layout / depth. /// /// Each pixel of this image is interpreted according to `own` and written to the resulting /// image in the format described by `output`. /// /// The resulting image is always in the native format as described by `setup`. pub fn reencode<'b>( &'b self, own: PixelLayout, output: PixelLayout, setup: &Setup, ) -> Result, ParseError> { if own == output { self.native(setup) } else { // Yay, we get to convert the image :-( let (width, height) = (self.width(), self.height()); let mut result = Image::allocate_native(width, height, output.depth(), setup)?; for y in 0..height { for x in 0..width { let pixel = self.get_pixel(x, y); let pixel = output.encode(own.decode(pixel)); result.put_pixel(x, y, pixel); } } Ok(Cow::Owned(result)) } } /// Set a single pixel in this image. /// /// The pixel at position `(x, y)` will be set to the value `pixel`. `pixel` is truncated to /// this image's [`Self::bits_per_pixel`]. /// /// If the image was constructed from a `Cow::Borrowed` access to its pixel data, this causes /// the whole pixel data to be copied. See [`Image::new`] and [`Image::data_mut`]. pub fn put_pixel(&mut self, x: u16, y: u16, pixel: u32) { assert!(x < self.width); assert!(y < self.height); let row_start = usize::from(y) * self.stride(); let x = usize::from(x); let data = self.data.to_mut(); match self.bits_per_pixel { BitsPerPixel::B1 => { let (byte, bit) = compute_depth_1_address(x, self.byte_order); let pixel = ((pixel & 0x01) << bit) as u8; let old = data[row_start + byte]; let bit_cleared = old & !(1 << bit); data[row_start + byte] = bit_cleared | pixel; } BitsPerPixel::B4 => { let mut pixel = pixel & 0x0f; let odd_x = x % 2 == 1; let mask = if odd_x == (self.byte_order == ImageOrder::MSBFirst) { pixel <<= 4; 0xf0 } else { 0x0f }; data[row_start + x / 2] = (data[row_start + x / 2] & !mask) | (pixel as u8); } BitsPerPixel::B8 => data[row_start + x] = pixel as u8, BitsPerPixel::B16 => { let (p0, p1) = match self.byte_order { ImageOrder::LSBFirst => (pixel, pixel >> 8), ImageOrder::MSBFirst => (pixel >> 8, pixel), }; data[row_start + 2 * x + 1] = p1 as u8; data[row_start + 2 * x] = p0 as u8; } BitsPerPixel::B24 => { let (p0, p1, p2) = match self.byte_order { ImageOrder::LSBFirst => (pixel, pixel >> 8, pixel >> 16), ImageOrder::MSBFirst => (pixel >> 16, pixel >> 8, pixel), }; data[row_start + 3 * x + 2] = p2 as u8; data[row_start + 3 * x + 1] = p1 as u8; data[row_start + 3 * x] = p0 as u8; } BitsPerPixel::B32 => { let (p0, p1, p2, p3) = match self.byte_order { ImageOrder::LSBFirst => (pixel, pixel >> 8, pixel >> 16, pixel >> 24), ImageOrder::MSBFirst => (pixel >> 24, pixel >> 16, pixel >> 8, pixel), }; data[row_start + 4 * x + 3] = p3 as u8; data[row_start + 4 * x + 2] = p2 as u8; data[row_start + 4 * x + 1] = p1 as u8; data[row_start + 4 * x] = p0 as u8; } } } /// Get the value of a single pixel. /// /// This function gets the value of the pixel at `(x, y)`. pub fn get_pixel(&self, x: u16, y: u16) -> u32 { assert!(x < self.width); assert!(y < self.height); let row_start = usize::from(y) * self.stride(); let x = usize::from(x); // TODO Can this code (and the one in put_pixel) be simplified? E.g. handle B4 as a special // case and copy bits_per_pixel.into() / 8 bytes in other cases? match self.bits_per_pixel { BitsPerPixel::B1 => { let (byte, bit) = compute_depth_1_address(x, self.byte_order); ((self.data[row_start + byte] >> bit) & 1).into() } BitsPerPixel::B4 => { let byte = u32::from(self.data[row_start + x / 2]); let odd_x = x % 2 == 1; if odd_x == (self.byte_order == ImageOrder::MSBFirst) { byte >> 4 } else { byte & 0x0f } } BitsPerPixel::B8 => self.data[row_start + x].into(), BitsPerPixel::B16 => { let p1 = u32::from(self.data[row_start + 2 * x + 1]); let p0 = u32::from(self.data[row_start + 2 * x]); match self.byte_order { ImageOrder::LSBFirst => p0 | (p1 << 8), ImageOrder::MSBFirst => p1 | (p0 << 8), } } BitsPerPixel::B24 => { let p2 = u32::from(self.data[row_start + 3 * x + 2]); let p1 = u32::from(self.data[row_start + 3 * x + 1]); let p0 = u32::from(self.data[row_start + 3 * x]); match self.byte_order { ImageOrder::LSBFirst => p0 | (p1 << 8) | (p2 << 16), ImageOrder::MSBFirst => p2 | (p1 << 8) | (p0 << 16), } } BitsPerPixel::B32 => { let p3 = u32::from(self.data[row_start + 4 * x + 3]); let p2 = u32::from(self.data[row_start + 4 * x + 2]); let p1 = u32::from(self.data[row_start + 4 * x + 1]); let p0 = u32::from(self.data[row_start + 4 * x]); match self.byte_order { ImageOrder::LSBFirst => p0 | (p1 << 8) | (p2 << 16) | (p3 << 24), ImageOrder::MSBFirst => p3 | (p2 << 8) | (p1 << 16) | (p0 << 24), } } } } } fn compute_depth_1_address(x: usize, order: ImageOrder) -> (usize, usize) { let bit = match order { ImageOrder::MSBFirst => 7 - x % 8, ImageOrder::LSBFirst => x % 8, }; (x / 8, bit) } #[cfg(test)] mod test_image { use super::{BitsPerPixel, Image, ImageOrder, ParseError, ScanlinePad}; use std::borrow::Cow; #[test] fn test_new_too_short() { let depth = 16; // Due to Pad16, this image needs two bytes let result = Image::new( 1, 1, ScanlinePad::Pad16, depth, BitsPerPixel::B8, ImageOrder::MSBFirst, Cow::Owned(vec![0]), ); assert_eq!(result.unwrap_err(), ParseError::InsufficientData); } #[test] fn test_new() { let depth = 16; let image = Image::new( 2, 1, ScanlinePad::Pad16, depth, BitsPerPixel::B8, ImageOrder::MSBFirst, Cow::Owned(vec![42, 125]), ) .unwrap(); assert_eq!(image.width(), 2); assert_eq!(image.height(), 1); assert_eq!(image.scanline_pad(), ScanlinePad::Pad16); assert_eq!(image.depth(), depth); assert_eq!(image.bits_per_pixel(), BitsPerPixel::B8); assert_eq!(image.byte_order(), ImageOrder::MSBFirst); assert_eq!(image.data(), [42, 125]); } #[test] fn put_pixel_depth1() { let mut image = Image::allocate( 16, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B1, ImageOrder::MSBFirst, ); for x in 0..8 { image.put_pixel(x, 0, 1); } assert_eq!(0b_1111_1111, image.data()[0]); image.put_pixel(0, 0, 0); assert_eq!(0b_0111_1111, image.data()[0]); image.put_pixel(2, 0, 0); assert_eq!(0b_0101_1111, image.data()[0]); image.put_pixel(4, 0, 0); assert_eq!(0b_0101_0111, image.data()[0]); image.put_pixel(6, 0, 0); assert_eq!(0b_0101_0101, image.data()[0]); image.data_mut()[1] = 0; image.put_pixel(8, 0, 1); assert_eq!(0b_1000_0000, image.data()[1]); image.put_pixel(15, 0, 1); assert_eq!(0b_1000_0001, image.data()[1]); assert_eq!(0b_0000_0000, image.data()[5]); image.put_pixel(15, 1, 1); assert_eq!(0b_0000_0001, image.data()[5]); } #[test] fn put_pixel_depth4() { let mut image = Image::allocate( 8, 2, ScanlinePad::Pad16, 1, BitsPerPixel::B4, ImageOrder::MSBFirst, ); for pos in 0..=0xf { image.put_pixel(pos % 8, pos / 8, pos.into()); } assert_eq!( image.data(), [0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE] ); } #[test] fn put_pixel_depth8() { let mut image = Image::allocate( 256, 2, ScanlinePad::Pad8, 1, BitsPerPixel::B8, ImageOrder::MSBFirst, ); for x in 0..=0xff { image.put_pixel(x, 0, x.into()); } image.put_pixel(255, 1, 0x1245_89AB); let expected = (0..=0xff) .chain((0..0xff).map(|_| 0)) .chain(std::iter::once(0xAB)) .collect::>(); assert_eq!(image.data(), &expected[..]); } #[test] fn put_pixel_depth16() { let mut image = Image::allocate( 5, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B16, ImageOrder::MSBFirst, ); image.put_pixel(0, 0, 0xAB_36_18_F8); image.put_pixel(4, 0, 0x12_34_56_78); image.put_pixel(4, 1, 0xFE_DC_BA_98); #[rustfmt::skip] let expected = [ // First row 0x18, 0xF8, 0, 0, 0, 0, 0, 0, 0x56, 0x78, // Padding Pad32 0, 0, // Second row 0, 0, 0, 0, 0, 0, 0, 0, 0xBA, 0x98, // Padding Pad32 0, 0, ]; assert_eq!(image.data(), expected); } #[test] fn put_pixel_depth32() { let mut image = Image::allocate( 2, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B32, ImageOrder::MSBFirst, ); image.put_pixel(0, 0, 0xAB_36_18_F8); image.put_pixel(1, 0, 0x12_34_56_78); image.put_pixel(1, 1, 0xFE_DC_BA_98); #[rustfmt::skip] let expected = [ // First row 0xAB, 0x36, 0x18, 0xF8, 0x12, 0x34, 0x56, 0x78, // Second row 0x00, 0x00, 0x00, 0x00, 0xFE, 0xDC, 0xBA, 0x98, ]; assert_eq!(image.data(), expected); } #[test] fn get_pixel_depth1() { let image = Image::new( 16, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B1, ImageOrder::MSBFirst, Cow::Borrowed(&DATA), ) .unwrap(); assert_eq!(1, image.get_pixel(0, 0)); assert_eq!(1, image.get_pixel(10, 0)); assert_eq!(0, image.get_pixel(15, 0)); assert_eq!(0, image.get_pixel(0, 1)); assert_eq!(1, image.get_pixel(10, 1)); assert_eq!(0, image.get_pixel(15, 1)); } #[test] fn get_pixel_depth4() { let image = Image::new( 16, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B4, ImageOrder::MSBFirst, Cow::Borrowed(&DATA), ) .unwrap(); assert_eq!(0xB, image.get_pixel(0, 0)); assert_eq!(0x4, image.get_pixel(10, 0)); assert_eq!(0x7, image.get_pixel(15, 0)); assert_eq!(0x0, image.get_pixel(0, 1)); assert_eq!(0xC, image.get_pixel(10, 1)); assert_eq!(0x9, image.get_pixel(15, 1)); } #[test] fn get_pixel_depth8() { let image = Image::new( 3, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B8, ImageOrder::MSBFirst, Cow::Borrowed(&DATA), ) .unwrap(); assert_eq!(0xAB, image.get_pixel(0, 0)); assert_eq!(0x36, image.get_pixel(1, 0)); assert_eq!(0x18, image.get_pixel(2, 0)); assert_eq!(0x12, image.get_pixel(0, 1)); assert_eq!(0x34, image.get_pixel(1, 1)); assert_eq!(0x56, image.get_pixel(2, 1)); } #[test] fn get_pixel_depth16() { let image = Image::new( 3, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B16, ImageOrder::MSBFirst, Cow::Borrowed(&DATA), ) .unwrap(); assert_eq!(0xAB36, image.get_pixel(0, 0)); assert_eq!(0x18F8, image.get_pixel(1, 0)); assert_eq!(0x1234, image.get_pixel(2, 0)); assert_eq!(0x0000, image.get_pixel(0, 1)); assert_eq!(0x0000, image.get_pixel(1, 1)); assert_eq!(0xFEDC, image.get_pixel(2, 1)); } #[test] fn get_pixel_depth32() { let image = Image::new( 2, 2, ScanlinePad::Pad32, 1, BitsPerPixel::B32, ImageOrder::MSBFirst, Cow::Borrowed(&DATA), ) .unwrap(); assert_eq!(0xAB36_18F8, image.get_pixel(0, 0)); assert_eq!(0x1234_5678, image.get_pixel(1, 0)); assert_eq!(0x0000_0000, image.get_pixel(0, 1)); assert_eq!(0xFEDC_BA98, image.get_pixel(1, 1)); } static DATA: [u8; 16] = [ 0xAB, 0x36, 0x18, 0xF8, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xDC, 0xBA, 0x98, ]; } x11rb-0.8.1/src/lib.rs010064400017500001750000000204271402220031600125340ustar 00000000000000//! X11 rust bindings. //! //! This library allows to interact with an X11 server from rust code. A connection to an X11 //! server is represented by an implementation of the `Connection` trait. //! //! The client can interact with the server by sending requests. The server can answer requests and //! can also generate events. //! //! The examples that come with this library might be a good starting point for new users. //! //! //! # Getting started with X11 //! //! X11 is a big protocol. I would claim that most of it is not actually that complicated, but it //! is still difficult to get into it. A good starting point might be some [libxcb //! tutorial](https://www.x.org/releases/X11R7.7/doc/libxcb/tutorial/index.html). This tutorial //! was adapted in this crate [as an //! example](https://github.com/psychon/x11rb/blob/master/examples/tutorial.rs). A more in-depth //! look at the X11 protocol can be gained from the [protocol reference //! manual](https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html), but this requires some //! existing basic understanding of X11. If you want to figure out what some specific request does, //! be sure to look it up in the specification! //! //! Most extensions can be understood by reading their specification. Most of them can be found //! [here](https://www.x.org/releases/current/doc/index.html#protocol). For example, [the //! specification of Composite //! 0.4](https://www.x.org/releases/X11R7.5/doc/compositeproto/compositeproto.txt) consists of //! about six pages of text. //! //! The notable exception is the X keyboard extension, which is documented in a [PDF file with 168 //! pages](https://www.x.org/releases/current/doc/kbproto/xkbproto.pdf) which I am never going to //! read completely. //! //! //! # Getting started with x11rb //! //! Most code in this code is automatically generated from an XML description of the protocol. This //! is the same approach as taken by [libxcb](https://xcb.freedesktop.org/) (and in fact this uses //! the same XML description). This means that if you know your way around X11, most things should //! be obvious to you. //! //! For example, here is how to create a new window with x11rb: //! ```no_run //! use x11rb::connection::Connection; //! use x11rb::errors::ReplyOrIdError; //! use x11rb::protocol::xproto::*; //! use x11rb::COPY_DEPTH_FROM_PARENT; //! //! fn main() -> Result<(), Box> { //! let (conn, screen_num) = x11rb::connect(None).unwrap(); //! let screen = &conn.setup().roots[screen_num]; //! let win_id = conn.generate_id()?; //! conn.create_window( //! COPY_DEPTH_FROM_PARENT, //! win_id, //! screen.root, //! 0, //! 0, //! 100, //! 100, //! 0, //! WindowClass::INPUT_OUTPUT, //! 0, //! &CreateWindowAux::new().background_pixel(screen.white_pixel), //! )?; //! conn.map_window(win_id)?; //! conn.flush(); //! loop { //! println!("Event: {:?}", conn.wait_for_event()?); //! } //! } //! ``` //! More examples can be found in the //! [examples](https://github.com/psychon/x11rb/tree/master/examples) directory. //! //! ## Feature flags //! //! This crate uses [feature //! flags](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section) to reduce //! the amount of compiled code. There are two kinds of feature flags available: //! //! * Feature flags for specific X11 extensions //! * Feature flags for additional functionality //! //! ### Feature flags for specific X11 extensions //! //! By default, only the core X11 protocol and X11 extensions that are //! needed internally are enabled. Further extensions need to be explicitly enabled via their //! feature flag: //! //! `composite`, `damage`, `dpms`, `dri2`, `dri3`, `glx`, `present`, `randr`, `record`, `render`, //! `res`, `screensaver`, `shape`, `shm`, `sync`, `xevie`, `xf86dri`, `xf86vidmode`, `xfixes`, //! `xinerama`, `xinput`, `xkb`, `xprint`, `xselinux`, `xtest`, `xv`, `xvmc`. //! //! If you want to take the "I do not want to think about this"-approach, you can enable the //! `all-extensions` feature to just enable, well, all extensions. //! //! ### Feature flags for additional functionality //! //! Additionally, the following flags exist: //! * `allow-unsafe-code`: Enable features that require `unsafe`. Without this flag, //! `x11rb::xcb_ffi::XCBConnection` and some support code for it are unavailable. //! * `cursor`: Enable the code in [crate::cursor] for loading cursor files. //! * `resource_manager`: Enable the code in [crate::resource_manager] for loading and querying the //! X11 resource database. //! * `image`: Enable the code in [crate::image] for working with pixel image data. //! * `dl-libxcb`: Enabling this feature will prevent from libxcb being linked to the //! resulting executable. Instead libxcb will be dynamically loaded at runtime. //! This feature adds the [`crate::xcb_ffi::load_libxcb`] function, that allows to load //! libxcb and check for success or failure. //! //! # Integrating x11rb with an Event Loop //! //! The [event_loop_integration](event_loop_integration/index.html) module contains some hints for //! integrating x11rb with an event loop as doc comments. #![forbid( missing_copy_implementations, missing_debug_implementations, private_doc_tests, rust_2018_idioms, //single_use_lifetimes, trivial_casts, trivial_numeric_casts, unreachable_pub, unused_import_braces, unused_results, clippy::cast_lossless, clippy::needless_pass_by_value, )] // A list of lints that are only #![deny] and not the stronger #![forbid]. Each one has a comment // explaining why it gets the weaker treatment. #![deny( // #[derive] generates an #[allow] for this unused_qualifications, // Not everything in x11rb::protocol has doc comments missing_docs, )] #![allow( // This suggests a method that was stabilised in Rust 1.45, while our MSRV is 1.40. clippy::manual_strip, // This suggests a macro that was stabilised in Rust 1.42, while our MSRV is 1.40. clippy::match_like_matches_macro, )] #![cfg_attr(not(feature = "allow-unsafe-code"), forbid(unsafe_code))] // Only contains documentation, but no "actual rust" pub mod event_loop_integration; pub mod utils; #[cfg(feature = "allow-unsafe-code")] pub mod xcb_ffi; #[macro_use] pub mod x11_utils; pub mod connection; pub mod cookie; #[cfg(feature = "cursor")] pub mod cursor; pub mod errors; pub mod extension_manager; #[cfg(feature = "image")] pub mod image; pub mod properties; pub mod rust_connection; pub mod wrapper; #[rustfmt::skip] #[allow(missing_docs)] pub mod protocol; #[cfg(feature = "resource_manager")] pub mod resource_manager; #[cfg(test)] mod test; use connection::Connection; use errors::ConnectError; use protocol::xproto::{Keysym, Timestamp}; /// Establish a new connection to an X11 server. /// /// If a `dpy_name` is provided, it describes the display that should be connected to, for /// example `127.0.0.1:1`. If no value is provided, the `$DISPLAY` environment variable is /// used. pub fn connect( dpy_name: Option<&str>, ) -> Result<(impl Connection + Send + Sync, usize), ConnectError> { #[cfg(feature = "allow-unsafe-code")] { let dpy_name = dpy_name .map(std::ffi::CString::new) .transpose() .map_err(|_| ConnectError::DisplayParsingError)?; let dpy_name = dpy_name.as_deref(); xcb_ffi::XCBConnection::connect(dpy_name) } #[cfg(not(feature = "allow-unsafe-code"))] { rust_connection::RustConnection::connect(dpy_name) } } /// The universal null resource or null atom parameter value for many core X requests pub const NONE: u32 = 0; /// This constant can be used for many parameters in `create_window` pub const COPY_FROM_PARENT: u32 = 0; /// This constant can be used for the depth parameter in `create_window`. It indicates to use the /// parent window's depth. pub const COPY_DEPTH_FROM_PARENT: u8 = 0; /// This constant can be used for the class parameter in `create_window`. It indicates to use the /// parent window's class. pub const COPY_CLASS_FROM_PARENT: u16 = 0; /// This constant can be used in most request that take a timestamp argument pub const CURRENT_TIME: Timestamp = 0; /// This constant can be used to fill unused entries in `Keysym` tables pub const NO_SYMBOL: Keysym = 0; x11rb-0.8.1/src/properties.rs010064400017500001750000000656751402220031600142000ustar 00000000000000//! Utility functions for working with X11 properties use std::convert::TryInto; use crate::connection::RequestConnection; use crate::cookie::{Cookie, VoidCookie}; use crate::errors::{ConnectionError, ParseError, ReplyError}; use crate::protocol::xproto::{self, Atom, AtomEnum, GetPropertyReply, Window}; use crate::x11_utils::{Serialize, TryParse}; // WM_CLASS /// A cookie for getting a window's `WM_CLASS` property. /// /// See `WmClass`. #[derive(Debug)] pub struct WmClassCookie<'a, Conn: RequestConnection + ?Sized>(Cookie<'a, Conn, GetPropertyReply>); impl<'a, Conn> WmClassCookie<'a, Conn> where Conn: RequestConnection + ?Sized, { /// Send a `GetProperty` request for the `WM_CLASS` property of the given window pub fn new(conn: &'a Conn, window: Window) -> Result { Ok(Self(xproto::get_property( conn, false, window, AtomEnum::WM_CLASS, AtomEnum::STRING, 0, 2048, )?)) } /// Get the reply that the server sent. pub fn reply(self) -> Result { Ok(WmClass::from_reply(self.0.reply()?)?) } /// Get the reply that the server sent, but have errors handled as events. pub fn reply_unchecked(self) -> Result, ConnectionError> { self.0 .reply_unchecked()? .map(WmClass::from_reply) .transpose() .map_err(Into::into) } } /// The value of a window's `WM_CLASS` property. /// /// Usage example: /// ``` /// use x11rb::connection::Connection; /// use x11rb::errors::ConnectionError; /// use x11rb::properties::WmClass; /// use x11rb::protocol::xproto::Window; /// /// fn print_class_instance( /// conn: &impl Connection, /// window: Window, /// ) -> Result { /// let wm_class = match WmClass::get(conn, window)?.reply_unchecked()? { /// Some(wm_class) => wm_class, /// None => return Ok(false), // Getting the property failed /// }; /// // Note that the WM_CLASS property is not actually encoded in utf8. /// // ASCII values are most common and for these from_utf8() should be fine. /// let class = std::str::from_utf8(wm_class.class()); /// let instance = std::str::from_utf8(wm_class.instance()); /// println!( /// "For window {:x}, class is '{:?}' and instance is '{:?}'", /// window, class, instance, /// ); /// Ok(true) /// } /// ``` #[derive(Debug)] pub struct WmClass(GetPropertyReply, usize); impl WmClass { /// Send a `GetProperty` request for the `WM_CLASS` property of the given window pub fn get( conn: &C, window: Window, ) -> Result, ConnectionError> { WmClassCookie::new(conn, window) } /// Construct a new `WmClass` instance from a `GetPropertyReply`. /// /// The original `GetProperty` request must have been for a `WM_CLASS` property for this /// function to return sensible results. pub fn from_reply(reply: GetPropertyReply) -> Result { if reply.type_ != AtomEnum::STRING.into() || reply.format != 8 { return Err(ParseError::InvalidValue); } // Find the first zero byte in the value let offset = reply .value .iter() .position(|&v| v == 0) .unwrap_or_else(|| reply.value.len()); Ok(WmClass(reply, offset)) } /// Get the instance contained in this `WM_CLASS` property pub fn instance(&self) -> &[u8] { &self.0.value[0..self.1] } /// Get the class contained in this `WM_CLASS` property pub fn class(&self) -> &[u8] { let start = self.1 + 1; if start >= self.0.value.len() { return &[]; }; let end = if self.0.value.last() == Some(&0) { self.0.value.len() - 1 } else { self.0.value.len() }; &self.0.value[start..end] } } // WM_SIZE_HINTS /// Representation of whether some part of `WM_SIZE_HINTS` was user/program specified. #[derive(Debug, Copy, Clone)] pub enum WmSizeHintsSpecification { /// The user specified the values. UserSpecified, /// The program specified the values. ProgramSpecified, } /// A cookie for getting a window's `WM_SIZE_HINTS` property. #[derive(Debug)] pub struct WmSizeHintsCookie<'a, Conn: RequestConnection + ?Sized>( Cookie<'a, Conn, GetPropertyReply>, ); const NUM_WM_SIZE_HINTS_ELEMENTS: u32 = 18; impl<'a, Conn> WmSizeHintsCookie<'a, Conn> where Conn: RequestConnection + ?Sized, { /// Send a `GetProperty` request for the given property of the given window pub fn new( conn: &'a Conn, window: Window, property: impl Into, ) -> Result { Ok(Self(xproto::get_property( conn, false, window, property, AtomEnum::WM_SIZE_HINTS, 0, NUM_WM_SIZE_HINTS_ELEMENTS, )?)) } /// Get the reply that the server sent. pub fn reply(self) -> Result { Ok(WmSizeHints::from_reply(&self.0.reply()?)?) } /// Get the reply that the server sent, but have errors handled as events. pub fn reply_unchecked(self) -> Result, ConnectionError> { self.0 .reply_unchecked()? .map(|r| WmSizeHints::from_reply(&r)) .transpose() .map_err(Into::into) } } // Possible flags for `WM_SIZE_HINTS`. const U_S_POSITION: u32 = 1; const U_S_SIZE: u32 = 1 << 1; const P_S_POSITION: u32 = 1 << 2; const P_S_SIZE: u32 = 1 << 3; const P_MIN_SIZE: u32 = 1 << 4; const P_MAX_SIZE: u32 = 1 << 5; const P_RESIZE_INCREMENT: u32 = 1 << 6; const P_ASPECT: u32 = 1 << 7; const P_BASE_SIZE: u32 = 1 << 8; const P_WIN_GRAVITY: u32 = 1 << 9; /// An aspect ratio `numerator` / `denominator`. #[derive(Debug, Copy, Clone)] pub struct AspectRatio { /// The numerator of the aspect ratio. pub numerator: i32, /// The denominator of the aspect ratio. pub denominator: i32, } impl AspectRatio { /// Create a new aspect ratio with the given values. pub fn new(numerator: i32, denominator: i32) -> Self { Self { numerator, denominator, } } } impl TryParse for AspectRatio { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let ((numerator, denominator), remaining) = TryParse::try_parse(value)?; let result = AspectRatio::new(numerator, denominator); Ok((result, remaining)) } } #[allow(clippy::many_single_char_names)] impl Serialize for AspectRatio { type Bytes = [u8; 8]; fn serialize(&self) -> Self::Bytes { let [a, b, c, d] = self.numerator.serialize(); let [e, f, g, h] = self.denominator.serialize(); [a, b, c, d, e, f, g, h] } fn serialize_into(&self, bytes: &mut Vec) { (self.numerator, self.denominator).serialize_into(bytes); } } /// A structure representing a `WM_SIZE_HINTS` property. #[derive(Debug, Default, Copy, Clone)] pub struct WmSizeHints { /// The position that the window should be assigned. /// /// Note that current versions of ICCCM only make use of the `WmSizeHintsSpecification` field. /// The later two fields exist only for backwards compatibility. pub position: Option<(WmSizeHintsSpecification, i32, i32)>, /// The size that the window should be assigned. /// /// Note that current versions of ICCCM only make use of the `WmSizeHintsSpecification` field. /// The later two fields exist only for backwards compatibility. pub size: Option<(WmSizeHintsSpecification, i32, i32)>, /// The minimum size that the window may be assigned. pub min_size: Option<(i32, i32)>, /// The maximum size that the window may be assigned. pub max_size: Option<(i32, i32)>, /// The increment to be used for sizing the window together with `base_size`. pub size_increment: Option<(i32, i32)>, /// The minimum and maximum aspect ratio. pub aspect: Option<(AspectRatio, AspectRatio)>, /// The base size of the window. /// /// This is used together with `size_increment`. pub base_size: Option<(i32, i32)>, /// The gravity that is used to make room for window decorations. pub win_gravity: Option, } impl WmSizeHints { /// Get a new, empty `WmSizeHints` structure. pub fn new() -> Self { Default::default() } /// Send a `GetProperty` request for the given property of the given window pub fn get( conn: &C, window: Window, property: impl Into, ) -> Result, ConnectionError> { WmSizeHintsCookie::new(conn, window, property) } /// Send a `GetProperty` request for the `WM_NORMAL_HINTS` property of the given window pub fn get_normal_hints( conn: &C, window: Window, ) -> Result, ConnectionError> { Self::get(conn, window, AtomEnum::WM_NORMAL_HINTS) } /// Construct a new `WmSizeHints` instance from a `GetPropertyReply`. /// /// The original `WmSizeHints` request must have been for a `WM_SIZE_HINTS` property for this /// function to return sensible results. pub fn from_reply(reply: &GetPropertyReply) -> Result { if reply.type_ != AtomEnum::WM_SIZE_HINTS.into() || reply.format != 32 { return Err(ParseError::InvalidValue); } Ok(Self::try_parse(&reply.value)?.0) } /// Set these `WM_SIZE_HINTS` on some window as the `WM_NORMAL_HINTS` property. pub fn set_normal_hints<'a, C: RequestConnection + ?Sized>( &self, conn: &'a C, window: Window, ) -> Result, ConnectionError> { self.set(conn, window, AtomEnum::WM_NORMAL_HINTS) } /// Set these `WM_SIZE_HINTS` on some window as the given property. pub fn set<'a, C: RequestConnection + ?Sized>( &self, conn: &'a C, window: Window, property: impl Into, ) -> Result, ConnectionError> { let data = self.serialize(); xproto::change_property( conn, xproto::PropMode::REPLACE, window, property.into(), AtomEnum::WM_SIZE_HINTS, 32, NUM_WM_SIZE_HINTS_ELEMENTS, &data, ) } } impl TryParse for WmSizeHints { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { // Implemented based on what xcb_icccm does. At least a bit. This stuff makes no sense... let (flags, remaining) = u32::try_parse(remaining)?; let (x, remaining) = i32::try_parse(remaining)?; let (y, remaining) = i32::try_parse(remaining)?; let (width, remaining) = i32::try_parse(remaining)?; let (height, remaining) = i32::try_parse(remaining)?; let (min_size, remaining) = parse_with_flag::<(i32, i32)>(remaining, flags, P_MIN_SIZE)?; let (max_size, remaining) = parse_with_flag::<(i32, i32)>(remaining, flags, P_MAX_SIZE)?; let (size_increment, remaining) = parse_with_flag::<(i32, i32)>(remaining, flags, P_RESIZE_INCREMENT)?; let (aspect, remaining) = parse_with_flag::<(AspectRatio, AspectRatio)>(remaining, flags, P_ASPECT)?; // Apparently, some older version of ICCCM didn't have these...? let (base_size, win_gravity, remaining) = if remaining.is_empty() { (min_size, Some(xproto::Gravity::NORTH_WEST), remaining) } else { let (base_size, remaining) = parse_with_flag::<(i32, i32)>(remaining, flags, P_BASE_SIZE)?; let (win_gravity, remaining) = parse_with_flag::(remaining, flags, P_WIN_GRAVITY)?; (base_size, win_gravity.map(Into::into), remaining) }; let position = if flags & U_S_POSITION != 0 { Some((WmSizeHintsSpecification::UserSpecified, x, y)) } else if flags & P_S_POSITION != 0 { Some((WmSizeHintsSpecification::ProgramSpecified, x, y)) } else { None }; let size = if flags & U_S_SIZE != 0 { Some((WmSizeHintsSpecification::UserSpecified, width, height)) } else if flags & P_S_SIZE != 0 { Some((WmSizeHintsSpecification::ProgramSpecified, width, height)) } else { None }; Ok(( WmSizeHints { position, size, min_size, max_size, size_increment, aspect, base_size, win_gravity, }, remaining, )) } } impl Serialize for WmSizeHints { type Bytes = Vec; fn serialize(&self) -> Self::Bytes { // 18*4 surely fits into an usize, so this unwrap() cannot trigger let mut result = Vec::with_capacity((NUM_WM_SIZE_HINTS_ELEMENTS * 4).try_into().unwrap()); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let mut flags = 0; match self.position { Some((WmSizeHintsSpecification::UserSpecified, _, _)) => flags |= U_S_POSITION, Some((WmSizeHintsSpecification::ProgramSpecified, _, _)) => flags |= P_S_POSITION, None => {} } match self.size { Some((WmSizeHintsSpecification::UserSpecified, _, _)) => flags |= U_S_SIZE, Some((WmSizeHintsSpecification::ProgramSpecified, _, _)) => flags |= P_S_SIZE, None => {} } flags |= self.min_size.map_or(0, |_| P_MIN_SIZE); flags |= self.max_size.map_or(0, |_| P_MAX_SIZE); flags |= self.size_increment.map_or(0, |_| P_RESIZE_INCREMENT); flags |= self.aspect.map_or(0, |_| P_ASPECT); flags |= self.base_size.map_or(0, |_| P_BASE_SIZE); flags |= self.win_gravity.map_or(0, |_| P_WIN_GRAVITY); flags.serialize_into(bytes); match self.position { Some((_, x, y)) => (x, y), None => (0, 0), } .serialize_into(bytes); match self.size { Some((_, width, height)) => (width, height), None => (0, 0), } .serialize_into(bytes); self.min_size.unwrap_or((0, 0)).serialize_into(bytes); self.max_size.unwrap_or((0, 0)).serialize_into(bytes); self.size_increment.unwrap_or((0, 0)).serialize_into(bytes); self.aspect .unwrap_or((AspectRatio::new(0, 0), AspectRatio::new(0, 0))) .serialize_into(bytes); self.base_size.unwrap_or((0, 0)).serialize_into(bytes); self.win_gravity.map_or(0, u32::from).serialize_into(bytes); } } // WM_HINTS /// A cookie for getting a window's `WM_HINTS` property. /// /// See `WmHints`. #[derive(Debug)] pub struct WmHintsCookie<'a, Conn: RequestConnection + ?Sized>(Cookie<'a, Conn, GetPropertyReply>); const NUM_WM_HINTS_ELEMENTS: u32 = 9; impl<'a, Conn> WmHintsCookie<'a, Conn> where Conn: RequestConnection + ?Sized, { /// Send a `GetProperty` request for the `WM_CLASS` property of the given window pub fn new(conn: &'a Conn, window: Window) -> Result { Ok(Self(xproto::get_property( conn, false, window, AtomEnum::WM_HINTS, AtomEnum::WM_HINTS, 0, NUM_WM_HINTS_ELEMENTS, )?)) } /// Get the reply that the server sent. pub fn reply(self) -> Result { Ok(WmHints::from_reply(&self.0.reply()?)?) } /// Get the reply that the server sent, but have errors handled as events. pub fn reply_unchecked(self) -> Result, ConnectionError> { self.0 .reply_unchecked()? .map(|r| WmHints::from_reply(&r)) .transpose() .map_err(Into::into) } } /// The possible values for a `WM_STATE`'s state field. #[derive(Debug, Copy, Clone)] pub enum WmHintsState { /// The window should be in Normal state. Normal, /// The window should be in Iconic state. Iconic, } // Possible flags for `WM_HINTS`. const HINT_INPUT: u32 = 1; const HINT_STATE: u32 = 1 << 1; const HINT_ICON_PIXMAP: u32 = 1 << 2; const HINT_ICON_WINDOW: u32 = 1 << 3; const HINT_ICON_POSITION: u32 = 1 << 4; const HINT_ICON_MASK: u32 = 1 << 5; const HINT_WINDOW_GROUP: u32 = 1 << 6; // This bit is obsolete, according to ICCCM //const HINT_MESSAGE: u32 = 1 << 7; const HINT_URGENCY: u32 = 1 << 8; /// A structure representing a `WM_HINTS` property. #[derive(Debug, Default, Copy, Clone)] pub struct WmHints { /// Whether the window manager may set the input focus to this window. /// /// See ICCCM §4.1.7 for details. pub input: Option, /// The state that the window should be when it leaves the Withdrawn state. pub initial_state: Option, /// A pixmap that represents the icon of this window. pub icon_pixmap: Option, /// A window that should be used as icon. pub icon_window: Option, /// The position where the icon should be shown. pub icon_position: Option<(i32, i32)>, /// A mask for `icon_pixmap`. /// /// This allows nonrectangular icons. pub icon_mask: Option, /// A window that represents a group of windows. /// /// The specified window is called the "group leader". All windows with the same group leader /// are part of the same group. pub window_group: Option, /// Indication that the window contents are urgent. /// /// Urgency means that a timely response of the user is required. The window manager must make /// some effort to draw the user's attention to this window while this flag is set. pub urgent: bool, } impl WmHints { /// Get a new, empty `WmSizeHints` structure. pub fn new() -> Self { Default::default() } /// Send a `GetProperty` request for the `WM_HINTS` property of the given window pub fn get( conn: &C, window: Window, ) -> Result, ConnectionError> { WmHintsCookie::new(conn, window) } /// Construct a new `WmHints` instance from a `GetPropertyReply`. /// /// The original `WmHints` request must have been for a `WM_HINTS` property for this /// function to return sensible results. pub fn from_reply(reply: &GetPropertyReply) -> Result { if reply.type_ != AtomEnum::WM_HINTS.into() || reply.format != 32 { return Err(ParseError::InvalidValue); } Ok(Self::try_parse(&reply.value)?.0) } /// Set these `WM_HINTS` on some window. pub fn set<'a, C: RequestConnection + ?Sized>( &self, conn: &'a C, window: Window, ) -> Result, ConnectionError> { let data = self.serialize(); xproto::change_property( conn, xproto::PropMode::REPLACE, window, xproto::AtomEnum::WM_HINTS, xproto::AtomEnum::WM_HINTS, 32, NUM_WM_HINTS_ELEMENTS, &data, ) } } impl TryParse for WmHints { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (flags, remaining) = u32::try_parse(remaining)?; let (input, remaining) = parse_with_flag::(remaining, flags, HINT_INPUT)?; let (initial_state, remaining) = parse_with_flag::(remaining, flags, HINT_STATE)?; let (icon_pixmap, remaining) = parse_with_flag::(remaining, flags, HINT_ICON_PIXMAP)?; let (icon_window, remaining) = parse_with_flag::(remaining, flags, HINT_ICON_WINDOW)?; let (icon_position, remaining) = parse_with_flag::<(i32, i32)>(remaining, flags, HINT_ICON_POSITION)?; let (icon_mask, remaining) = parse_with_flag::(remaining, flags, HINT_ICON_MASK)?; // Apparently, some older version of ICCCM didn't have this...? let (window_group, remaining) = if remaining.is_empty() { (None, remaining) } else { let (window_group, remaining) = parse_with_flag::(remaining, flags, HINT_WINDOW_GROUP)?; (window_group, remaining) }; let input = input.map(|input| input != 0); let initial_state = match initial_state { None => None, Some(1) => Some(WmHintsState::Normal), Some(3) => Some(WmHintsState::Iconic), _ => return Err(ParseError::InvalidValue), }; let urgent = flags & HINT_URGENCY != 0; Ok(( WmHints { input, initial_state, icon_pixmap, icon_window, icon_position, icon_mask, window_group, urgent, }, remaining, )) } } impl Serialize for WmHints { type Bytes = Vec; fn serialize(&self) -> Self::Bytes { // 9*4 surely fits into an usize, so this unwrap() cannot trigger let mut result = Vec::with_capacity((NUM_WM_HINTS_ELEMENTS * 4).try_into().unwrap()); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let mut flags = 0; flags |= self.input.map_or(0, |_| HINT_INPUT); flags |= self.initial_state.map_or(0, |_| HINT_STATE); flags |= self.icon_pixmap.map_or(0, |_| HINT_ICON_PIXMAP); flags |= self.icon_window.map_or(0, |_| HINT_ICON_WINDOW); flags |= self.icon_position.map_or(0, |_| HINT_ICON_POSITION); flags |= self.icon_mask.map_or(0, |_| HINT_ICON_MASK); flags |= self.window_group.map_or(0, |_| HINT_WINDOW_GROUP); if self.urgent { flags |= HINT_URGENCY; } flags.serialize_into(bytes); u32::from(self.input.unwrap_or(false)).serialize_into(bytes); match self.initial_state { Some(WmHintsState::Normal) => 1, Some(WmHintsState::Iconic) => 3, None => 0, } .serialize_into(bytes); self.icon_pixmap.unwrap_or(0).serialize_into(bytes); self.icon_window.unwrap_or(0).serialize_into(bytes); self.icon_position.unwrap_or((0, 0)).serialize_into(bytes); self.icon_mask.unwrap_or(0).serialize_into(bytes); self.window_group.unwrap_or(0).serialize_into(bytes); } } /// Parse an element of type `T` and turn it into an `Option` by checking if the given `bit` is set /// in `flags`. fn parse_with_flag( remaining: &[u8], flags: u32, bit: u32, ) -> Result<(Option, &[u8]), ParseError> { let (value, remaining) = T::try_parse(remaining)?; if flags & bit != 0 { Ok((Some(value), remaining)) } else { Ok((None, remaining)) } } #[cfg(test)] mod test { use std::convert::TryInto; use super::{WmClass, WmHints, WmHintsState, WmSizeHints}; use crate::protocol::xproto::{Atom, AtomEnum, GetPropertyReply, Gravity}; use crate::x11_utils::Serialize; fn get_property_reply(value: &[u8], format: u8, type_: impl Into) -> GetPropertyReply { GetPropertyReply { format, sequence: 0, length: 0, type_: type_.into(), bytes_after: 0, value_len: value.len().try_into().unwrap(), value: value.to_vec(), } } #[test] fn test_wm_class() { for (input, instance, class) in &[ (&b""[..], &b""[..], &b""[..]), (b"\0", b"", b""), (b"\0\0", b"", b""), (b"\0\0\0", b"", b"\0"), (b"Hello World", b"Hello World", b""), (b"Hello World\0", b"Hello World", b""), (b"Hello\0World\0", b"Hello", b"World"), (b"Hello\0World", b"Hello", b"World"), (b"Hello\0World\0Good\0Day", b"Hello", b"World\0Good\0Day"), ] { let wm_class = WmClass::from_reply(get_property_reply(input, 8, AtomEnum::STRING)).unwrap(); assert_eq!((wm_class.instance(), wm_class.class()), (*instance, *class)); } } #[test] fn test_wm_normal_hints() { // This is the value of some random xterm window. // It was acquired via 'xtrace xprop WM_NORMAL_HINTS'. let input = [ 0x0000_0350, 0x0000_0000, 0x0000_0000, 0x0000_0000, 0x0000_0000, 0x0000_0015, 0x0000_0017, 0x0000_0000, 0x0000_0000, 0x0000_000a, 0x0000_0013, 0x0000_0000, 0x0000_0000, 0x0000_0000, 0x0000_0000, 0x0000_000b, 0x0000_0004, 0x0000_0001, ]; let input = input .iter() .flat_map(|v| u32::serialize(v).to_vec()) .collect::>(); let wm_size_hints = WmSizeHints::from_reply(&get_property_reply(&input, 32, AtomEnum::WM_SIZE_HINTS)) .unwrap(); assert!( wm_size_hints.position.is_none(), "{:?}", wm_size_hints.position, ); assert!(wm_size_hints.size.is_none(), "{:?}", wm_size_hints.size); assert_eq!(wm_size_hints.min_size, Some((21, 23))); assert_eq!(wm_size_hints.max_size, None); assert_eq!(wm_size_hints.size_increment, Some((10, 19))); assert!(wm_size_hints.aspect.is_none(), "{:?}", wm_size_hints.aspect); assert_eq!(wm_size_hints.base_size, Some((11, 4))); assert_eq!(wm_size_hints.win_gravity, Some(Gravity::NORTH_WEST)); assert_eq!(input, wm_size_hints.serialize()); } #[test] fn test_wm_hints() { // This is the value of some random xterm window. // It was acquired via 'xtrace xprop WM_HINTS'. let input = [ 0x0000_0043, 0x0000_0001, 0x0000_0001, 0x0000_0000, 0x0000_0000, 0x0000_0000, 0x0000_0000, 0x0000_0000, 0x0060_0009, ]; let input = input .iter() .flat_map(|v| u32::serialize(v).to_vec()) .collect::>(); let wm_hints = WmHints::from_reply(&get_property_reply(&input, 32, AtomEnum::WM_HINTS)).unwrap(); assert_eq!(wm_hints.input, Some(true)); match wm_hints.initial_state { Some(WmHintsState::Normal) => {} value => panic!("Expected Some(Normal), but got {:?}", value), } assert_eq!(wm_hints.icon_pixmap, None); assert_eq!(wm_hints.icon_window, None); assert_eq!(wm_hints.icon_position, None); assert_eq!(wm_hints.icon_mask, None); assert_eq!(wm_hints.window_group, Some(0x0060_0009)); assert_eq!(wm_hints.urgent, false); assert_eq!(input, wm_hints.serialize()); } } x11rb-0.8.1/src/protocol/bigreq.rs010064400017500001750000000107441402220031600151010ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `BigRequests` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "BIG-REQUESTS"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (0, 0); /// Opcode for the Enable request pub const ENABLE_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EnableRequest; impl EnableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, ENABLE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != ENABLE_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(EnableRequest ) } } impl Request for EnableRequest { type Reply = EnableReply; } pub fn enable(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = EnableRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EnableReply { pub sequence: u16, pub length: u32, pub maximum_request_length: u32, } impl TryParse for EnableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (maximum_request_length, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = EnableReply { sequence, length, maximum_request_length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn bigreq_enable(&self) -> Result, ConnectionError> { enable(self) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/composite.rs010064400017500001750000000756751402220031600156500ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Composite` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xfixes; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "Composite"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (0, 4); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Redirect(u8); impl Redirect { pub const AUTOMATIC: Self = Self(0); pub const MANUAL: Self = Self(1); } impl From for u8 { #[inline] fn from(input: Redirect) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Redirect) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Redirect) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Redirect) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Redirect) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Redirect) -> Self { Some(u32::from(input.0)) } } impl From for Redirect { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Redirect { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::AUTOMATIC.0.into(), "AUTOMATIC", "Automatic"), (Self::MANUAL.0.into(), "MANUAL", "Manual"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major_version: u32, pub client_minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_major_version_bytes[2], client_major_version_bytes[3], client_minor_version_bytes[0], client_minor_version_bytes[1], client_minor_version_bytes[2], client_minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u32::try_parse(value)?; let (client_minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major_version, client_minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the RedirectWindow request pub const REDIRECT_WINDOW_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct RedirectWindowRequest { pub window: xproto::Window, pub update: Redirect, } impl RedirectWindowRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let update_bytes = u8::from(self.update).serialize(); let mut request0 = vec![ extension_information.major_opcode, REDIRECT_WINDOW_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], update_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != REDIRECT_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (update, remaining) = u8::try_parse(remaining)?; let update = update.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(RedirectWindowRequest { window, update, }) } } impl Request for RedirectWindowRequest { type Reply = (); } pub fn redirect_window(conn: &Conn, window: xproto::Window, update: Redirect) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RedirectWindowRequest { window, update, }; request0.send(conn) } /// Opcode for the RedirectSubwindows request pub const REDIRECT_SUBWINDOWS_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct RedirectSubwindowsRequest { pub window: xproto::Window, pub update: Redirect, } impl RedirectSubwindowsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let update_bytes = u8::from(self.update).serialize(); let mut request0 = vec![ extension_information.major_opcode, REDIRECT_SUBWINDOWS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], update_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != REDIRECT_SUBWINDOWS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (update, remaining) = u8::try_parse(remaining)?; let update = update.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(RedirectSubwindowsRequest { window, update, }) } } impl Request for RedirectSubwindowsRequest { type Reply = (); } pub fn redirect_subwindows(conn: &Conn, window: xproto::Window, update: Redirect) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RedirectSubwindowsRequest { window, update, }; request0.send(conn) } /// Opcode for the UnredirectWindow request pub const UNREDIRECT_WINDOW_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UnredirectWindowRequest { pub window: xproto::Window, pub update: Redirect, } impl UnredirectWindowRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let update_bytes = u8::from(self.update).serialize(); let mut request0 = vec![ extension_information.major_opcode, UNREDIRECT_WINDOW_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], update_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNREDIRECT_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (update, remaining) = u8::try_parse(remaining)?; let update = update.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(UnredirectWindowRequest { window, update, }) } } impl Request for UnredirectWindowRequest { type Reply = (); } pub fn unredirect_window(conn: &Conn, window: xproto::Window, update: Redirect) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = UnredirectWindowRequest { window, update, }; request0.send(conn) } /// Opcode for the UnredirectSubwindows request pub const UNREDIRECT_SUBWINDOWS_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UnredirectSubwindowsRequest { pub window: xproto::Window, pub update: Redirect, } impl UnredirectSubwindowsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let update_bytes = u8::from(self.update).serialize(); let mut request0 = vec![ extension_information.major_opcode, UNREDIRECT_SUBWINDOWS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], update_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNREDIRECT_SUBWINDOWS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (update, remaining) = u8::try_parse(remaining)?; let update = update.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(UnredirectSubwindowsRequest { window, update, }) } } impl Request for UnredirectSubwindowsRequest { type Reply = (); } pub fn unredirect_subwindows(conn: &Conn, window: xproto::Window, update: Redirect) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = UnredirectSubwindowsRequest { window, update, }; request0.send(conn) } /// Opcode for the CreateRegionFromBorderClip request pub const CREATE_REGION_FROM_BORDER_CLIP_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateRegionFromBorderClipRequest { pub region: xfixes::Region, pub window: xproto::Window, } impl CreateRegionFromBorderClipRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_REGION_FROM_BORDER_CLIP_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_REGION_FROM_BORDER_CLIP_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = xfixes::Region::try_parse(value)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let _ = remaining; Ok(CreateRegionFromBorderClipRequest { region, window, }) } } impl Request for CreateRegionFromBorderClipRequest { type Reply = (); } pub fn create_region_from_border_clip(conn: &Conn, region: xfixes::Region, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRegionFromBorderClipRequest { region, window, }; request0.send(conn) } /// Opcode for the NameWindowPixmap request pub const NAME_WINDOW_PIXMAP_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NameWindowPixmapRequest { pub window: xproto::Window, pub pixmap: xproto::Pixmap, } impl NameWindowPixmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let pixmap_bytes = self.pixmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, NAME_WINDOW_PIXMAP_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], pixmap_bytes[0], pixmap_bytes[1], pixmap_bytes[2], pixmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != NAME_WINDOW_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (pixmap, remaining) = xproto::Pixmap::try_parse(remaining)?; let _ = remaining; Ok(NameWindowPixmapRequest { window, pixmap, }) } } impl Request for NameWindowPixmapRequest { type Reply = (); } pub fn name_window_pixmap(conn: &Conn, window: xproto::Window, pixmap: xproto::Pixmap) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = NameWindowPixmapRequest { window, pixmap, }; request0.send(conn) } /// Opcode for the GetOverlayWindow request pub const GET_OVERLAY_WINDOW_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetOverlayWindowRequest { pub window: xproto::Window, } impl GetOverlayWindowRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_OVERLAY_WINDOW_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_OVERLAY_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetOverlayWindowRequest { window, }) } } impl Request for GetOverlayWindowRequest { type Reply = GetOverlayWindowReply; } pub fn get_overlay_window(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetOverlayWindowRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetOverlayWindowReply { pub sequence: u16, pub length: u32, pub overlay_win: xproto::Window, } impl TryParse for GetOverlayWindowReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (overlay_win, remaining) = xproto::Window::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetOverlayWindowReply { sequence, length, overlay_win }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the ReleaseOverlayWindow request pub const RELEASE_OVERLAY_WINDOW_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ReleaseOverlayWindowRequest { pub window: xproto::Window, } impl ReleaseOverlayWindowRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, RELEASE_OVERLAY_WINDOW_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != RELEASE_OVERLAY_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(ReleaseOverlayWindowRequest { window, }) } } impl Request for ReleaseOverlayWindowRequest { type Reply = (); } pub fn release_overlay_window(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ReleaseOverlayWindowRequest { window, }; request0.send(conn) } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn composite_query_version(&self, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> { query_version(self, client_major_version, client_minor_version) } fn composite_redirect_window(&self, window: xproto::Window, update: Redirect) -> Result, ConnectionError> { redirect_window(self, window, update) } fn composite_redirect_subwindows(&self, window: xproto::Window, update: Redirect) -> Result, ConnectionError> { redirect_subwindows(self, window, update) } fn composite_unredirect_window(&self, window: xproto::Window, update: Redirect) -> Result, ConnectionError> { unredirect_window(self, window, update) } fn composite_unredirect_subwindows(&self, window: xproto::Window, update: Redirect) -> Result, ConnectionError> { unredirect_subwindows(self, window, update) } fn composite_create_region_from_border_clip(&self, region: xfixes::Region, window: xproto::Window) -> Result, ConnectionError> { create_region_from_border_clip(self, region, window) } fn composite_name_window_pixmap(&self, window: xproto::Window, pixmap: xproto::Pixmap) -> Result, ConnectionError> { name_window_pixmap(self, window, pixmap) } fn composite_get_overlay_window(&self, window: xproto::Window) -> Result, ConnectionError> { get_overlay_window(self, window) } fn composite_release_overlay_window(&self, window: xproto::Window) -> Result, ConnectionError> { release_overlay_window(self, window) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/damage.rs010064400017500001750000000537651402220031600150600ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Damage` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xfixes; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "DAMAGE"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 1); pub type Damage = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct ReportLevel(u8); impl ReportLevel { pub const RAW_RECTANGLES: Self = Self(0); pub const DELTA_RECTANGLES: Self = Self(1); pub const BOUNDING_BOX: Self = Self(2); pub const NON_EMPTY: Self = Self(3); } impl From for u8 { #[inline] fn from(input: ReportLevel) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ReportLevel) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ReportLevel) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ReportLevel) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ReportLevel) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ReportLevel) -> Self { Some(u32::from(input.0)) } } impl From for ReportLevel { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ReportLevel { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::RAW_RECTANGLES.0.into(), "RAW_RECTANGLES", "RawRectangles"), (Self::DELTA_RECTANGLES.0.into(), "DELTA_RECTANGLES", "DeltaRectangles"), (Self::BOUNDING_BOX.0.into(), "BOUNDING_BOX", "BoundingBox"), (Self::NON_EMPTY.0.into(), "NON_EMPTY", "NonEmpty"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the BadDamage error pub const BAD_DAMAGE_ERROR: u8 = 0; /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major_version: u32, pub client_minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_major_version_bytes[2], client_major_version_bytes[3], client_minor_version_bytes[0], client_minor_version_bytes[1], client_minor_version_bytes[2], client_minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u32::try_parse(value)?; let (client_minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major_version, client_minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Create request pub const CREATE_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateRequest { pub damage: Damage, pub drawable: xproto::Drawable, pub level: ReportLevel, } impl CreateRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let damage_bytes = self.damage.serialize(); let drawable_bytes = self.drawable.serialize(); let level_bytes = u8::from(self.level).serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_REQUEST, 0, 0, damage_bytes[0], damage_bytes[1], damage_bytes[2], damage_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], level_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_REQUEST { return Err(ParseError::InvalidValue); } let (damage, remaining) = Damage::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (level, remaining) = u8::try_parse(remaining)?; let level = level.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(CreateRequest { damage, drawable, level, }) } } impl Request for CreateRequest { type Reply = (); } pub fn create(conn: &Conn, damage: Damage, drawable: xproto::Drawable, level: ReportLevel) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRequest { damage, drawable, level, }; request0.send(conn) } /// Opcode for the Destroy request pub const DESTROY_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyRequest { pub damage: Damage, } impl DestroyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let damage_bytes = self.damage.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_REQUEST, 0, 0, damage_bytes[0], damage_bytes[1], damage_bytes[2], damage_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_REQUEST { return Err(ParseError::InvalidValue); } let (damage, remaining) = Damage::try_parse(value)?; let _ = remaining; Ok(DestroyRequest { damage, }) } } impl Request for DestroyRequest { type Reply = (); } pub fn destroy(conn: &Conn, damage: Damage) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyRequest { damage, }; request0.send(conn) } /// Opcode for the Subtract request pub const SUBTRACT_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SubtractRequest { pub damage: Damage, pub repair: xfixes::Region, pub parts: xfixes::Region, } impl SubtractRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let damage_bytes = self.damage.serialize(); let repair_bytes = self.repair.serialize(); let parts_bytes = self.parts.serialize(); let mut request0 = vec![ extension_information.major_opcode, SUBTRACT_REQUEST, 0, 0, damage_bytes[0], damage_bytes[1], damage_bytes[2], damage_bytes[3], repair_bytes[0], repair_bytes[1], repair_bytes[2], repair_bytes[3], parts_bytes[0], parts_bytes[1], parts_bytes[2], parts_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SUBTRACT_REQUEST { return Err(ParseError::InvalidValue); } let (damage, remaining) = Damage::try_parse(value)?; let (repair, remaining) = xfixes::Region::try_parse(remaining)?; let (parts, remaining) = xfixes::Region::try_parse(remaining)?; let _ = remaining; Ok(SubtractRequest { damage, repair, parts, }) } } impl Request for SubtractRequest { type Reply = (); } pub fn subtract(conn: &Conn, damage: Damage, repair: A, parts: B) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let repair: xfixes::Region = repair.into(); let parts: xfixes::Region = parts.into(); let request0 = SubtractRequest { damage, repair, parts, }; request0.send(conn) } /// Opcode for the Add request pub const ADD_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AddRequest { pub drawable: xproto::Drawable, pub region: xfixes::Region, } impl AddRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let region_bytes = self.region.serialize(); let mut request0 = vec![ extension_information.major_opcode, ADD_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != ADD_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (region, remaining) = xfixes::Region::try_parse(remaining)?; let _ = remaining; Ok(AddRequest { drawable, region, }) } } impl Request for AddRequest { type Reply = (); } pub fn add(conn: &Conn, drawable: xproto::Drawable, region: xfixes::Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AddRequest { drawable, region, }; request0.send(conn) } /// Opcode for the Notify event pub const NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NotifyEvent { pub response_type: u8, pub level: ReportLevel, pub sequence: u16, pub drawable: xproto::Drawable, pub damage: Damage, pub timestamp: xproto::Timestamp, pub area: xproto::Rectangle, pub geometry: xproto::Rectangle, } impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (level, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (damage, remaining) = Damage::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (area, remaining) = xproto::Rectangle::try_parse(remaining)?; let (geometry, remaining) = xproto::Rectangle::try_parse(remaining)?; let level = level.into(); let result = NotifyEvent { response_type, level, sequence, drawable, damage, timestamp, area, geometry }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NotifyEvent> for [u8; 32] { fn from(input: &NotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let level_bytes = u8::from(input.level).serialize(); let sequence_bytes = input.sequence.serialize(); let drawable_bytes = input.drawable.serialize(); let damage_bytes = input.damage.serialize(); let timestamp_bytes = input.timestamp.serialize(); let area_bytes = input.area.serialize(); let geometry_bytes = input.geometry.serialize(); [ response_type_bytes[0], level_bytes[0], sequence_bytes[0], sequence_bytes[1], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], damage_bytes[0], damage_bytes[1], damage_bytes[2], damage_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], area_bytes[0], area_bytes[1], area_bytes[2], area_bytes[3], area_bytes[4], area_bytes[5], area_bytes[6], area_bytes[7], geometry_bytes[0], geometry_bytes[1], geometry_bytes[2], geometry_bytes[3], geometry_bytes[4], geometry_bytes[5], geometry_bytes[6], geometry_bytes[7], ] } } impl From for [u8; 32] { fn from(input: NotifyEvent) -> Self { Self::from(&input) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn damage_query_version(&self, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> { query_version(self, client_major_version, client_minor_version) } fn damage_create(&self, damage: Damage, drawable: xproto::Drawable, level: ReportLevel) -> Result, ConnectionError> { create(self, damage, drawable, level) } fn damage_destroy(&self, damage: Damage) -> Result, ConnectionError> { destroy(self, damage) } fn damage_subtract(&self, damage: Damage, repair: A, parts: B) -> Result, ConnectionError> where A: Into, B: Into, { subtract(self, damage, repair, parts) } fn damage_add(&self, drawable: xproto::Drawable, region: xfixes::Region) -> Result, ConnectionError> { add(self, drawable, region) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/dpms.rs010064400017500001750000000642551402220031600146010ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `DPMS` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "DPMS"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (0, 0); /// Opcode for the GetVersion request pub const GET_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVersionRequest { pub client_major_version: u16, pub client_minor_version: u16, } impl GetVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_minor_version_bytes[0], client_minor_version_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u16::try_parse(value)?; let (client_minor_version, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(GetVersionRequest { client_major_version, client_minor_version, }) } } impl Request for GetVersionRequest { type Reply = GetVersionReply; } pub fn get_version(conn: &Conn, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVersionReply { pub sequence: u16, pub length: u32, pub server_major_version: u16, pub server_minor_version: u16, } impl TryParse for GetVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major_version, remaining) = u16::try_parse(remaining)?; let (server_minor_version, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetVersionReply { sequence, length, server_major_version, server_minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Capable request pub const CAPABLE_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CapableRequest; impl CapableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, CAPABLE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CAPABLE_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(CapableRequest ) } } impl Request for CapableRequest { type Reply = CapableReply; } pub fn capable(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CapableRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CapableReply { pub sequence: u16, pub length: u32, pub capable: bool, } impl TryParse for CapableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (capable, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CapableReply { sequence, length, capable }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetTimeouts request pub const GET_TIMEOUTS_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTimeoutsRequest; impl GetTimeoutsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_TIMEOUTS_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TIMEOUTS_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetTimeoutsRequest ) } } impl Request for GetTimeoutsRequest { type Reply = GetTimeoutsReply; } pub fn get_timeouts(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTimeoutsRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTimeoutsReply { pub sequence: u16, pub length: u32, pub standby_timeout: u16, pub suspend_timeout: u16, pub off_timeout: u16, } impl TryParse for GetTimeoutsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (standby_timeout, remaining) = u16::try_parse(remaining)?; let (suspend_timeout, remaining) = u16::try_parse(remaining)?; let (off_timeout, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(18..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTimeoutsReply { sequence, length, standby_timeout, suspend_timeout, off_timeout }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetTimeouts request pub const SET_TIMEOUTS_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetTimeoutsRequest { pub standby_timeout: u16, pub suspend_timeout: u16, pub off_timeout: u16, } impl SetTimeoutsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let standby_timeout_bytes = self.standby_timeout.serialize(); let suspend_timeout_bytes = self.suspend_timeout.serialize(); let off_timeout_bytes = self.off_timeout.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_TIMEOUTS_REQUEST, 0, 0, standby_timeout_bytes[0], standby_timeout_bytes[1], suspend_timeout_bytes[0], suspend_timeout_bytes[1], off_timeout_bytes[0], off_timeout_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_TIMEOUTS_REQUEST { return Err(ParseError::InvalidValue); } let (standby_timeout, remaining) = u16::try_parse(value)?; let (suspend_timeout, remaining) = u16::try_parse(remaining)?; let (off_timeout, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(SetTimeoutsRequest { standby_timeout, suspend_timeout, off_timeout, }) } } impl Request for SetTimeoutsRequest { type Reply = (); } pub fn set_timeouts(conn: &Conn, standby_timeout: u16, suspend_timeout: u16, off_timeout: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetTimeoutsRequest { standby_timeout, suspend_timeout, off_timeout, }; request0.send(conn) } /// Opcode for the Enable request pub const ENABLE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EnableRequest; impl EnableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, ENABLE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != ENABLE_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(EnableRequest ) } } impl Request for EnableRequest { type Reply = (); } pub fn enable(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = EnableRequest; request0.send(conn) } /// Opcode for the Disable request pub const DISABLE_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DisableRequest; impl DisableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, DISABLE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DISABLE_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(DisableRequest ) } } impl Request for DisableRequest { type Reply = (); } pub fn disable(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DisableRequest; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DPMSMode(u16); impl DPMSMode { pub const ON: Self = Self(0); pub const STANDBY: Self = Self(1); pub const SUSPEND: Self = Self(2); pub const OFF: Self = Self(3); } impl From for u16 { #[inline] fn from(input: DPMSMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DPMSMode) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: DPMSMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DPMSMode) -> Self { Some(u32::from(input.0)) } } impl From for DPMSMode { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for DPMSMode { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for DPMSMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ON.0.into(), "ON", "On"), (Self::STANDBY.0.into(), "STANDBY", "Standby"), (Self::SUSPEND.0.into(), "SUSPEND", "Suspend"), (Self::OFF.0.into(), "OFF", "Off"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the ForceLevel request pub const FORCE_LEVEL_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ForceLevelRequest { pub power_level: DPMSMode, } impl ForceLevelRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let power_level_bytes = u16::from(self.power_level).serialize(); let mut request0 = vec![ extension_information.major_opcode, FORCE_LEVEL_REQUEST, 0, 0, power_level_bytes[0], power_level_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FORCE_LEVEL_REQUEST { return Err(ParseError::InvalidValue); } let (power_level, remaining) = u16::try_parse(value)?; let power_level = power_level.into(); let _ = remaining; Ok(ForceLevelRequest { power_level, }) } } impl Request for ForceLevelRequest { type Reply = (); } pub fn force_level(conn: &Conn, power_level: DPMSMode) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ForceLevelRequest { power_level, }; request0.send(conn) } /// Opcode for the Info request pub const INFO_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InfoRequest; impl InfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, INFO_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != INFO_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(InfoRequest ) } } impl Request for InfoRequest { type Reply = InfoReply; } pub fn info(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = InfoRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InfoReply { pub sequence: u16, pub length: u32, pub power_level: DPMSMode, pub state: bool, } impl TryParse for InfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (power_level, remaining) = u16::try_parse(remaining)?; let (state, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(21..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let power_level = power_level.into(); let result = InfoReply { sequence, length, power_level, state }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn dpms_get_version(&self, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> { get_version(self, client_major_version, client_minor_version) } fn dpms_capable(&self) -> Result, ConnectionError> { capable(self) } fn dpms_get_timeouts(&self) -> Result, ConnectionError> { get_timeouts(self) } fn dpms_set_timeouts(&self, standby_timeout: u16, suspend_timeout: u16, off_timeout: u16) -> Result, ConnectionError> { set_timeouts(self, standby_timeout, suspend_timeout, off_timeout) } fn dpms_enable(&self) -> Result, ConnectionError> { enable(self) } fn dpms_disable(&self) -> Result, ConnectionError> { disable(self) } fn dpms_force_level(&self, power_level: DPMSMode) -> Result, ConnectionError> { force_level(self, power_level) } fn dpms_info(&self) -> Result, ConnectionError> { info(self) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/dri2.rs010064400017500001750000002311241402220031600144650ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `DRI2` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "DRI2"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 4); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Attachment(u32); impl Attachment { pub const BUFFER_FRONT_LEFT: Self = Self(0); pub const BUFFER_BACK_LEFT: Self = Self(1); pub const BUFFER_FRONT_RIGHT: Self = Self(2); pub const BUFFER_BACK_RIGHT: Self = Self(3); pub const BUFFER_DEPTH: Self = Self(4); pub const BUFFER_STENCIL: Self = Self(5); pub const BUFFER_ACCUM: Self = Self(6); pub const BUFFER_FAKE_FRONT_LEFT: Self = Self(7); pub const BUFFER_FAKE_FRONT_RIGHT: Self = Self(8); pub const BUFFER_DEPTH_STENCIL: Self = Self(9); pub const BUFFER_HIZ: Self = Self(10); } impl From for u32 { #[inline] fn from(input: Attachment) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Attachment) -> Self { Some(input.0) } } impl From for Attachment { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for Attachment { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for Attachment { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for Attachment { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::BUFFER_FRONT_LEFT.0, "BUFFER_FRONT_LEFT", "BufferFrontLeft"), (Self::BUFFER_BACK_LEFT.0, "BUFFER_BACK_LEFT", "BufferBackLeft"), (Self::BUFFER_FRONT_RIGHT.0, "BUFFER_FRONT_RIGHT", "BufferFrontRight"), (Self::BUFFER_BACK_RIGHT.0, "BUFFER_BACK_RIGHT", "BufferBackRight"), (Self::BUFFER_DEPTH.0, "BUFFER_DEPTH", "BufferDepth"), (Self::BUFFER_STENCIL.0, "BUFFER_STENCIL", "BufferStencil"), (Self::BUFFER_ACCUM.0, "BUFFER_ACCUM", "BufferAccum"), (Self::BUFFER_FAKE_FRONT_LEFT.0, "BUFFER_FAKE_FRONT_LEFT", "BufferFakeFrontLeft"), (Self::BUFFER_FAKE_FRONT_RIGHT.0, "BUFFER_FAKE_FRONT_RIGHT", "BufferFakeFrontRight"), (Self::BUFFER_DEPTH_STENCIL.0, "BUFFER_DEPTH_STENCIL", "BufferDepthStencil"), (Self::BUFFER_HIZ.0, "BUFFER_HIZ", "BufferHiz"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DriverType(u32); impl DriverType { pub const DRI: Self = Self(0); pub const VDPAU: Self = Self(1); } impl From for u32 { #[inline] fn from(input: DriverType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DriverType) -> Self { Some(input.0) } } impl From for DriverType { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for DriverType { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for DriverType { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for DriverType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DRI.0, "DRI", "DRI"), (Self::VDPAU.0, "VDPAU", "VDPAU"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct EventType(u16); impl EventType { pub const EXCHANGE_COMPLETE: Self = Self(1); pub const BLIT_COMPLETE: Self = Self(2); pub const FLIP_COMPLETE: Self = Self(3); } impl From for u16 { #[inline] fn from(input: EventType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: EventType) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: EventType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: EventType) -> Self { Some(u32::from(input.0)) } } impl From for EventType { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for EventType { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for EventType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::EXCHANGE_COMPLETE.0.into(), "EXCHANGE_COMPLETE", "ExchangeComplete"), (Self::BLIT_COMPLETE.0.into(), "BLIT_COMPLETE", "BlitComplete"), (Self::FLIP_COMPLETE.0.into(), "FLIP_COMPLETE", "FlipComplete"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DRI2Buffer { pub attachment: Attachment, pub name: u32, pub pitch: u32, pub cpp: u32, pub flags: u32, } impl TryParse for DRI2Buffer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (attachment, remaining) = u32::try_parse(remaining)?; let (name, remaining) = u32::try_parse(remaining)?; let (pitch, remaining) = u32::try_parse(remaining)?; let (cpp, remaining) = u32::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let attachment = attachment.into(); let result = DRI2Buffer { attachment, name, pitch, cpp, flags }; Ok((result, remaining)) } } impl Serialize for DRI2Buffer { type Bytes = [u8; 20]; fn serialize(&self) -> [u8; 20] { let attachment_bytes = u32::from(self.attachment).serialize(); let name_bytes = self.name.serialize(); let pitch_bytes = self.pitch.serialize(); let cpp_bytes = self.cpp.serialize(); let flags_bytes = self.flags.serialize(); [ attachment_bytes[0], attachment_bytes[1], attachment_bytes[2], attachment_bytes[3], name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3], pitch_bytes[0], pitch_bytes[1], pitch_bytes[2], pitch_bytes[3], cpp_bytes[0], cpp_bytes[1], cpp_bytes[2], cpp_bytes[3], flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(20); u32::from(self.attachment).serialize_into(bytes); self.name.serialize_into(bytes); self.pitch.serialize_into(bytes); self.cpp.serialize_into(bytes); self.flags.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AttachFormat { pub attachment: Attachment, pub format: u32, } impl TryParse for AttachFormat { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (attachment, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let attachment = attachment.into(); let result = AttachFormat { attachment, format }; Ok((result, remaining)) } } impl Serialize for AttachFormat { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let attachment_bytes = u32::from(self.attachment).serialize(); let format_bytes = self.format.serialize(); [ attachment_bytes[0], attachment_bytes[1], attachment_bytes[2], attachment_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u32::from(self.attachment).serialize_into(bytes); self.format.serialize_into(bytes); } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub major_version: u32, pub minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], major_version_bytes[2], major_version_bytes[3], minor_version_bytes[0], minor_version_bytes[1], minor_version_bytes[2], minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u32::try_parse(value)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { major_version, minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, major_version: u32, minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { major_version, minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Connect request pub const CONNECT_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ConnectRequest { pub window: xproto::Window, pub driver_type: DriverType, } impl ConnectRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let driver_type_bytes = u32::from(self.driver_type).serialize(); let mut request0 = vec![ extension_information.major_opcode, CONNECT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], driver_type_bytes[0], driver_type_bytes[1], driver_type_bytes[2], driver_type_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CONNECT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (driver_type, remaining) = u32::try_parse(remaining)?; let driver_type = driver_type.into(); let _ = remaining; Ok(ConnectRequest { window, driver_type, }) } } impl Request for ConnectRequest { type Reply = ConnectReply; } pub fn connect(conn: &Conn, window: xproto::Window, driver_type: DriverType) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ConnectRequest { window, driver_type, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConnectReply { pub sequence: u16, pub length: u32, pub driver_name: Vec, pub alignment_pad: Vec, pub device_name: Vec, } impl TryParse for ConnectReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (driver_name_length, remaining) = u32::try_parse(remaining)?; let (device_name_length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (driver_name, remaining) = crate::x11_utils::parse_u8_list(remaining, driver_name_length.try_to_usize()?)?; let driver_name = driver_name.to_vec(); let (alignment_pad, remaining) = crate::x11_utils::parse_u8_list(remaining, (driver_name_length.checked_add(3u32).ok_or(ParseError::InvalidExpression)? & (!3u32)).checked_sub(driver_name_length).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let alignment_pad = alignment_pad.to_vec(); let (device_name, remaining) = crate::x11_utils::parse_u8_list(remaining, device_name_length.try_to_usize()?)?; let device_name = device_name.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ConnectReply { sequence, length, driver_name, alignment_pad, device_name }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ConnectReply { /// Get the value of the `driver_name_length` field. /// /// The `driver_name_length` field is used as the length field of the `driver_name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn driver_name_length(&self) -> u32 { self.driver_name.len() .try_into().unwrap() } /// Get the value of the `device_name_length` field. /// /// The `device_name_length` field is used as the length field of the `device_name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn device_name_length(&self) -> u32 { self.device_name.len() .try_into().unwrap() } } /// Opcode for the Authenticate request pub const AUTHENTICATE_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AuthenticateRequest { pub window: xproto::Window, pub magic: u32, } impl AuthenticateRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let magic_bytes = self.magic.serialize(); let mut request0 = vec![ extension_information.major_opcode, AUTHENTICATE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], magic_bytes[0], magic_bytes[1], magic_bytes[2], magic_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != AUTHENTICATE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (magic, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(AuthenticateRequest { window, magic, }) } } impl Request for AuthenticateRequest { type Reply = AuthenticateReply; } pub fn authenticate(conn: &Conn, window: xproto::Window, magic: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AuthenticateRequest { window, magic, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AuthenticateReply { pub sequence: u16, pub length: u32, pub authenticated: u32, } impl TryParse for AuthenticateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (authenticated, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = AuthenticateReply { sequence, length, authenticated }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the CreateDrawable request pub const CREATE_DRAWABLE_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateDrawableRequest { pub drawable: xproto::Drawable, } impl CreateDrawableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_DRAWABLE_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_DRAWABLE_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let _ = remaining; Ok(CreateDrawableRequest { drawable, }) } } impl Request for CreateDrawableRequest { type Reply = (); } pub fn create_drawable(conn: &Conn, drawable: xproto::Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateDrawableRequest { drawable, }; request0.send(conn) } /// Opcode for the DestroyDrawable request pub const DESTROY_DRAWABLE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyDrawableRequest { pub drawable: xproto::Drawable, } impl DestroyDrawableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_DRAWABLE_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_DRAWABLE_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let _ = remaining; Ok(DestroyDrawableRequest { drawable, }) } } impl Request for DestroyDrawableRequest { type Reply = (); } pub fn destroy_drawable(conn: &Conn, drawable: xproto::Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyDrawableRequest { drawable, }; request0.send(conn) } /// Opcode for the GetBuffers request pub const GET_BUFFERS_REQUEST: u8 = 5; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetBuffersRequest<'input> { pub drawable: xproto::Drawable, pub count: u32, pub attachments: Cow<'input, [u32]>, } impl<'input> GetBuffersRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let count_bytes = self.count.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_BUFFERS_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], count_bytes[0], count_bytes[1], count_bytes[2], count_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let attachments_bytes = self.attachments.serialize(); let length_so_far = length_so_far + attachments_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), attachments_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != GET_BUFFERS_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (count, remaining) = u32::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut attachments = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = u32::try_parse(remaining)?; remaining = new_remaining; attachments.push(v); } let _ = remaining; Ok(GetBuffersRequest { drawable, count, attachments: Cow::Owned(attachments), }) } /// Clone all borrowed data in this GetBuffersRequest. pub fn into_owned(self) -> GetBuffersRequest<'static> { GetBuffersRequest { drawable: self.drawable, count: self.count, attachments: Cow::Owned(self.attachments.into_owned()), } } } impl<'input> Request for GetBuffersRequest<'input> { type Reply = GetBuffersReply; } pub fn get_buffers<'c, 'input, Conn>(conn: &'c Conn, drawable: xproto::Drawable, count: u32, attachments: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetBuffersRequest { drawable, count, attachments: Cow::Borrowed(attachments), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetBuffersReply { pub sequence: u16, pub length: u32, pub width: u32, pub height: u32, pub buffers: Vec, } impl TryParse for GetBuffersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u32::try_parse(remaining)?; let (height, remaining) = u32::try_parse(remaining)?; let (count, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (buffers, remaining) = crate::x11_utils::parse_list::(remaining, count.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetBuffersReply { sequence, length, width, height, buffers }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetBuffersReply { /// Get the value of the `count` field. /// /// The `count` field is used as the length field of the `buffers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn count(&self) -> u32 { self.buffers.len() .try_into().unwrap() } } /// Opcode for the CopyRegion request pub const COPY_REGION_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CopyRegionRequest { pub drawable: xproto::Drawable, pub region: u32, pub dest: u32, pub src: u32, } impl CopyRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let region_bytes = self.region.serialize(); let dest_bytes = self.dest.serialize(); let src_bytes = self.src.serialize(); let mut request0 = vec![ extension_information.major_opcode, COPY_REGION_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], dest_bytes[0], dest_bytes[1], dest_bytes[2], dest_bytes[3], src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != COPY_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (region, remaining) = u32::try_parse(remaining)?; let (dest, remaining) = u32::try_parse(remaining)?; let (src, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(CopyRegionRequest { drawable, region, dest, src, }) } } impl Request for CopyRegionRequest { type Reply = CopyRegionReply; } pub fn copy_region(conn: &Conn, drawable: xproto::Drawable, region: u32, dest: u32, src: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CopyRegionRequest { drawable, region, dest, src, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CopyRegionReply { pub sequence: u16, pub length: u32, } impl TryParse for CopyRegionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CopyRegionReply { sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetBuffersWithFormat request pub const GET_BUFFERS_WITH_FORMAT_REQUEST: u8 = 7; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetBuffersWithFormatRequest<'input> { pub drawable: xproto::Drawable, pub count: u32, pub attachments: Cow<'input, [AttachFormat]>, } impl<'input> GetBuffersWithFormatRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let count_bytes = self.count.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_BUFFERS_WITH_FORMAT_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], count_bytes[0], count_bytes[1], count_bytes[2], count_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let attachments_bytes = self.attachments.serialize(); let length_so_far = length_so_far + attachments_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), attachments_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != GET_BUFFERS_WITH_FORMAT_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (count, remaining) = u32::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut attachments = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = AttachFormat::try_parse(remaining)?; remaining = new_remaining; attachments.push(v); } let _ = remaining; Ok(GetBuffersWithFormatRequest { drawable, count, attachments: Cow::Owned(attachments), }) } /// Clone all borrowed data in this GetBuffersWithFormatRequest. pub fn into_owned(self) -> GetBuffersWithFormatRequest<'static> { GetBuffersWithFormatRequest { drawable: self.drawable, count: self.count, attachments: Cow::Owned(self.attachments.into_owned()), } } } impl<'input> Request for GetBuffersWithFormatRequest<'input> { type Reply = GetBuffersWithFormatReply; } pub fn get_buffers_with_format<'c, 'input, Conn>(conn: &'c Conn, drawable: xproto::Drawable, count: u32, attachments: &'input [AttachFormat]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetBuffersWithFormatRequest { drawable, count, attachments: Cow::Borrowed(attachments), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetBuffersWithFormatReply { pub sequence: u16, pub length: u32, pub width: u32, pub height: u32, pub buffers: Vec, } impl TryParse for GetBuffersWithFormatReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u32::try_parse(remaining)?; let (height, remaining) = u32::try_parse(remaining)?; let (count, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (buffers, remaining) = crate::x11_utils::parse_list::(remaining, count.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetBuffersWithFormatReply { sequence, length, width, height, buffers }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetBuffersWithFormatReply { /// Get the value of the `count` field. /// /// The `count` field is used as the length field of the `buffers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn count(&self) -> u32 { self.buffers.len() .try_into().unwrap() } } /// Opcode for the SwapBuffers request pub const SWAP_BUFFERS_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SwapBuffersRequest { pub drawable: xproto::Drawable, pub target_msc_hi: u32, pub target_msc_lo: u32, pub divisor_hi: u32, pub divisor_lo: u32, pub remainder_hi: u32, pub remainder_lo: u32, } impl SwapBuffersRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let target_msc_hi_bytes = self.target_msc_hi.serialize(); let target_msc_lo_bytes = self.target_msc_lo.serialize(); let divisor_hi_bytes = self.divisor_hi.serialize(); let divisor_lo_bytes = self.divisor_lo.serialize(); let remainder_hi_bytes = self.remainder_hi.serialize(); let remainder_lo_bytes = self.remainder_lo.serialize(); let mut request0 = vec![ extension_information.major_opcode, SWAP_BUFFERS_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], target_msc_hi_bytes[0], target_msc_hi_bytes[1], target_msc_hi_bytes[2], target_msc_hi_bytes[3], target_msc_lo_bytes[0], target_msc_lo_bytes[1], target_msc_lo_bytes[2], target_msc_lo_bytes[3], divisor_hi_bytes[0], divisor_hi_bytes[1], divisor_hi_bytes[2], divisor_hi_bytes[3], divisor_lo_bytes[0], divisor_lo_bytes[1], divisor_lo_bytes[2], divisor_lo_bytes[3], remainder_hi_bytes[0], remainder_hi_bytes[1], remainder_hi_bytes[2], remainder_hi_bytes[3], remainder_lo_bytes[0], remainder_lo_bytes[1], remainder_lo_bytes[2], remainder_lo_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SWAP_BUFFERS_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (target_msc_hi, remaining) = u32::try_parse(remaining)?; let (target_msc_lo, remaining) = u32::try_parse(remaining)?; let (divisor_hi, remaining) = u32::try_parse(remaining)?; let (divisor_lo, remaining) = u32::try_parse(remaining)?; let (remainder_hi, remaining) = u32::try_parse(remaining)?; let (remainder_lo, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SwapBuffersRequest { drawable, target_msc_hi, target_msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo, }) } } impl Request for SwapBuffersRequest { type Reply = SwapBuffersReply; } pub fn swap_buffers(conn: &Conn, drawable: xproto::Drawable, target_msc_hi: u32, target_msc_lo: u32, divisor_hi: u32, divisor_lo: u32, remainder_hi: u32, remainder_lo: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SwapBuffersRequest { drawable, target_msc_hi, target_msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SwapBuffersReply { pub sequence: u16, pub length: u32, pub swap_hi: u32, pub swap_lo: u32, } impl TryParse for SwapBuffersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (swap_hi, remaining) = u32::try_parse(remaining)?; let (swap_lo, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = SwapBuffersReply { sequence, length, swap_hi, swap_lo }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetMSC request pub const GET_MSC_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMSCRequest { pub drawable: xproto::Drawable, } impl GetMSCRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MSC_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MSC_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let _ = remaining; Ok(GetMSCRequest { drawable, }) } } impl Request for GetMSCRequest { type Reply = GetMSCReply; } pub fn get_msc(conn: &Conn, drawable: xproto::Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMSCRequest { drawable, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMSCReply { pub sequence: u16, pub length: u32, pub ust_hi: u32, pub ust_lo: u32, pub msc_hi: u32, pub msc_lo: u32, pub sbc_hi: u32, pub sbc_lo: u32, } impl TryParse for GetMSCReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ust_hi, remaining) = u32::try_parse(remaining)?; let (ust_lo, remaining) = u32::try_parse(remaining)?; let (msc_hi, remaining) = u32::try_parse(remaining)?; let (msc_lo, remaining) = u32::try_parse(remaining)?; let (sbc_hi, remaining) = u32::try_parse(remaining)?; let (sbc_lo, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMSCReply { sequence, length, ust_hi, ust_lo, msc_hi, msc_lo, sbc_hi, sbc_lo }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the WaitMSC request pub const WAIT_MSC_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct WaitMSCRequest { pub drawable: xproto::Drawable, pub target_msc_hi: u32, pub target_msc_lo: u32, pub divisor_hi: u32, pub divisor_lo: u32, pub remainder_hi: u32, pub remainder_lo: u32, } impl WaitMSCRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let target_msc_hi_bytes = self.target_msc_hi.serialize(); let target_msc_lo_bytes = self.target_msc_lo.serialize(); let divisor_hi_bytes = self.divisor_hi.serialize(); let divisor_lo_bytes = self.divisor_lo.serialize(); let remainder_hi_bytes = self.remainder_hi.serialize(); let remainder_lo_bytes = self.remainder_lo.serialize(); let mut request0 = vec![ extension_information.major_opcode, WAIT_MSC_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], target_msc_hi_bytes[0], target_msc_hi_bytes[1], target_msc_hi_bytes[2], target_msc_hi_bytes[3], target_msc_lo_bytes[0], target_msc_lo_bytes[1], target_msc_lo_bytes[2], target_msc_lo_bytes[3], divisor_hi_bytes[0], divisor_hi_bytes[1], divisor_hi_bytes[2], divisor_hi_bytes[3], divisor_lo_bytes[0], divisor_lo_bytes[1], divisor_lo_bytes[2], divisor_lo_bytes[3], remainder_hi_bytes[0], remainder_hi_bytes[1], remainder_hi_bytes[2], remainder_hi_bytes[3], remainder_lo_bytes[0], remainder_lo_bytes[1], remainder_lo_bytes[2], remainder_lo_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != WAIT_MSC_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (target_msc_hi, remaining) = u32::try_parse(remaining)?; let (target_msc_lo, remaining) = u32::try_parse(remaining)?; let (divisor_hi, remaining) = u32::try_parse(remaining)?; let (divisor_lo, remaining) = u32::try_parse(remaining)?; let (remainder_hi, remaining) = u32::try_parse(remaining)?; let (remainder_lo, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(WaitMSCRequest { drawable, target_msc_hi, target_msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo, }) } } impl Request for WaitMSCRequest { type Reply = WaitMSCReply; } pub fn wait_msc(conn: &Conn, drawable: xproto::Drawable, target_msc_hi: u32, target_msc_lo: u32, divisor_hi: u32, divisor_lo: u32, remainder_hi: u32, remainder_lo: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = WaitMSCRequest { drawable, target_msc_hi, target_msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct WaitMSCReply { pub sequence: u16, pub length: u32, pub ust_hi: u32, pub ust_lo: u32, pub msc_hi: u32, pub msc_lo: u32, pub sbc_hi: u32, pub sbc_lo: u32, } impl TryParse for WaitMSCReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ust_hi, remaining) = u32::try_parse(remaining)?; let (ust_lo, remaining) = u32::try_parse(remaining)?; let (msc_hi, remaining) = u32::try_parse(remaining)?; let (msc_lo, remaining) = u32::try_parse(remaining)?; let (sbc_hi, remaining) = u32::try_parse(remaining)?; let (sbc_lo, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = WaitMSCReply { sequence, length, ust_hi, ust_lo, msc_hi, msc_lo, sbc_hi, sbc_lo }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the WaitSBC request pub const WAIT_SBC_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct WaitSBCRequest { pub drawable: xproto::Drawable, pub target_sbc_hi: u32, pub target_sbc_lo: u32, } impl WaitSBCRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let target_sbc_hi_bytes = self.target_sbc_hi.serialize(); let target_sbc_lo_bytes = self.target_sbc_lo.serialize(); let mut request0 = vec![ extension_information.major_opcode, WAIT_SBC_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], target_sbc_hi_bytes[0], target_sbc_hi_bytes[1], target_sbc_hi_bytes[2], target_sbc_hi_bytes[3], target_sbc_lo_bytes[0], target_sbc_lo_bytes[1], target_sbc_lo_bytes[2], target_sbc_lo_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != WAIT_SBC_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (target_sbc_hi, remaining) = u32::try_parse(remaining)?; let (target_sbc_lo, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(WaitSBCRequest { drawable, target_sbc_hi, target_sbc_lo, }) } } impl Request for WaitSBCRequest { type Reply = WaitSBCReply; } pub fn wait_sbc(conn: &Conn, drawable: xproto::Drawable, target_sbc_hi: u32, target_sbc_lo: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = WaitSBCRequest { drawable, target_sbc_hi, target_sbc_lo, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct WaitSBCReply { pub sequence: u16, pub length: u32, pub ust_hi: u32, pub ust_lo: u32, pub msc_hi: u32, pub msc_lo: u32, pub sbc_hi: u32, pub sbc_lo: u32, } impl TryParse for WaitSBCReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ust_hi, remaining) = u32::try_parse(remaining)?; let (ust_lo, remaining) = u32::try_parse(remaining)?; let (msc_hi, remaining) = u32::try_parse(remaining)?; let (msc_lo, remaining) = u32::try_parse(remaining)?; let (sbc_hi, remaining) = u32::try_parse(remaining)?; let (sbc_lo, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = WaitSBCReply { sequence, length, ust_hi, ust_lo, msc_hi, msc_lo, sbc_hi, sbc_lo }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SwapInterval request pub const SWAP_INTERVAL_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SwapIntervalRequest { pub drawable: xproto::Drawable, pub interval: u32, } impl SwapIntervalRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let interval_bytes = self.interval.serialize(); let mut request0 = vec![ extension_information.major_opcode, SWAP_INTERVAL_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], interval_bytes[0], interval_bytes[1], interval_bytes[2], interval_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SWAP_INTERVAL_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (interval, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SwapIntervalRequest { drawable, interval, }) } } impl Request for SwapIntervalRequest { type Reply = (); } pub fn swap_interval(conn: &Conn, drawable: xproto::Drawable, interval: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SwapIntervalRequest { drawable, interval, }; request0.send(conn) } /// Opcode for the GetParam request pub const GET_PARAM_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetParamRequest { pub drawable: xproto::Drawable, pub param: u32, } impl GetParamRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let param_bytes = self.param.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PARAM_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], param_bytes[0], param_bytes[1], param_bytes[2], param_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PARAM_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (param, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetParamRequest { drawable, param, }) } } impl Request for GetParamRequest { type Reply = GetParamReply; } pub fn get_param(conn: &Conn, drawable: xproto::Drawable, param: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetParamRequest { drawable, param, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetParamReply { pub is_param_recognized: bool, pub sequence: u16, pub length: u32, pub value_hi: u32, pub value_lo: u32, } impl TryParse for GetParamReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (is_param_recognized, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (value_hi, remaining) = u32::try_parse(remaining)?; let (value_lo, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetParamReply { is_param_recognized, sequence, length, value_hi, value_lo }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the BufferSwapComplete event pub const BUFFER_SWAP_COMPLETE_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BufferSwapCompleteEvent { pub response_type: u8, pub sequence: u16, pub event_type: EventType, pub drawable: xproto::Drawable, pub ust_hi: u32, pub ust_lo: u32, pub msc_hi: u32, pub msc_lo: u32, pub sbc: u32, } impl TryParse for BufferSwapCompleteEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (ust_hi, remaining) = u32::try_parse(remaining)?; let (ust_lo, remaining) = u32::try_parse(remaining)?; let (msc_hi, remaining) = u32::try_parse(remaining)?; let (msc_lo, remaining) = u32::try_parse(remaining)?; let (sbc, remaining) = u32::try_parse(remaining)?; let event_type = event_type.into(); let result = BufferSwapCompleteEvent { response_type, sequence, event_type, drawable, ust_hi, ust_lo, msc_hi, msc_lo, sbc }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&BufferSwapCompleteEvent> for [u8; 32] { fn from(input: &BufferSwapCompleteEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_type_bytes = u16::from(input.event_type).serialize(); let drawable_bytes = input.drawable.serialize(); let ust_hi_bytes = input.ust_hi.serialize(); let ust_lo_bytes = input.ust_lo.serialize(); let msc_hi_bytes = input.msc_hi.serialize(); let msc_lo_bytes = input.msc_lo.serialize(); let sbc_bytes = input.sbc.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_type_bytes[0], event_type_bytes[1], 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ust_hi_bytes[0], ust_hi_bytes[1], ust_hi_bytes[2], ust_hi_bytes[3], ust_lo_bytes[0], ust_lo_bytes[1], ust_lo_bytes[2], ust_lo_bytes[3], msc_hi_bytes[0], msc_hi_bytes[1], msc_hi_bytes[2], msc_hi_bytes[3], msc_lo_bytes[0], msc_lo_bytes[1], msc_lo_bytes[2], msc_lo_bytes[3], sbc_bytes[0], sbc_bytes[1], sbc_bytes[2], sbc_bytes[3], ] } } impl From for [u8; 32] { fn from(input: BufferSwapCompleteEvent) -> Self { Self::from(&input) } } /// Opcode for the InvalidateBuffers event pub const INVALIDATE_BUFFERS_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InvalidateBuffersEvent { pub response_type: u8, pub sequence: u16, pub drawable: xproto::Drawable, } impl TryParse for InvalidateBuffersEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let result = InvalidateBuffersEvent { response_type, sequence, drawable }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&InvalidateBuffersEvent> for [u8; 32] { fn from(input: &InvalidateBuffersEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let drawable_bytes = input.drawable.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: InvalidateBuffersEvent) -> Self { Self::from(&input) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn dri2_query_version(&self, major_version: u32, minor_version: u32) -> Result, ConnectionError> { query_version(self, major_version, minor_version) } fn dri2_connect(&self, window: xproto::Window, driver_type: DriverType) -> Result, ConnectionError> { connect(self, window, driver_type) } fn dri2_authenticate(&self, window: xproto::Window, magic: u32) -> Result, ConnectionError> { authenticate(self, window, magic) } fn dri2_create_drawable(&self, drawable: xproto::Drawable) -> Result, ConnectionError> { create_drawable(self, drawable) } fn dri2_destroy_drawable(&self, drawable: xproto::Drawable) -> Result, ConnectionError> { destroy_drawable(self, drawable) } fn dri2_get_buffers<'c, 'input>(&'c self, drawable: xproto::Drawable, count: u32, attachments: &'input [u32]) -> Result, ConnectionError> { get_buffers(self, drawable, count, attachments) } fn dri2_copy_region(&self, drawable: xproto::Drawable, region: u32, dest: u32, src: u32) -> Result, ConnectionError> { copy_region(self, drawable, region, dest, src) } fn dri2_get_buffers_with_format<'c, 'input>(&'c self, drawable: xproto::Drawable, count: u32, attachments: &'input [AttachFormat]) -> Result, ConnectionError> { get_buffers_with_format(self, drawable, count, attachments) } fn dri2_swap_buffers(&self, drawable: xproto::Drawable, target_msc_hi: u32, target_msc_lo: u32, divisor_hi: u32, divisor_lo: u32, remainder_hi: u32, remainder_lo: u32) -> Result, ConnectionError> { swap_buffers(self, drawable, target_msc_hi, target_msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo) } fn dri2_get_msc(&self, drawable: xproto::Drawable) -> Result, ConnectionError> { get_msc(self, drawable) } fn dri2_wait_msc(&self, drawable: xproto::Drawable, target_msc_hi: u32, target_msc_lo: u32, divisor_hi: u32, divisor_lo: u32, remainder_hi: u32, remainder_lo: u32) -> Result, ConnectionError> { wait_msc(self, drawable, target_msc_hi, target_msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo) } fn dri2_wait_sbc(&self, drawable: xproto::Drawable, target_sbc_hi: u32, target_sbc_lo: u32) -> Result, ConnectionError> { wait_sbc(self, drawable, target_sbc_hi, target_sbc_lo) } fn dri2_swap_interval(&self, drawable: xproto::Drawable, interval: u32) -> Result, ConnectionError> { swap_interval(self, drawable, interval) } fn dri2_get_param(&self, drawable: xproto::Drawable, param: u32) -> Result, ConnectionError> { get_param(self, drawable, param) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/dri3.rs010064400017500001750000001313731402220031600144730ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `DRI3` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "DRI3"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 2); /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub major_version: u32, pub minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], major_version_bytes[2], major_version_bytes[3], minor_version_bytes[0], minor_version_bytes[1], minor_version_bytes[2], minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u32::try_parse(value)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { major_version, minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, major_version: u32, minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { major_version, minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Open request pub const OPEN_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OpenRequest { pub drawable: xproto::Drawable, pub provider: u32, } impl OpenRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let provider_bytes = self.provider.serialize(); let mut request0 = vec![ extension_information.major_opcode, OPEN_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply_with_fds(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != OPEN_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (provider, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(OpenRequest { drawable, provider, }) } } impl Request for OpenRequest { type Reply = OpenReply; } pub fn open(conn: &Conn, drawable: xproto::Drawable, provider: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = OpenRequest { drawable, provider, }; request0.send(conn) } #[derive(Debug, PartialEq, Eq)] pub struct OpenReply { pub nfd: u8, pub sequence: u16, pub length: u32, pub device_fd: RawFdContainer, } impl TryParseFd for OpenReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let device_fd = fds.remove(0); let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = OpenReply { nfd, sequence, length, device_fd }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PixmapFromBuffer request pub const PIXMAP_FROM_BUFFER_REQUEST: u8 = 2; #[derive(Debug, PartialEq, Eq)] pub struct PixmapFromBufferRequest { pub pixmap: xproto::Pixmap, pub drawable: xproto::Drawable, pub size: u32, pub width: u16, pub height: u16, pub stride: u16, pub depth: u8, pub bpp: u8, pub pixmap_fd: RawFdContainer, } impl PixmapFromBufferRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let pixmap_bytes = self.pixmap.serialize(); let drawable_bytes = self.drawable.serialize(); let size_bytes = self.size.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let stride_bytes = self.stride.serialize(); let depth_bytes = self.depth.serialize(); let bpp_bytes = self.bpp.serialize(); let mut request0 = vec![ extension_information.major_opcode, PIXMAP_FROM_BUFFER_REQUEST, 0, 0, pixmap_bytes[0], pixmap_bytes[1], pixmap_bytes[2], pixmap_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], size_bytes[0], size_bytes[1], size_bytes[2], size_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], stride_bytes[0], stride_bytes[1], depth_bytes[0], bpp_bytes[0], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![self.pixmap_fd])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request_fd(header: RequestHeader, value: &[u8], fds: &mut Vec) -> Result { if header.minor_opcode != PIXMAP_FROM_BUFFER_REQUEST { return Err(ParseError::InvalidValue); } let (pixmap, remaining) = xproto::Pixmap::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (size, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (stride, remaining) = u16::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (bpp, remaining) = u8::try_parse(remaining)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let pixmap_fd = fds.remove(0); let _ = remaining; Ok(PixmapFromBufferRequest { pixmap, drawable, size, width, height, stride, depth, bpp, pixmap_fd, }) } } impl Request for PixmapFromBufferRequest { type Reply = (); } pub fn pixmap_from_buffer(conn: &Conn, pixmap: xproto::Pixmap, drawable: xproto::Drawable, size: u32, width: u16, height: u16, stride: u16, depth: u8, bpp: u8, pixmap_fd: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let pixmap_fd: RawFdContainer = pixmap_fd.into(); let request0 = PixmapFromBufferRequest { pixmap, drawable, size, width, height, stride, depth, bpp, pixmap_fd, }; request0.send(conn) } /// Opcode for the BufferFromPixmap request pub const BUFFER_FROM_PIXMAP_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BufferFromPixmapRequest { pub pixmap: xproto::Pixmap, } impl BufferFromPixmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let pixmap_bytes = self.pixmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, BUFFER_FROM_PIXMAP_REQUEST, 0, 0, pixmap_bytes[0], pixmap_bytes[1], pixmap_bytes[2], pixmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply_with_fds(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != BUFFER_FROM_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (pixmap, remaining) = xproto::Pixmap::try_parse(value)?; let _ = remaining; Ok(BufferFromPixmapRequest { pixmap, }) } } impl Request for BufferFromPixmapRequest { type Reply = BufferFromPixmapReply; } pub fn buffer_from_pixmap(conn: &Conn, pixmap: xproto::Pixmap) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = BufferFromPixmapRequest { pixmap, }; request0.send(conn) } #[derive(Debug, PartialEq, Eq)] pub struct BufferFromPixmapReply { pub nfd: u8, pub sequence: u16, pub length: u32, pub size: u32, pub width: u16, pub height: u16, pub stride: u16, pub depth: u8, pub bpp: u8, pub pixmap_fd: RawFdContainer, } impl TryParseFd for BufferFromPixmapReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (size, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (stride, remaining) = u16::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (bpp, remaining) = u8::try_parse(remaining)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let pixmap_fd = fds.remove(0); let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = BufferFromPixmapReply { nfd, sequence, length, size, width, height, stride, depth, bpp, pixmap_fd }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the FenceFromFD request pub const FENCE_FROM_FD_REQUEST: u8 = 4; #[derive(Debug, PartialEq, Eq)] pub struct FenceFromFDRequest { pub drawable: xproto::Drawable, pub fence: u32, pub initially_triggered: bool, pub fence_fd: RawFdContainer, } impl FenceFromFDRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let fence_bytes = self.fence.serialize(); let initially_triggered_bytes = self.initially_triggered.serialize(); let mut request0 = vec![ extension_information.major_opcode, FENCE_FROM_FD_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], fence_bytes[0], fence_bytes[1], fence_bytes[2], fence_bytes[3], initially_triggered_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![self.fence_fd])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request_fd(header: RequestHeader, value: &[u8], fds: &mut Vec) -> Result { if header.minor_opcode != FENCE_FROM_FD_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (fence, remaining) = u32::try_parse(remaining)?; let (initially_triggered, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let fence_fd = fds.remove(0); let _ = remaining; Ok(FenceFromFDRequest { drawable, fence, initially_triggered, fence_fd, }) } } impl Request for FenceFromFDRequest { type Reply = (); } pub fn fence_from_fd(conn: &Conn, drawable: xproto::Drawable, fence: u32, initially_triggered: bool, fence_fd: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let fence_fd: RawFdContainer = fence_fd.into(); let request0 = FenceFromFDRequest { drawable, fence, initially_triggered, fence_fd, }; request0.send(conn) } /// Opcode for the FDFromFence request pub const FD_FROM_FENCE_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FDFromFenceRequest { pub drawable: xproto::Drawable, pub fence: u32, } impl FDFromFenceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let fence_bytes = self.fence.serialize(); let mut request0 = vec![ extension_information.major_opcode, FD_FROM_FENCE_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], fence_bytes[0], fence_bytes[1], fence_bytes[2], fence_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply_with_fds(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FD_FROM_FENCE_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (fence, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(FDFromFenceRequest { drawable, fence, }) } } impl Request for FDFromFenceRequest { type Reply = FDFromFenceReply; } pub fn fd_from_fence(conn: &Conn, drawable: xproto::Drawable, fence: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FDFromFenceRequest { drawable, fence, }; request0.send(conn) } #[derive(Debug, PartialEq, Eq)] pub struct FDFromFenceReply { pub nfd: u8, pub sequence: u16, pub length: u32, pub fence_fd: RawFdContainer, } impl TryParseFd for FDFromFenceReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let fence_fd = fds.remove(0); let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = FDFromFenceReply { nfd, sequence, length, fence_fd }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetSupportedModifiers request pub const GET_SUPPORTED_MODIFIERS_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetSupportedModifiersRequest { pub window: u32, pub depth: u8, pub bpp: u8, } impl GetSupportedModifiersRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let depth_bytes = self.depth.serialize(); let bpp_bytes = self.bpp.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SUPPORTED_MODIFIERS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], depth_bytes[0], bpp_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SUPPORTED_MODIFIERS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = u32::try_parse(value)?; let (depth, remaining) = u8::try_parse(remaining)?; let (bpp, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetSupportedModifiersRequest { window, depth, bpp, }) } } impl Request for GetSupportedModifiersRequest { type Reply = GetSupportedModifiersReply; } pub fn get_supported_modifiers(conn: &Conn, window: u32, depth: u8, bpp: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetSupportedModifiersRequest { window, depth, bpp, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetSupportedModifiersReply { pub sequence: u16, pub length: u32, pub window_modifiers: Vec, pub screen_modifiers: Vec, } impl TryParse for GetSupportedModifiersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_window_modifiers, remaining) = u32::try_parse(remaining)?; let (num_screen_modifiers, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (window_modifiers, remaining) = crate::x11_utils::parse_list::(remaining, num_window_modifiers.try_to_usize()?)?; let (screen_modifiers, remaining) = crate::x11_utils::parse_list::(remaining, num_screen_modifiers.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetSupportedModifiersReply { sequence, length, window_modifiers, screen_modifiers }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetSupportedModifiersReply { /// Get the value of the `num_window_modifiers` field. /// /// The `num_window_modifiers` field is used as the length field of the `window_modifiers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_window_modifiers(&self) -> u32 { self.window_modifiers.len() .try_into().unwrap() } /// Get the value of the `num_screen_modifiers` field. /// /// The `num_screen_modifiers` field is used as the length field of the `screen_modifiers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_screen_modifiers(&self) -> u32 { self.screen_modifiers.len() .try_into().unwrap() } } /// Opcode for the PixmapFromBuffers request pub const PIXMAP_FROM_BUFFERS_REQUEST: u8 = 7; #[derive(Debug, PartialEq, Eq)] pub struct PixmapFromBuffersRequest { pub pixmap: xproto::Pixmap, pub window: xproto::Window, pub width: u16, pub height: u16, pub stride0: u32, pub offset0: u32, pub stride1: u32, pub offset1: u32, pub stride2: u32, pub offset2: u32, pub stride3: u32, pub offset3: u32, pub depth: u8, pub bpp: u8, pub modifier: u64, pub buffers: Vec, } impl PixmapFromBuffersRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let pixmap_bytes = self.pixmap.serialize(); let window_bytes = self.window.serialize(); let num_buffers = u8::try_from(self.buffers.len()).expect("`buffers` has too many elements"); let num_buffers_bytes = num_buffers.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let stride0_bytes = self.stride0.serialize(); let offset0_bytes = self.offset0.serialize(); let stride1_bytes = self.stride1.serialize(); let offset1_bytes = self.offset1.serialize(); let stride2_bytes = self.stride2.serialize(); let offset2_bytes = self.offset2.serialize(); let stride3_bytes = self.stride3.serialize(); let offset3_bytes = self.offset3.serialize(); let depth_bytes = self.depth.serialize(); let bpp_bytes = self.bpp.serialize(); let modifier_bytes = self.modifier.serialize(); let mut request0 = vec![ extension_information.major_opcode, PIXMAP_FROM_BUFFERS_REQUEST, 0, 0, pixmap_bytes[0], pixmap_bytes[1], pixmap_bytes[2], pixmap_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], num_buffers_bytes[0], 0, 0, 0, width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], stride0_bytes[0], stride0_bytes[1], stride0_bytes[2], stride0_bytes[3], offset0_bytes[0], offset0_bytes[1], offset0_bytes[2], offset0_bytes[3], stride1_bytes[0], stride1_bytes[1], stride1_bytes[2], stride1_bytes[3], offset1_bytes[0], offset1_bytes[1], offset1_bytes[2], offset1_bytes[3], stride2_bytes[0], stride2_bytes[1], stride2_bytes[2], stride2_bytes[3], offset2_bytes[0], offset2_bytes[1], offset2_bytes[2], offset2_bytes[3], stride3_bytes[0], stride3_bytes[1], stride3_bytes[2], stride3_bytes[3], offset3_bytes[0], offset3_bytes[1], offset3_bytes[2], offset3_bytes[3], depth_bytes[0], bpp_bytes[0], 0, 0, modifier_bytes[0], modifier_bytes[1], modifier_bytes[2], modifier_bytes[3], modifier_bytes[4], modifier_bytes[5], modifier_bytes[6], modifier_bytes[7], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], self.buffers)) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request_fd(header: RequestHeader, value: &[u8], fds: &mut Vec) -> Result { if header.minor_opcode != PIXMAP_FROM_BUFFERS_REQUEST { return Err(ParseError::InvalidValue); } let (pixmap, remaining) = xproto::Pixmap::try_parse(value)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (num_buffers, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (stride0, remaining) = u32::try_parse(remaining)?; let (offset0, remaining) = u32::try_parse(remaining)?; let (stride1, remaining) = u32::try_parse(remaining)?; let (offset1, remaining) = u32::try_parse(remaining)?; let (stride2, remaining) = u32::try_parse(remaining)?; let (offset2, remaining) = u32::try_parse(remaining)?; let (stride3, remaining) = u32::try_parse(remaining)?; let (offset3, remaining) = u32::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (bpp, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (modifier, remaining) = u64::try_parse(remaining)?; let fds_len = num_buffers.try_to_usize()?; if fds.len() < fds_len { return Err(ParseError::MissingFileDescriptors) } let mut buffers = fds.split_off(fds_len); std::mem::swap(fds, &mut buffers); let _ = remaining; Ok(PixmapFromBuffersRequest { pixmap, window, width, height, stride0, offset0, stride1, offset1, stride2, offset2, stride3, offset3, depth, bpp, modifier, buffers, }) } } impl Request for PixmapFromBuffersRequest { type Reply = (); } pub fn pixmap_from_buffers(conn: &Conn, pixmap: xproto::Pixmap, window: xproto::Window, width: u16, height: u16, stride0: u32, offset0: u32, stride1: u32, offset1: u32, stride2: u32, offset2: u32, stride3: u32, offset3: u32, depth: u8, bpp: u8, modifier: u64, buffers: Vec) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PixmapFromBuffersRequest { pixmap, window, width, height, stride0, offset0, stride1, offset1, stride2, offset2, stride3, offset3, depth, bpp, modifier, buffers, }; request0.send(conn) } /// Opcode for the BuffersFromPixmap request pub const BUFFERS_FROM_PIXMAP_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BuffersFromPixmapRequest { pub pixmap: xproto::Pixmap, } impl BuffersFromPixmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let pixmap_bytes = self.pixmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, BUFFERS_FROM_PIXMAP_REQUEST, 0, 0, pixmap_bytes[0], pixmap_bytes[1], pixmap_bytes[2], pixmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply_with_fds(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != BUFFERS_FROM_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (pixmap, remaining) = xproto::Pixmap::try_parse(value)?; let _ = remaining; Ok(BuffersFromPixmapRequest { pixmap, }) } } impl Request for BuffersFromPixmapRequest { type Reply = BuffersFromPixmapReply; } pub fn buffers_from_pixmap(conn: &Conn, pixmap: xproto::Pixmap) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = BuffersFromPixmapRequest { pixmap, }; request0.send(conn) } #[derive(Debug, PartialEq, Eq)] pub struct BuffersFromPixmapReply { pub sequence: u16, pub length: u32, pub width: u16, pub height: u16, pub modifier: u64, pub depth: u8, pub bpp: u8, pub strides: Vec, pub offsets: Vec, pub buffers: Vec, } impl TryParseFd for BuffersFromPixmapReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (modifier, remaining) = u64::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (bpp, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(6..).ok_or(ParseError::InsufficientData)?; let (strides, remaining) = crate::x11_utils::parse_list::(remaining, nfd.try_to_usize()?)?; let (offsets, remaining) = crate::x11_utils::parse_list::(remaining, nfd.try_to_usize()?)?; let fds_len = nfd.try_to_usize()?; if fds.len() < fds_len { return Err(ParseError::MissingFileDescriptors) } let mut buffers = fds.split_off(fds_len); std::mem::swap(fds, &mut buffers); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = BuffersFromPixmapReply { sequence, length, width, height, modifier, depth, bpp, strides, offsets, buffers }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl BuffersFromPixmapReply { /// Get the value of the `nfd` field. /// /// The `nfd` field is used as the length field of the `strides` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn nfd(&self) -> u8 { self.strides.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn dri3_query_version(&self, major_version: u32, minor_version: u32) -> Result, ConnectionError> { query_version(self, major_version, minor_version) } fn dri3_open(&self, drawable: xproto::Drawable, provider: u32) -> Result, ConnectionError> { open(self, drawable, provider) } fn dri3_pixmap_from_buffer(&self, pixmap: xproto::Pixmap, drawable: xproto::Drawable, size: u32, width: u16, height: u16, stride: u16, depth: u8, bpp: u8, pixmap_fd: A) -> Result, ConnectionError> where A: Into, { pixmap_from_buffer(self, pixmap, drawable, size, width, height, stride, depth, bpp, pixmap_fd) } fn dri3_buffer_from_pixmap(&self, pixmap: xproto::Pixmap) -> Result, ConnectionError> { buffer_from_pixmap(self, pixmap) } fn dri3_fence_from_fd(&self, drawable: xproto::Drawable, fence: u32, initially_triggered: bool, fence_fd: A) -> Result, ConnectionError> where A: Into, { fence_from_fd(self, drawable, fence, initially_triggered, fence_fd) } fn dri3_fd_from_fence(&self, drawable: xproto::Drawable, fence: u32) -> Result, ConnectionError> { fd_from_fence(self, drawable, fence) } fn dri3_get_supported_modifiers(&self, window: u32, depth: u8, bpp: u8) -> Result, ConnectionError> { get_supported_modifiers(self, window, depth, bpp) } fn dri3_pixmap_from_buffers(&self, pixmap: xproto::Pixmap, window: xproto::Window, width: u16, height: u16, stride0: u32, offset0: u32, stride1: u32, offset1: u32, stride2: u32, offset2: u32, stride3: u32, offset3: u32, depth: u8, bpp: u8, modifier: u64, buffers: Vec) -> Result, ConnectionError> { pixmap_from_buffers(self, pixmap, window, width, height, stride0, offset0, stride1, offset1, stride2, offset2, stride3, offset3, depth, bpp, modifier, buffers) } fn dri3_buffers_from_pixmap(&self, pixmap: xproto::Pixmap) -> Result, ConnectionError> { buffers_from_pixmap(self, pixmap) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/ge.rs010064400017500001750000000131331402220031600142160ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `GenericEvent` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "Generic Event Extension"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 0); /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major_version: u16, pub client_minor_version: u16, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_minor_version_bytes[0], client_minor_version_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u16::try_parse(value)?; let (client_minor_version, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major_version, client_minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u16, pub minor_version: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u16::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn ge_query_version(&self, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> { query_version(self, client_major_version, client_minor_version) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/glx.rs010064400017500001750000016340131402220031600144240ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Glx` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "GLX"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 4); pub type Pixmap = u32; pub type Context = u32; pub type Pbuffer = u32; pub type Window = u32; pub type Fbconfig = u32; pub type Drawable = u32; pub type Float32 = f32; pub type Float64 = f64; pub type Bool32 = u32; pub type ContextTag = u32; /// Opcode for the BadContext error pub const BAD_CONTEXT_ERROR: u8 = 0; /// Opcode for the BadContextState error pub const BAD_CONTEXT_STATE_ERROR: u8 = 1; /// Opcode for the BadDrawable error pub const BAD_DRAWABLE_ERROR: u8 = 2; /// Opcode for the BadPixmap error pub const BAD_PIXMAP_ERROR: u8 = 3; /// Opcode for the BadContextTag error pub const BAD_CONTEXT_TAG_ERROR: u8 = 4; /// Opcode for the BadCurrentWindow error pub const BAD_CURRENT_WINDOW_ERROR: u8 = 5; /// Opcode for the BadRenderRequest error pub const BAD_RENDER_REQUEST_ERROR: u8 = 6; /// Opcode for the BadLargeRequest error pub const BAD_LARGE_REQUEST_ERROR: u8 = 7; /// Opcode for the UnsupportedPrivateRequest error pub const UNSUPPORTED_PRIVATE_REQUEST_ERROR: u8 = 8; /// Opcode for the BadFBConfig error pub const BAD_FB_CONFIG_ERROR: u8 = 9; /// Opcode for the BadPbuffer error pub const BAD_PBUFFER_ERROR: u8 = 10; /// Opcode for the BadCurrentDrawable error pub const BAD_CURRENT_DRAWABLE_ERROR: u8 = 11; /// Opcode for the BadWindow error pub const BAD_WINDOW_ERROR: u8 = 12; /// Opcode for the GLXBadProfileARB error pub const GLX_BAD_PROFILE_ARB_ERROR: u8 = 13; /// Opcode for the PbufferClobber event pub const PBUFFER_CLOBBER_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PbufferClobberEvent { pub response_type: u8, pub sequence: u16, pub event_type: u16, pub draw_type: u16, pub drawable: Drawable, pub b_mask: u32, pub aux_buffer: u16, pub x: u16, pub y: u16, pub width: u16, pub height: u16, pub count: u16, } impl TryParse for PbufferClobberEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (draw_type, remaining) = u16::try_parse(remaining)?; let (drawable, remaining) = Drawable::try_parse(remaining)?; let (b_mask, remaining) = u32::try_parse(remaining)?; let (aux_buffer, remaining) = u16::try_parse(remaining)?; let (x, remaining) = u16::try_parse(remaining)?; let (y, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (count, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let result = PbufferClobberEvent { response_type, sequence, event_type, draw_type, drawable, b_mask, aux_buffer, x, y, width, height, count }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&PbufferClobberEvent> for [u8; 32] { fn from(input: &PbufferClobberEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_type_bytes = input.event_type.serialize(); let draw_type_bytes = input.draw_type.serialize(); let drawable_bytes = input.drawable.serialize(); let b_mask_bytes = input.b_mask.serialize(); let aux_buffer_bytes = input.aux_buffer.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); let count_bytes = input.count.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_type_bytes[0], event_type_bytes[1], draw_type_bytes[0], draw_type_bytes[1], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], b_mask_bytes[0], b_mask_bytes[1], b_mask_bytes[2], b_mask_bytes[3], aux_buffer_bytes[0], aux_buffer_bytes[1], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], count_bytes[0], count_bytes[1], 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: PbufferClobberEvent) -> Self { Self::from(&input) } } /// Opcode for the BufferSwapComplete event pub const BUFFER_SWAP_COMPLETE_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BufferSwapCompleteEvent { pub response_type: u8, pub sequence: u16, pub event_type: u16, pub drawable: Drawable, pub ust_hi: u32, pub ust_lo: u32, pub msc_hi: u32, pub msc_lo: u32, pub sbc: u32, } impl TryParse for BufferSwapCompleteEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (drawable, remaining) = Drawable::try_parse(remaining)?; let (ust_hi, remaining) = u32::try_parse(remaining)?; let (ust_lo, remaining) = u32::try_parse(remaining)?; let (msc_hi, remaining) = u32::try_parse(remaining)?; let (msc_lo, remaining) = u32::try_parse(remaining)?; let (sbc, remaining) = u32::try_parse(remaining)?; let result = BufferSwapCompleteEvent { response_type, sequence, event_type, drawable, ust_hi, ust_lo, msc_hi, msc_lo, sbc }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&BufferSwapCompleteEvent> for [u8; 32] { fn from(input: &BufferSwapCompleteEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_type_bytes = input.event_type.serialize(); let drawable_bytes = input.drawable.serialize(); let ust_hi_bytes = input.ust_hi.serialize(); let ust_lo_bytes = input.ust_lo.serialize(); let msc_hi_bytes = input.msc_hi.serialize(); let msc_lo_bytes = input.msc_lo.serialize(); let sbc_bytes = input.sbc.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_type_bytes[0], event_type_bytes[1], 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ust_hi_bytes[0], ust_hi_bytes[1], ust_hi_bytes[2], ust_hi_bytes[3], ust_lo_bytes[0], ust_lo_bytes[1], ust_lo_bytes[2], ust_lo_bytes[3], msc_hi_bytes[0], msc_hi_bytes[1], msc_hi_bytes[2], msc_hi_bytes[3], msc_lo_bytes[0], msc_lo_bytes[1], msc_lo_bytes[2], msc_lo_bytes[3], sbc_bytes[0], sbc_bytes[1], sbc_bytes[2], sbc_bytes[3], ] } } impl From for [u8; 32] { fn from(input: BufferSwapCompleteEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PBCET(u16); impl PBCET { pub const DAMAGED: Self = Self(32791); pub const SAVED: Self = Self(32792); } impl From for u16 { #[inline] fn from(input: PBCET) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PBCET) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: PBCET) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PBCET) -> Self { Some(u32::from(input.0)) } } impl From for PBCET { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for PBCET { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for PBCET { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DAMAGED.0.into(), "DAMAGED", "Damaged"), (Self::SAVED.0.into(), "SAVED", "Saved"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PBCDT(u16); impl PBCDT { pub const WINDOW: Self = Self(32793); pub const PBUFFER: Self = Self(32794); } impl From for u16 { #[inline] fn from(input: PBCDT) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PBCDT) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: PBCDT) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PBCDT) -> Self { Some(u32::from(input.0)) } } impl From for PBCDT { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for PBCDT { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for PBCDT { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::WINDOW.0.into(), "WINDOW", "Window"), (Self::PBUFFER.0.into(), "PBUFFER", "Pbuffer"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the Render request pub const RENDER_REQUEST: u8 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RenderRequest<'input> { pub context_tag: ContextTag, pub data: Cow<'input, [u8]>, } impl<'input> RenderRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, RENDER_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != RENDER_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (data, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(RenderRequest { context_tag, data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this RenderRequest. pub fn into_owned(self) -> RenderRequest<'static> { RenderRequest { context_tag: self.context_tag, data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for RenderRequest<'input> { type Reply = (); } pub fn render<'c, 'input, Conn>(conn: &'c Conn, context_tag: ContextTag, data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RenderRequest { context_tag, data: Cow::Borrowed(data), }; request0.send(conn) } /// Opcode for the RenderLarge request pub const RENDER_LARGE_REQUEST: u8 = 2; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RenderLargeRequest<'input> { pub context_tag: ContextTag, pub request_num: u16, pub request_total: u16, pub data: Cow<'input, [u8]>, } impl<'input> RenderLargeRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let request_num_bytes = self.request_num.serialize(); let request_total_bytes = self.request_total.serialize(); let data_len = u32::try_from(self.data.len()).expect("`data` has too many elements"); let data_len_bytes = data_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, RENDER_LARGE_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], request_num_bytes[0], request_num_bytes[1], request_total_bytes[0], request_total_bytes[1], data_len_bytes[0], data_len_bytes[1], data_len_bytes[2], data_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != RENDER_LARGE_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (request_num, remaining) = u16::try_parse(remaining)?; let (request_total, remaining) = u16::try_parse(remaining)?; let (data_len, remaining) = u32::try_parse(remaining)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, data_len.try_to_usize()?)?; let _ = remaining; Ok(RenderLargeRequest { context_tag, request_num, request_total, data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this RenderLargeRequest. pub fn into_owned(self) -> RenderLargeRequest<'static> { RenderLargeRequest { context_tag: self.context_tag, request_num: self.request_num, request_total: self.request_total, data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for RenderLargeRequest<'input> { type Reply = (); } pub fn render_large<'c, 'input, Conn>(conn: &'c Conn, context_tag: ContextTag, request_num: u16, request_total: u16, data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RenderLargeRequest { context_tag, request_num, request_total, data: Cow::Borrowed(data), }; request0.send(conn) } /// Opcode for the CreateContext request pub const CREATE_CONTEXT_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateContextRequest { pub context: Context, pub visual: xproto::Visualid, pub screen: u32, pub share_list: Context, pub is_direct: bool, } impl CreateContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let visual_bytes = self.visual.serialize(); let screen_bytes = self.screen.serialize(); let share_list_bytes = self.share_list.serialize(); let is_direct_bytes = self.is_direct.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], visual_bytes[0], visual_bytes[1], visual_bytes[2], visual_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], share_list_bytes[0], share_list_bytes[1], share_list_bytes[2], share_list_bytes[3], is_direct_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (screen, remaining) = u32::try_parse(remaining)?; let (share_list, remaining) = Context::try_parse(remaining)?; let (is_direct, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(CreateContextRequest { context, visual, screen, share_list, is_direct, }) } } impl Request for CreateContextRequest { type Reply = (); } pub fn create_context(conn: &Conn, context: Context, visual: xproto::Visualid, screen: u32, share_list: Context, is_direct: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateContextRequest { context, visual, screen, share_list, is_direct, }; request0.send(conn) } /// Opcode for the DestroyContext request pub const DESTROY_CONTEXT_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyContextRequest { pub context: Context, } impl DestroyContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(DestroyContextRequest { context, }) } } impl Request for DestroyContextRequest { type Reply = (); } pub fn destroy_context(conn: &Conn, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyContextRequest { context, }; request0.send(conn) } /// Opcode for the MakeCurrent request pub const MAKE_CURRENT_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MakeCurrentRequest { pub drawable: Drawable, pub context: Context, pub old_context_tag: ContextTag, } impl MakeCurrentRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let context_bytes = self.context.serialize(); let old_context_tag_bytes = self.old_context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, MAKE_CURRENT_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], old_context_tag_bytes[0], old_context_tag_bytes[1], old_context_tag_bytes[2], old_context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != MAKE_CURRENT_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = Drawable::try_parse(value)?; let (context, remaining) = Context::try_parse(remaining)?; let (old_context_tag, remaining) = ContextTag::try_parse(remaining)?; let _ = remaining; Ok(MakeCurrentRequest { drawable, context, old_context_tag, }) } } impl Request for MakeCurrentRequest { type Reply = MakeCurrentReply; } pub fn make_current(conn: &Conn, drawable: Drawable, context: Context, old_context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = MakeCurrentRequest { drawable, context, old_context_tag, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MakeCurrentReply { pub sequence: u16, pub length: u32, pub context_tag: ContextTag, } impl TryParse for MakeCurrentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_tag, remaining) = ContextTag::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = MakeCurrentReply { sequence, length, context_tag }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the IsDirect request pub const IS_DIRECT_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsDirectRequest { pub context: Context, } impl IsDirectRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, IS_DIRECT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != IS_DIRECT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(IsDirectRequest { context, }) } } impl Request for IsDirectRequest { type Reply = IsDirectReply; } pub fn is_direct(conn: &Conn, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = IsDirectRequest { context, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsDirectReply { pub sequence: u16, pub length: u32, pub is_direct: bool, } impl TryParse for IsDirectReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (is_direct, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = IsDirectReply { sequence, length, is_direct }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub major_version: u32, pub minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], major_version_bytes[2], major_version_bytes[3], minor_version_bytes[0], minor_version_bytes[1], minor_version_bytes[2], minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u32::try_parse(value)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { major_version, minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, major_version: u32, minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { major_version, minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the WaitGL request pub const WAIT_GL_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct WaitGLRequest { pub context_tag: ContextTag, } impl WaitGLRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, WAIT_GL_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != WAIT_GL_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let _ = remaining; Ok(WaitGLRequest { context_tag, }) } } impl Request for WaitGLRequest { type Reply = (); } pub fn wait_gl(conn: &Conn, context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = WaitGLRequest { context_tag, }; request0.send(conn) } /// Opcode for the WaitX request pub const WAIT_X_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct WaitXRequest { pub context_tag: ContextTag, } impl WaitXRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, WAIT_X_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != WAIT_X_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let _ = remaining; Ok(WaitXRequest { context_tag, }) } } impl Request for WaitXRequest { type Reply = (); } pub fn wait_x(conn: &Conn, context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = WaitXRequest { context_tag, }; request0.send(conn) } /// Opcode for the CopyContext request pub const COPY_CONTEXT_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CopyContextRequest { pub src: Context, pub dest: Context, pub mask: u32, pub src_context_tag: ContextTag, } impl CopyContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let src_bytes = self.src.serialize(); let dest_bytes = self.dest.serialize(); let mask_bytes = self.mask.serialize(); let src_context_tag_bytes = self.src_context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, COPY_CONTEXT_REQUEST, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dest_bytes[0], dest_bytes[1], dest_bytes[2], dest_bytes[3], mask_bytes[0], mask_bytes[1], mask_bytes[2], mask_bytes[3], src_context_tag_bytes[0], src_context_tag_bytes[1], src_context_tag_bytes[2], src_context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != COPY_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (src, remaining) = Context::try_parse(value)?; let (dest, remaining) = Context::try_parse(remaining)?; let (mask, remaining) = u32::try_parse(remaining)?; let (src_context_tag, remaining) = ContextTag::try_parse(remaining)?; let _ = remaining; Ok(CopyContextRequest { src, dest, mask, src_context_tag, }) } } impl Request for CopyContextRequest { type Reply = (); } pub fn copy_context(conn: &Conn, src: Context, dest: Context, mask: u32, src_context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CopyContextRequest { src, dest, mask, src_context_tag, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct GC(u32); impl GC { pub const GL_CURRENT_BIT: Self = Self(1 << 0); pub const GL_POINT_BIT: Self = Self(1 << 1); pub const GL_LINE_BIT: Self = Self(1 << 2); pub const GL_POLYGON_BIT: Self = Self(1 << 3); pub const GL_POLYGON_STIPPLE_BIT: Self = Self(1 << 4); pub const GL_PIXEL_MODE_BIT: Self = Self(1 << 5); pub const GL_LIGHTING_BIT: Self = Self(1 << 6); pub const GL_FOG_BIT: Self = Self(1 << 7); pub const GL_DEPTH_BUFFER_BIT: Self = Self(1 << 8); pub const GL_ACCUM_BUFFER_BIT: Self = Self(1 << 9); pub const GL_STENCIL_BUFFER_BIT: Self = Self(1 << 10); pub const GL_VIEWPORT_BIT: Self = Self(1 << 11); pub const GL_TRANSFORM_BIT: Self = Self(1 << 12); pub const GL_ENABLE_BIT: Self = Self(1 << 13); pub const GL_COLOR_BUFFER_BIT: Self = Self(1 << 14); pub const GL_HINT_BIT: Self = Self(1 << 15); pub const GL_EVAL_BIT: Self = Self(1 << 16); pub const GL_LIST_BIT: Self = Self(1 << 17); pub const GL_TEXTURE_BIT: Self = Self(1 << 18); pub const GL_SCISSOR_BIT: Self = Self(1 << 19); pub const GL_ALL_ATTRIB_BITS: Self = Self(16_777_215); } impl From for u32 { #[inline] fn from(input: GC) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GC) -> Self { Some(input.0) } } impl From for GC { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for GC { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for GC { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for GC { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::GL_CURRENT_BIT.0, "GL_CURRENT_BIT", "GL_CURRENT_BIT"), (Self::GL_POINT_BIT.0, "GL_POINT_BIT", "GL_POINT_BIT"), (Self::GL_LINE_BIT.0, "GL_LINE_BIT", "GL_LINE_BIT"), (Self::GL_POLYGON_BIT.0, "GL_POLYGON_BIT", "GL_POLYGON_BIT"), (Self::GL_POLYGON_STIPPLE_BIT.0, "GL_POLYGON_STIPPLE_BIT", "GL_POLYGON_STIPPLE_BIT"), (Self::GL_PIXEL_MODE_BIT.0, "GL_PIXEL_MODE_BIT", "GL_PIXEL_MODE_BIT"), (Self::GL_LIGHTING_BIT.0, "GL_LIGHTING_BIT", "GL_LIGHTING_BIT"), (Self::GL_FOG_BIT.0, "GL_FOG_BIT", "GL_FOG_BIT"), (Self::GL_DEPTH_BUFFER_BIT.0, "GL_DEPTH_BUFFER_BIT", "GL_DEPTH_BUFFER_BIT"), (Self::GL_ACCUM_BUFFER_BIT.0, "GL_ACCUM_BUFFER_BIT", "GL_ACCUM_BUFFER_BIT"), (Self::GL_STENCIL_BUFFER_BIT.0, "GL_STENCIL_BUFFER_BIT", "GL_STENCIL_BUFFER_BIT"), (Self::GL_VIEWPORT_BIT.0, "GL_VIEWPORT_BIT", "GL_VIEWPORT_BIT"), (Self::GL_TRANSFORM_BIT.0, "GL_TRANSFORM_BIT", "GL_TRANSFORM_BIT"), (Self::GL_ENABLE_BIT.0, "GL_ENABLE_BIT", "GL_ENABLE_BIT"), (Self::GL_COLOR_BUFFER_BIT.0, "GL_COLOR_BUFFER_BIT", "GL_COLOR_BUFFER_BIT"), (Self::GL_HINT_BIT.0, "GL_HINT_BIT", "GL_HINT_BIT"), (Self::GL_EVAL_BIT.0, "GL_EVAL_BIT", "GL_EVAL_BIT"), (Self::GL_LIST_BIT.0, "GL_LIST_BIT", "GL_LIST_BIT"), (Self::GL_TEXTURE_BIT.0, "GL_TEXTURE_BIT", "GL_TEXTURE_BIT"), (Self::GL_SCISSOR_BIT.0, "GL_SCISSOR_BIT", "GL_SCISSOR_BIT"), (Self::GL_ALL_ATTRIB_BITS.0, "GL_ALL_ATTRIB_BITS", "GL_ALL_ATTRIB_BITS"), ]; pretty_print_enum(fmt, self.0, &variants) } } /// Opcode for the SwapBuffers request pub const SWAP_BUFFERS_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SwapBuffersRequest { pub context_tag: ContextTag, pub drawable: Drawable, } impl SwapBuffersRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, SWAP_BUFFERS_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SWAP_BUFFERS_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (drawable, remaining) = Drawable::try_parse(remaining)?; let _ = remaining; Ok(SwapBuffersRequest { context_tag, drawable, }) } } impl Request for SwapBuffersRequest { type Reply = (); } pub fn swap_buffers(conn: &Conn, context_tag: ContextTag, drawable: Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SwapBuffersRequest { context_tag, drawable, }; request0.send(conn) } /// Opcode for the UseXFont request pub const USE_X_FONT_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UseXFontRequest { pub context_tag: ContextTag, pub font: xproto::Font, pub first: u32, pub count: u32, pub list_base: u32, } impl UseXFontRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let font_bytes = self.font.serialize(); let first_bytes = self.first.serialize(); let count_bytes = self.count.serialize(); let list_base_bytes = self.list_base.serialize(); let mut request0 = vec![ extension_information.major_opcode, USE_X_FONT_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], font_bytes[0], font_bytes[1], font_bytes[2], font_bytes[3], first_bytes[0], first_bytes[1], first_bytes[2], first_bytes[3], count_bytes[0], count_bytes[1], count_bytes[2], count_bytes[3], list_base_bytes[0], list_base_bytes[1], list_base_bytes[2], list_base_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != USE_X_FONT_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (font, remaining) = xproto::Font::try_parse(remaining)?; let (first, remaining) = u32::try_parse(remaining)?; let (count, remaining) = u32::try_parse(remaining)?; let (list_base, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(UseXFontRequest { context_tag, font, first, count, list_base, }) } } impl Request for UseXFontRequest { type Reply = (); } pub fn use_x_font(conn: &Conn, context_tag: ContextTag, font: xproto::Font, first: u32, count: u32, list_base: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = UseXFontRequest { context_tag, font, first, count, list_base, }; request0.send(conn) } /// Opcode for the CreateGLXPixmap request pub const CREATE_GLX_PIXMAP_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateGLXPixmapRequest { pub screen: u32, pub visual: xproto::Visualid, pub pixmap: xproto::Pixmap, pub glx_pixmap: Pixmap, } impl CreateGLXPixmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let visual_bytes = self.visual.serialize(); let pixmap_bytes = self.pixmap.serialize(); let glx_pixmap_bytes = self.glx_pixmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_GLX_PIXMAP_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], visual_bytes[0], visual_bytes[1], visual_bytes[2], visual_bytes[3], pixmap_bytes[0], pixmap_bytes[1], pixmap_bytes[2], pixmap_bytes[3], glx_pixmap_bytes[0], glx_pixmap_bytes[1], glx_pixmap_bytes[2], glx_pixmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_GLX_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (pixmap, remaining) = xproto::Pixmap::try_parse(remaining)?; let (glx_pixmap, remaining) = Pixmap::try_parse(remaining)?; let _ = remaining; Ok(CreateGLXPixmapRequest { screen, visual, pixmap, glx_pixmap, }) } } impl Request for CreateGLXPixmapRequest { type Reply = (); } pub fn create_glx_pixmap(conn: &Conn, screen: u32, visual: xproto::Visualid, pixmap: xproto::Pixmap, glx_pixmap: Pixmap) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateGLXPixmapRequest { screen, visual, pixmap, glx_pixmap, }; request0.send(conn) } /// Opcode for the GetVisualConfigs request pub const GET_VISUAL_CONFIGS_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVisualConfigsRequest { pub screen: u32, } impl GetVisualConfigsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_VISUAL_CONFIGS_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_VISUAL_CONFIGS_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetVisualConfigsRequest { screen, }) } } impl Request for GetVisualConfigsRequest { type Reply = GetVisualConfigsReply; } pub fn get_visual_configs(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetVisualConfigsRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetVisualConfigsReply { pub sequence: u16, pub num_visuals: u32, pub num_properties: u32, pub property_list: Vec, } impl TryParse for GetVisualConfigsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_visuals, remaining) = u32::try_parse(remaining)?; let (num_properties, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (property_list, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetVisualConfigsReply { sequence, num_visuals, num_properties, property_list }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetVisualConfigsReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `property_list` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.property_list.len() .try_into().unwrap() } } /// Opcode for the DestroyGLXPixmap request pub const DESTROY_GLX_PIXMAP_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyGLXPixmapRequest { pub glx_pixmap: Pixmap, } impl DestroyGLXPixmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let glx_pixmap_bytes = self.glx_pixmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_GLX_PIXMAP_REQUEST, 0, 0, glx_pixmap_bytes[0], glx_pixmap_bytes[1], glx_pixmap_bytes[2], glx_pixmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_GLX_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (glx_pixmap, remaining) = Pixmap::try_parse(value)?; let _ = remaining; Ok(DestroyGLXPixmapRequest { glx_pixmap, }) } } impl Request for DestroyGLXPixmapRequest { type Reply = (); } pub fn destroy_glx_pixmap(conn: &Conn, glx_pixmap: Pixmap) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyGLXPixmapRequest { glx_pixmap, }; request0.send(conn) } /// Opcode for the VendorPrivate request pub const VENDOR_PRIVATE_REQUEST: u8 = 16; #[derive(Debug, Clone, PartialEq, Eq)] pub struct VendorPrivateRequest<'input> { pub vendor_code: u32, pub context_tag: ContextTag, pub data: Cow<'input, [u8]>, } impl<'input> VendorPrivateRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let vendor_code_bytes = self.vendor_code.serialize(); let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, VENDOR_PRIVATE_REQUEST, 0, 0, vendor_code_bytes[0], vendor_code_bytes[1], vendor_code_bytes[2], vendor_code_bytes[3], context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != VENDOR_PRIVATE_REQUEST { return Err(ParseError::InvalidValue); } let (vendor_code, remaining) = u32::try_parse(value)?; let (context_tag, remaining) = ContextTag::try_parse(remaining)?; let (data, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(VendorPrivateRequest { vendor_code, context_tag, data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this VendorPrivateRequest. pub fn into_owned(self) -> VendorPrivateRequest<'static> { VendorPrivateRequest { vendor_code: self.vendor_code, context_tag: self.context_tag, data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for VendorPrivateRequest<'input> { type Reply = (); } pub fn vendor_private<'c, 'input, Conn>(conn: &'c Conn, vendor_code: u32, context_tag: ContextTag, data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = VendorPrivateRequest { vendor_code, context_tag, data: Cow::Borrowed(data), }; request0.send(conn) } /// Opcode for the VendorPrivateWithReply request pub const VENDOR_PRIVATE_WITH_REPLY_REQUEST: u8 = 17; #[derive(Debug, Clone, PartialEq, Eq)] pub struct VendorPrivateWithReplyRequest<'input> { pub vendor_code: u32, pub context_tag: ContextTag, pub data: Cow<'input, [u8]>, } impl<'input> VendorPrivateWithReplyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let vendor_code_bytes = self.vendor_code.serialize(); let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, VENDOR_PRIVATE_WITH_REPLY_REQUEST, 0, 0, vendor_code_bytes[0], vendor_code_bytes[1], vendor_code_bytes[2], vendor_code_bytes[3], context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != VENDOR_PRIVATE_WITH_REPLY_REQUEST { return Err(ParseError::InvalidValue); } let (vendor_code, remaining) = u32::try_parse(value)?; let (context_tag, remaining) = ContextTag::try_parse(remaining)?; let (data, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(VendorPrivateWithReplyRequest { vendor_code, context_tag, data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this VendorPrivateWithReplyRequest. pub fn into_owned(self) -> VendorPrivateWithReplyRequest<'static> { VendorPrivateWithReplyRequest { vendor_code: self.vendor_code, context_tag: self.context_tag, data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for VendorPrivateWithReplyRequest<'input> { type Reply = VendorPrivateWithReplyReply; } pub fn vendor_private_with_reply<'c, 'input, Conn>(conn: &'c Conn, vendor_code: u32, context_tag: ContextTag, data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = VendorPrivateWithReplyRequest { vendor_code, context_tag, data: Cow::Borrowed(data), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct VendorPrivateWithReplyReply { pub sequence: u16, pub retval: u32, pub data1: [u8; 24], pub data2: Vec, } impl TryParse for VendorPrivateWithReplyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (retval, remaining) = u32::try_parse(remaining)?; let (data1, remaining) = crate::x11_utils::parse_u8_list(remaining, 24)?; let data1 = <[u8; 24]>::try_from(data1).unwrap(); let (data2, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data2 = data2.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = VendorPrivateWithReplyReply { sequence, retval, data1, data2 }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl VendorPrivateWithReplyReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data2` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data2.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the QueryExtensionsString request pub const QUERY_EXTENSIONS_STRING_REQUEST: u8 = 18; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryExtensionsStringRequest { pub screen: u32, } impl QueryExtensionsStringRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_EXTENSIONS_STRING_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_EXTENSIONS_STRING_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(QueryExtensionsStringRequest { screen, }) } } impl Request for QueryExtensionsStringRequest { type Reply = QueryExtensionsStringReply; } pub fn query_extensions_string(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryExtensionsStringRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryExtensionsStringReply { pub sequence: u16, pub length: u32, pub n: u32, } impl TryParse for QueryExtensionsStringReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryExtensionsStringReply { sequence, length, n }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryServerString request pub const QUERY_SERVER_STRING_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryServerStringRequest { pub screen: u32, pub name: u32, } impl QueryServerStringRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let name_bytes = self.name.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_SERVER_STRING_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_SERVER_STRING_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (name, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryServerStringRequest { screen, name, }) } } impl Request for QueryServerStringRequest { type Reply = QueryServerStringReply; } pub fn query_server_string(conn: &Conn, screen: u32, name: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryServerStringRequest { screen, name, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryServerStringReply { pub sequence: u16, pub length: u32, pub string: Vec, } impl TryParse for QueryServerStringReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (str_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, str_len.try_to_usize()?)?; let string = string.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryServerStringReply { sequence, length, string }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryServerStringReply { /// Get the value of the `str_len` field. /// /// The `str_len` field is used as the length field of the `string` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn str_len(&self) -> u32 { self.string.len() .try_into().unwrap() } } /// Opcode for the ClientInfo request pub const CLIENT_INFO_REQUEST: u8 = 20; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ClientInfoRequest<'input> { pub major_version: u32, pub minor_version: u32, pub string: Cow<'input, [u8]>, } impl<'input> ClientInfoRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let str_len = u32::try_from(self.string.len()).expect("`string` has too many elements"); let str_len_bytes = str_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, CLIENT_INFO_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], major_version_bytes[2], major_version_bytes[3], minor_version_bytes[0], minor_version_bytes[1], minor_version_bytes[2], minor_version_bytes[3], str_len_bytes[0], str_len_bytes[1], str_len_bytes[2], str_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.string.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.string, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CLIENT_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u32::try_parse(value)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let (str_len, remaining) = u32::try_parse(remaining)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, str_len.try_to_usize()?)?; let _ = remaining; Ok(ClientInfoRequest { major_version, minor_version, string: Cow::Borrowed(string), }) } /// Clone all borrowed data in this ClientInfoRequest. pub fn into_owned(self) -> ClientInfoRequest<'static> { ClientInfoRequest { major_version: self.major_version, minor_version: self.minor_version, string: Cow::Owned(self.string.into_owned()), } } } impl<'input> Request for ClientInfoRequest<'input> { type Reply = (); } pub fn client_info<'c, 'input, Conn>(conn: &'c Conn, major_version: u32, minor_version: u32, string: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ClientInfoRequest { major_version, minor_version, string: Cow::Borrowed(string), }; request0.send(conn) } /// Opcode for the GetFBConfigs request pub const GET_FB_CONFIGS_REQUEST: u8 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetFBConfigsRequest { pub screen: u32, } impl GetFBConfigsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_FB_CONFIGS_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_FB_CONFIGS_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetFBConfigsRequest { screen, }) } } impl Request for GetFBConfigsRequest { type Reply = GetFBConfigsReply; } pub fn get_fb_configs(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetFBConfigsRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetFBConfigsReply { pub sequence: u16, pub num_fb_configs: u32, pub num_properties: u32, pub property_list: Vec, } impl TryParse for GetFBConfigsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_fb_configs, remaining) = u32::try_parse(remaining)?; let (num_properties, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (property_list, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetFBConfigsReply { sequence, num_fb_configs, num_properties, property_list }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetFBConfigsReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `property_list` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.property_list.len() .try_into().unwrap() } } /// Opcode for the CreatePixmap request pub const CREATE_PIXMAP_REQUEST: u8 = 22; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreatePixmapRequest<'input> { pub screen: u32, pub fbconfig: Fbconfig, pub pixmap: xproto::Pixmap, pub glx_pixmap: Pixmap, pub attribs: Cow<'input, [u32]>, } impl<'input> CreatePixmapRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let fbconfig_bytes = self.fbconfig.serialize(); let pixmap_bytes = self.pixmap.serialize(); let glx_pixmap_bytes = self.glx_pixmap.serialize(); assert_eq!(self.attribs.len() % 2, 0, "`attribs` has an incorrect length, must be a multiple of 2"); let num_attribs = u32::try_from(self.attribs.len() / 2).expect("`attribs` has too many elements"); let num_attribs_bytes = num_attribs.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_PIXMAP_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], fbconfig_bytes[0], fbconfig_bytes[1], fbconfig_bytes[2], fbconfig_bytes[3], pixmap_bytes[0], pixmap_bytes[1], pixmap_bytes[2], pixmap_bytes[3], glx_pixmap_bytes[0], glx_pixmap_bytes[1], glx_pixmap_bytes[2], glx_pixmap_bytes[3], num_attribs_bytes[0], num_attribs_bytes[1], num_attribs_bytes[2], num_attribs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let attribs_bytes = self.attribs.serialize(); let length_so_far = length_so_far + attribs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), attribs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (fbconfig, remaining) = Fbconfig::try_parse(remaining)?; let (pixmap, remaining) = xproto::Pixmap::try_parse(remaining)?; let (glx_pixmap, remaining) = Pixmap::try_parse(remaining)?; let (num_attribs, remaining) = u32::try_parse(remaining)?; let (attribs, remaining) = crate::x11_utils::parse_list::(remaining, num_attribs.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(CreatePixmapRequest { screen, fbconfig, pixmap, glx_pixmap, attribs: Cow::Owned(attribs), }) } /// Clone all borrowed data in this CreatePixmapRequest. pub fn into_owned(self) -> CreatePixmapRequest<'static> { CreatePixmapRequest { screen: self.screen, fbconfig: self.fbconfig, pixmap: self.pixmap, glx_pixmap: self.glx_pixmap, attribs: Cow::Owned(self.attribs.into_owned()), } } } impl<'input> Request for CreatePixmapRequest<'input> { type Reply = (); } pub fn create_pixmap<'c, 'input, Conn>(conn: &'c Conn, screen: u32, fbconfig: Fbconfig, pixmap: xproto::Pixmap, glx_pixmap: Pixmap, attribs: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreatePixmapRequest { screen, fbconfig, pixmap, glx_pixmap, attribs: Cow::Borrowed(attribs), }; request0.send(conn) } /// Opcode for the DestroyPixmap request pub const DESTROY_PIXMAP_REQUEST: u8 = 23; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyPixmapRequest { pub glx_pixmap: Pixmap, } impl DestroyPixmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let glx_pixmap_bytes = self.glx_pixmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_PIXMAP_REQUEST, 0, 0, glx_pixmap_bytes[0], glx_pixmap_bytes[1], glx_pixmap_bytes[2], glx_pixmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (glx_pixmap, remaining) = Pixmap::try_parse(value)?; let _ = remaining; Ok(DestroyPixmapRequest { glx_pixmap, }) } } impl Request for DestroyPixmapRequest { type Reply = (); } pub fn destroy_pixmap(conn: &Conn, glx_pixmap: Pixmap) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyPixmapRequest { glx_pixmap, }; request0.send(conn) } /// Opcode for the CreateNewContext request pub const CREATE_NEW_CONTEXT_REQUEST: u8 = 24; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateNewContextRequest { pub context: Context, pub fbconfig: Fbconfig, pub screen: u32, pub render_type: u32, pub share_list: Context, pub is_direct: bool, } impl CreateNewContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let fbconfig_bytes = self.fbconfig.serialize(); let screen_bytes = self.screen.serialize(); let render_type_bytes = self.render_type.serialize(); let share_list_bytes = self.share_list.serialize(); let is_direct_bytes = self.is_direct.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_NEW_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], fbconfig_bytes[0], fbconfig_bytes[1], fbconfig_bytes[2], fbconfig_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], render_type_bytes[0], render_type_bytes[1], render_type_bytes[2], render_type_bytes[3], share_list_bytes[0], share_list_bytes[1], share_list_bytes[2], share_list_bytes[3], is_direct_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_NEW_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let (fbconfig, remaining) = Fbconfig::try_parse(remaining)?; let (screen, remaining) = u32::try_parse(remaining)?; let (render_type, remaining) = u32::try_parse(remaining)?; let (share_list, remaining) = Context::try_parse(remaining)?; let (is_direct, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(CreateNewContextRequest { context, fbconfig, screen, render_type, share_list, is_direct, }) } } impl Request for CreateNewContextRequest { type Reply = (); } pub fn create_new_context(conn: &Conn, context: Context, fbconfig: Fbconfig, screen: u32, render_type: u32, share_list: Context, is_direct: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateNewContextRequest { context, fbconfig, screen, render_type, share_list, is_direct, }; request0.send(conn) } /// Opcode for the QueryContext request pub const QUERY_CONTEXT_REQUEST: u8 = 25; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryContextRequest { pub context: Context, } impl QueryContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(QueryContextRequest { context, }) } } impl Request for QueryContextRequest { type Reply = QueryContextReply; } pub fn query_context(conn: &Conn, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryContextRequest { context, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryContextReply { pub sequence: u16, pub length: u32, pub attribs: Vec, } impl TryParse for QueryContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_attribs, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (attribs, remaining) = crate::x11_utils::parse_list::(remaining, num_attribs.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryContextReply { sequence, length, attribs }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryContextReply { /// Get the value of the `num_attribs` field. /// /// The `num_attribs` field is used as the length field of the `attribs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_attribs(&self) -> u32 { self.attribs.len() .checked_div(2).unwrap() .try_into().unwrap() } } /// Opcode for the MakeContextCurrent request pub const MAKE_CONTEXT_CURRENT_REQUEST: u8 = 26; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MakeContextCurrentRequest { pub old_context_tag: ContextTag, pub drawable: Drawable, pub read_drawable: Drawable, pub context: Context, } impl MakeContextCurrentRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let old_context_tag_bytes = self.old_context_tag.serialize(); let drawable_bytes = self.drawable.serialize(); let read_drawable_bytes = self.read_drawable.serialize(); let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, MAKE_CONTEXT_CURRENT_REQUEST, 0, 0, old_context_tag_bytes[0], old_context_tag_bytes[1], old_context_tag_bytes[2], old_context_tag_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], read_drawable_bytes[0], read_drawable_bytes[1], read_drawable_bytes[2], read_drawable_bytes[3], context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != MAKE_CONTEXT_CURRENT_REQUEST { return Err(ParseError::InvalidValue); } let (old_context_tag, remaining) = ContextTag::try_parse(value)?; let (drawable, remaining) = Drawable::try_parse(remaining)?; let (read_drawable, remaining) = Drawable::try_parse(remaining)?; let (context, remaining) = Context::try_parse(remaining)?; let _ = remaining; Ok(MakeContextCurrentRequest { old_context_tag, drawable, read_drawable, context, }) } } impl Request for MakeContextCurrentRequest { type Reply = MakeContextCurrentReply; } pub fn make_context_current(conn: &Conn, old_context_tag: ContextTag, drawable: Drawable, read_drawable: Drawable, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = MakeContextCurrentRequest { old_context_tag, drawable, read_drawable, context, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MakeContextCurrentReply { pub sequence: u16, pub length: u32, pub context_tag: ContextTag, } impl TryParse for MakeContextCurrentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_tag, remaining) = ContextTag::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = MakeContextCurrentReply { sequence, length, context_tag }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the CreatePbuffer request pub const CREATE_PBUFFER_REQUEST: u8 = 27; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreatePbufferRequest<'input> { pub screen: u32, pub fbconfig: Fbconfig, pub pbuffer: Pbuffer, pub attribs: Cow<'input, [u32]>, } impl<'input> CreatePbufferRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let fbconfig_bytes = self.fbconfig.serialize(); let pbuffer_bytes = self.pbuffer.serialize(); assert_eq!(self.attribs.len() % 2, 0, "`attribs` has an incorrect length, must be a multiple of 2"); let num_attribs = u32::try_from(self.attribs.len() / 2).expect("`attribs` has too many elements"); let num_attribs_bytes = num_attribs.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_PBUFFER_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], fbconfig_bytes[0], fbconfig_bytes[1], fbconfig_bytes[2], fbconfig_bytes[3], pbuffer_bytes[0], pbuffer_bytes[1], pbuffer_bytes[2], pbuffer_bytes[3], num_attribs_bytes[0], num_attribs_bytes[1], num_attribs_bytes[2], num_attribs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let attribs_bytes = self.attribs.serialize(); let length_so_far = length_so_far + attribs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), attribs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_PBUFFER_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (fbconfig, remaining) = Fbconfig::try_parse(remaining)?; let (pbuffer, remaining) = Pbuffer::try_parse(remaining)?; let (num_attribs, remaining) = u32::try_parse(remaining)?; let (attribs, remaining) = crate::x11_utils::parse_list::(remaining, num_attribs.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(CreatePbufferRequest { screen, fbconfig, pbuffer, attribs: Cow::Owned(attribs), }) } /// Clone all borrowed data in this CreatePbufferRequest. pub fn into_owned(self) -> CreatePbufferRequest<'static> { CreatePbufferRequest { screen: self.screen, fbconfig: self.fbconfig, pbuffer: self.pbuffer, attribs: Cow::Owned(self.attribs.into_owned()), } } } impl<'input> Request for CreatePbufferRequest<'input> { type Reply = (); } pub fn create_pbuffer<'c, 'input, Conn>(conn: &'c Conn, screen: u32, fbconfig: Fbconfig, pbuffer: Pbuffer, attribs: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreatePbufferRequest { screen, fbconfig, pbuffer, attribs: Cow::Borrowed(attribs), }; request0.send(conn) } /// Opcode for the DestroyPbuffer request pub const DESTROY_PBUFFER_REQUEST: u8 = 28; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyPbufferRequest { pub pbuffer: Pbuffer, } impl DestroyPbufferRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let pbuffer_bytes = self.pbuffer.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_PBUFFER_REQUEST, 0, 0, pbuffer_bytes[0], pbuffer_bytes[1], pbuffer_bytes[2], pbuffer_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_PBUFFER_REQUEST { return Err(ParseError::InvalidValue); } let (pbuffer, remaining) = Pbuffer::try_parse(value)?; let _ = remaining; Ok(DestroyPbufferRequest { pbuffer, }) } } impl Request for DestroyPbufferRequest { type Reply = (); } pub fn destroy_pbuffer(conn: &Conn, pbuffer: Pbuffer) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyPbufferRequest { pbuffer, }; request0.send(conn) } /// Opcode for the GetDrawableAttributes request pub const GET_DRAWABLE_ATTRIBUTES_REQUEST: u8 = 29; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDrawableAttributesRequest { pub drawable: Drawable, } impl GetDrawableAttributesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DRAWABLE_ATTRIBUTES_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DRAWABLE_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = Drawable::try_parse(value)?; let _ = remaining; Ok(GetDrawableAttributesRequest { drawable, }) } } impl Request for GetDrawableAttributesRequest { type Reply = GetDrawableAttributesReply; } pub fn get_drawable_attributes(conn: &Conn, drawable: Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDrawableAttributesRequest { drawable, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDrawableAttributesReply { pub sequence: u16, pub length: u32, pub attribs: Vec, } impl TryParse for GetDrawableAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_attribs, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (attribs, remaining) = crate::x11_utils::parse_list::(remaining, num_attribs.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDrawableAttributesReply { sequence, length, attribs }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDrawableAttributesReply { /// Get the value of the `num_attribs` field. /// /// The `num_attribs` field is used as the length field of the `attribs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_attribs(&self) -> u32 { self.attribs.len() .checked_div(2).unwrap() .try_into().unwrap() } } /// Opcode for the ChangeDrawableAttributes request pub const CHANGE_DRAWABLE_ATTRIBUTES_REQUEST: u8 = 30; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeDrawableAttributesRequest<'input> { pub drawable: Drawable, pub attribs: Cow<'input, [u32]>, } impl<'input> ChangeDrawableAttributesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); assert_eq!(self.attribs.len() % 2, 0, "`attribs` has an incorrect length, must be a multiple of 2"); let num_attribs = u32::try_from(self.attribs.len() / 2).expect("`attribs` has too many elements"); let num_attribs_bytes = num_attribs.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_DRAWABLE_ATTRIBUTES_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], num_attribs_bytes[0], num_attribs_bytes[1], num_attribs_bytes[2], num_attribs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let attribs_bytes = self.attribs.serialize(); let length_so_far = length_so_far + attribs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), attribs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_DRAWABLE_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = Drawable::try_parse(value)?; let (num_attribs, remaining) = u32::try_parse(remaining)?; let (attribs, remaining) = crate::x11_utils::parse_list::(remaining, num_attribs.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(ChangeDrawableAttributesRequest { drawable, attribs: Cow::Owned(attribs), }) } /// Clone all borrowed data in this ChangeDrawableAttributesRequest. pub fn into_owned(self) -> ChangeDrawableAttributesRequest<'static> { ChangeDrawableAttributesRequest { drawable: self.drawable, attribs: Cow::Owned(self.attribs.into_owned()), } } } impl<'input> Request for ChangeDrawableAttributesRequest<'input> { type Reply = (); } pub fn change_drawable_attributes<'c, 'input, Conn>(conn: &'c Conn, drawable: Drawable, attribs: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeDrawableAttributesRequest { drawable, attribs: Cow::Borrowed(attribs), }; request0.send(conn) } /// Opcode for the CreateWindow request pub const CREATE_WINDOW_REQUEST: u8 = 31; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateWindowRequest<'input> { pub screen: u32, pub fbconfig: Fbconfig, pub window: xproto::Window, pub glx_window: Window, pub attribs: Cow<'input, [u32]>, } impl<'input> CreateWindowRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let fbconfig_bytes = self.fbconfig.serialize(); let window_bytes = self.window.serialize(); let glx_window_bytes = self.glx_window.serialize(); assert_eq!(self.attribs.len() % 2, 0, "`attribs` has an incorrect length, must be a multiple of 2"); let num_attribs = u32::try_from(self.attribs.len() / 2).expect("`attribs` has too many elements"); let num_attribs_bytes = num_attribs.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_WINDOW_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], fbconfig_bytes[0], fbconfig_bytes[1], fbconfig_bytes[2], fbconfig_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], glx_window_bytes[0], glx_window_bytes[1], glx_window_bytes[2], glx_window_bytes[3], num_attribs_bytes[0], num_attribs_bytes[1], num_attribs_bytes[2], num_attribs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let attribs_bytes = self.attribs.serialize(); let length_so_far = length_so_far + attribs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), attribs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (fbconfig, remaining) = Fbconfig::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (glx_window, remaining) = Window::try_parse(remaining)?; let (num_attribs, remaining) = u32::try_parse(remaining)?; let (attribs, remaining) = crate::x11_utils::parse_list::(remaining, num_attribs.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(CreateWindowRequest { screen, fbconfig, window, glx_window, attribs: Cow::Owned(attribs), }) } /// Clone all borrowed data in this CreateWindowRequest. pub fn into_owned(self) -> CreateWindowRequest<'static> { CreateWindowRequest { screen: self.screen, fbconfig: self.fbconfig, window: self.window, glx_window: self.glx_window, attribs: Cow::Owned(self.attribs.into_owned()), } } } impl<'input> Request for CreateWindowRequest<'input> { type Reply = (); } pub fn create_window<'c, 'input, Conn>(conn: &'c Conn, screen: u32, fbconfig: Fbconfig, window: xproto::Window, glx_window: Window, attribs: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateWindowRequest { screen, fbconfig, window, glx_window, attribs: Cow::Borrowed(attribs), }; request0.send(conn) } /// Opcode for the DeleteWindow request pub const DELETE_WINDOW_REQUEST: u8 = 32; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeleteWindowRequest { pub glxwindow: Window, } impl DeleteWindowRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let glxwindow_bytes = self.glxwindow.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_WINDOW_REQUEST, 0, 0, glxwindow_bytes[0], glxwindow_bytes[1], glxwindow_bytes[2], glxwindow_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let (glxwindow, remaining) = Window::try_parse(value)?; let _ = remaining; Ok(DeleteWindowRequest { glxwindow, }) } } impl Request for DeleteWindowRequest { type Reply = (); } pub fn delete_window(conn: &Conn, glxwindow: Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteWindowRequest { glxwindow, }; request0.send(conn) } /// Opcode for the SetClientInfoARB request pub const SET_CLIENT_INFO_ARB_REQUEST: u8 = 33; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetClientInfoARBRequest<'input> { pub major_version: u32, pub minor_version: u32, pub gl_versions: Cow<'input, [u32]>, pub gl_extension_string: Cow<'input, [u8]>, pub glx_extension_string: Cow<'input, [u8]>, } impl<'input> SetClientInfoARBRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); assert_eq!(self.gl_versions.len() % 2, 0, "`gl_versions` has an incorrect length, must be a multiple of 2"); let num_versions = u32::try_from(self.gl_versions.len() / 2).expect("`gl_versions` has too many elements"); let num_versions_bytes = num_versions.serialize(); let gl_str_len = u32::try_from(self.gl_extension_string.len()).expect("`gl_extension_string` has too many elements"); let gl_str_len_bytes = gl_str_len.serialize(); let glx_str_len = u32::try_from(self.glx_extension_string.len()).expect("`glx_extension_string` has too many elements"); let glx_str_len_bytes = glx_str_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CLIENT_INFO_ARB_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], major_version_bytes[2], major_version_bytes[3], minor_version_bytes[0], minor_version_bytes[1], minor_version_bytes[2], minor_version_bytes[3], num_versions_bytes[0], num_versions_bytes[1], num_versions_bytes[2], num_versions_bytes[3], gl_str_len_bytes[0], gl_str_len_bytes[1], gl_str_len_bytes[2], gl_str_len_bytes[3], glx_str_len_bytes[0], glx_str_len_bytes[1], glx_str_len_bytes[2], glx_str_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let gl_versions_bytes = self.gl_versions.serialize(); let length_so_far = length_so_far + gl_versions_bytes.len(); let length_so_far = length_so_far + self.gl_extension_string.len(); let length_so_far = length_so_far + self.glx_extension_string.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), gl_versions_bytes.into(), self.gl_extension_string, self.glx_extension_string, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_CLIENT_INFO_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u32::try_parse(value)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let (num_versions, remaining) = u32::try_parse(remaining)?; let (gl_str_len, remaining) = u32::try_parse(remaining)?; let (glx_str_len, remaining) = u32::try_parse(remaining)?; let (gl_versions, remaining) = crate::x11_utils::parse_list::(remaining, num_versions.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let (gl_extension_string, remaining) = crate::x11_utils::parse_u8_list(remaining, gl_str_len.try_to_usize()?)?; let (glx_extension_string, remaining) = crate::x11_utils::parse_u8_list(remaining, glx_str_len.try_to_usize()?)?; let _ = remaining; Ok(SetClientInfoARBRequest { major_version, minor_version, gl_versions: Cow::Owned(gl_versions), gl_extension_string: Cow::Borrowed(gl_extension_string), glx_extension_string: Cow::Borrowed(glx_extension_string), }) } /// Clone all borrowed data in this SetClientInfoARBRequest. pub fn into_owned(self) -> SetClientInfoARBRequest<'static> { SetClientInfoARBRequest { major_version: self.major_version, minor_version: self.minor_version, gl_versions: Cow::Owned(self.gl_versions.into_owned()), gl_extension_string: Cow::Owned(self.gl_extension_string.into_owned()), glx_extension_string: Cow::Owned(self.glx_extension_string.into_owned()), } } } impl<'input> Request for SetClientInfoARBRequest<'input> { type Reply = (); } pub fn set_client_info_arb<'c, 'input, Conn>(conn: &'c Conn, major_version: u32, minor_version: u32, gl_versions: &'input [u32], gl_extension_string: &'input [u8], glx_extension_string: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetClientInfoARBRequest { major_version, minor_version, gl_versions: Cow::Borrowed(gl_versions), gl_extension_string: Cow::Borrowed(gl_extension_string), glx_extension_string: Cow::Borrowed(glx_extension_string), }; request0.send(conn) } /// Opcode for the CreateContextAttribsARB request pub const CREATE_CONTEXT_ATTRIBS_ARB_REQUEST: u8 = 34; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateContextAttribsARBRequest<'input> { pub context: Context, pub fbconfig: Fbconfig, pub screen: u32, pub share_list: Context, pub is_direct: bool, pub attribs: Cow<'input, [u32]>, } impl<'input> CreateContextAttribsARBRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let fbconfig_bytes = self.fbconfig.serialize(); let screen_bytes = self.screen.serialize(); let share_list_bytes = self.share_list.serialize(); let is_direct_bytes = self.is_direct.serialize(); assert_eq!(self.attribs.len() % 2, 0, "`attribs` has an incorrect length, must be a multiple of 2"); let num_attribs = u32::try_from(self.attribs.len() / 2).expect("`attribs` has too many elements"); let num_attribs_bytes = num_attribs.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CONTEXT_ATTRIBS_ARB_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], fbconfig_bytes[0], fbconfig_bytes[1], fbconfig_bytes[2], fbconfig_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], share_list_bytes[0], share_list_bytes[1], share_list_bytes[2], share_list_bytes[3], is_direct_bytes[0], 0, 0, 0, num_attribs_bytes[0], num_attribs_bytes[1], num_attribs_bytes[2], num_attribs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let attribs_bytes = self.attribs.serialize(); let length_so_far = length_so_far + attribs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), attribs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_CONTEXT_ATTRIBS_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let (fbconfig, remaining) = Fbconfig::try_parse(remaining)?; let (screen, remaining) = u32::try_parse(remaining)?; let (share_list, remaining) = Context::try_parse(remaining)?; let (is_direct, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (num_attribs, remaining) = u32::try_parse(remaining)?; let (attribs, remaining) = crate::x11_utils::parse_list::(remaining, num_attribs.checked_mul(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(CreateContextAttribsARBRequest { context, fbconfig, screen, share_list, is_direct, attribs: Cow::Owned(attribs), }) } /// Clone all borrowed data in this CreateContextAttribsARBRequest. pub fn into_owned(self) -> CreateContextAttribsARBRequest<'static> { CreateContextAttribsARBRequest { context: self.context, fbconfig: self.fbconfig, screen: self.screen, share_list: self.share_list, is_direct: self.is_direct, attribs: Cow::Owned(self.attribs.into_owned()), } } } impl<'input> Request for CreateContextAttribsARBRequest<'input> { type Reply = (); } pub fn create_context_attribs_arb<'c, 'input, Conn>(conn: &'c Conn, context: Context, fbconfig: Fbconfig, screen: u32, share_list: Context, is_direct: bool, attribs: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateContextAttribsARBRequest { context, fbconfig, screen, share_list, is_direct, attribs: Cow::Borrowed(attribs), }; request0.send(conn) } /// Opcode for the SetClientInfo2ARB request pub const SET_CLIENT_INFO2_ARB_REQUEST: u8 = 35; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetClientInfo2ARBRequest<'input> { pub major_version: u32, pub minor_version: u32, pub gl_versions: Cow<'input, [u32]>, pub gl_extension_string: Cow<'input, [u8]>, pub glx_extension_string: Cow<'input, [u8]>, } impl<'input> SetClientInfo2ARBRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); assert_eq!(self.gl_versions.len() % 3, 0, "`gl_versions` has an incorrect length, must be a multiple of 3"); let num_versions = u32::try_from(self.gl_versions.len() / 3).expect("`gl_versions` has too many elements"); let num_versions_bytes = num_versions.serialize(); let gl_str_len = u32::try_from(self.gl_extension_string.len()).expect("`gl_extension_string` has too many elements"); let gl_str_len_bytes = gl_str_len.serialize(); let glx_str_len = u32::try_from(self.glx_extension_string.len()).expect("`glx_extension_string` has too many elements"); let glx_str_len_bytes = glx_str_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CLIENT_INFO2_ARB_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], major_version_bytes[2], major_version_bytes[3], minor_version_bytes[0], minor_version_bytes[1], minor_version_bytes[2], minor_version_bytes[3], num_versions_bytes[0], num_versions_bytes[1], num_versions_bytes[2], num_versions_bytes[3], gl_str_len_bytes[0], gl_str_len_bytes[1], gl_str_len_bytes[2], gl_str_len_bytes[3], glx_str_len_bytes[0], glx_str_len_bytes[1], glx_str_len_bytes[2], glx_str_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let gl_versions_bytes = self.gl_versions.serialize(); let length_so_far = length_so_far + gl_versions_bytes.len(); let length_so_far = length_so_far + self.gl_extension_string.len(); let length_so_far = length_so_far + self.glx_extension_string.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), gl_versions_bytes.into(), self.gl_extension_string, self.glx_extension_string, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_CLIENT_INFO2_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u32::try_parse(value)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let (num_versions, remaining) = u32::try_parse(remaining)?; let (gl_str_len, remaining) = u32::try_parse(remaining)?; let (glx_str_len, remaining) = u32::try_parse(remaining)?; let (gl_versions, remaining) = crate::x11_utils::parse_list::(remaining, num_versions.checked_mul(3u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let (gl_extension_string, remaining) = crate::x11_utils::parse_u8_list(remaining, gl_str_len.try_to_usize()?)?; let (glx_extension_string, remaining) = crate::x11_utils::parse_u8_list(remaining, glx_str_len.try_to_usize()?)?; let _ = remaining; Ok(SetClientInfo2ARBRequest { major_version, minor_version, gl_versions: Cow::Owned(gl_versions), gl_extension_string: Cow::Borrowed(gl_extension_string), glx_extension_string: Cow::Borrowed(glx_extension_string), }) } /// Clone all borrowed data in this SetClientInfo2ARBRequest. pub fn into_owned(self) -> SetClientInfo2ARBRequest<'static> { SetClientInfo2ARBRequest { major_version: self.major_version, minor_version: self.minor_version, gl_versions: Cow::Owned(self.gl_versions.into_owned()), gl_extension_string: Cow::Owned(self.gl_extension_string.into_owned()), glx_extension_string: Cow::Owned(self.glx_extension_string.into_owned()), } } } impl<'input> Request for SetClientInfo2ARBRequest<'input> { type Reply = (); } pub fn set_client_info2_arb<'c, 'input, Conn>(conn: &'c Conn, major_version: u32, minor_version: u32, gl_versions: &'input [u32], gl_extension_string: &'input [u8], glx_extension_string: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetClientInfo2ARBRequest { major_version, minor_version, gl_versions: Cow::Borrowed(gl_versions), gl_extension_string: Cow::Borrowed(gl_extension_string), glx_extension_string: Cow::Borrowed(glx_extension_string), }; request0.send(conn) } /// Opcode for the NewList request pub const NEW_LIST_REQUEST: u8 = 101; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NewListRequest { pub context_tag: ContextTag, pub list: u32, pub mode: u32, } impl NewListRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let list_bytes = self.list.serialize(); let mode_bytes = self.mode.serialize(); let mut request0 = vec![ extension_information.major_opcode, NEW_LIST_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], list_bytes[0], list_bytes[1], list_bytes[2], list_bytes[3], mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != NEW_LIST_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (list, remaining) = u32::try_parse(remaining)?; let (mode, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(NewListRequest { context_tag, list, mode, }) } } impl Request for NewListRequest { type Reply = (); } pub fn new_list(conn: &Conn, context_tag: ContextTag, list: u32, mode: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = NewListRequest { context_tag, list, mode, }; request0.send(conn) } /// Opcode for the EndList request pub const END_LIST_REQUEST: u8 = 102; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EndListRequest { pub context_tag: ContextTag, } impl EndListRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, END_LIST_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != END_LIST_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let _ = remaining; Ok(EndListRequest { context_tag, }) } } impl Request for EndListRequest { type Reply = (); } pub fn end_list(conn: &Conn, context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = EndListRequest { context_tag, }; request0.send(conn) } /// Opcode for the DeleteLists request pub const DELETE_LISTS_REQUEST: u8 = 103; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeleteListsRequest { pub context_tag: ContextTag, pub list: u32, pub range: i32, } impl DeleteListsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let list_bytes = self.list.serialize(); let range_bytes = self.range.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_LISTS_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], list_bytes[0], list_bytes[1], list_bytes[2], list_bytes[3], range_bytes[0], range_bytes[1], range_bytes[2], range_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_LISTS_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (list, remaining) = u32::try_parse(remaining)?; let (range, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(DeleteListsRequest { context_tag, list, range, }) } } impl Request for DeleteListsRequest { type Reply = (); } pub fn delete_lists(conn: &Conn, context_tag: ContextTag, list: u32, range: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteListsRequest { context_tag, list, range, }; request0.send(conn) } /// Opcode for the GenLists request pub const GEN_LISTS_REQUEST: u8 = 104; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GenListsRequest { pub context_tag: ContextTag, pub range: i32, } impl GenListsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let range_bytes = self.range.serialize(); let mut request0 = vec![ extension_information.major_opcode, GEN_LISTS_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], range_bytes[0], range_bytes[1], range_bytes[2], range_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GEN_LISTS_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (range, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(GenListsRequest { context_tag, range, }) } } impl Request for GenListsRequest { type Reply = GenListsReply; } pub fn gen_lists(conn: &Conn, context_tag: ContextTag, range: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GenListsRequest { context_tag, range, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GenListsReply { pub sequence: u16, pub length: u32, pub ret_val: u32, } impl TryParse for GenListsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ret_val, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GenListsReply { sequence, length, ret_val }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the FeedbackBuffer request pub const FEEDBACK_BUFFER_REQUEST: u8 = 105; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackBufferRequest { pub context_tag: ContextTag, pub size: i32, pub type_: i32, } impl FeedbackBufferRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let size_bytes = self.size.serialize(); let type_bytes = self.type_.serialize(); let mut request0 = vec![ extension_information.major_opcode, FEEDBACK_BUFFER_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], size_bytes[0], size_bytes[1], size_bytes[2], size_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FEEDBACK_BUFFER_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (size, remaining) = i32::try_parse(remaining)?; let (type_, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(FeedbackBufferRequest { context_tag, size, type_, }) } } impl Request for FeedbackBufferRequest { type Reply = (); } pub fn feedback_buffer(conn: &Conn, context_tag: ContextTag, size: i32, type_: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FeedbackBufferRequest { context_tag, size, type_, }; request0.send(conn) } /// Opcode for the SelectBuffer request pub const SELECT_BUFFER_REQUEST: u8 = 106; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectBufferRequest { pub context_tag: ContextTag, pub size: i32, } impl SelectBufferRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let size_bytes = self.size.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_BUFFER_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], size_bytes[0], size_bytes[1], size_bytes[2], size_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_BUFFER_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (size, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(SelectBufferRequest { context_tag, size, }) } } impl Request for SelectBufferRequest { type Reply = (); } pub fn select_buffer(conn: &Conn, context_tag: ContextTag, size: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SelectBufferRequest { context_tag, size, }; request0.send(conn) } /// Opcode for the RenderMode request pub const RENDER_MODE_REQUEST: u8 = 107; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct RenderModeRequest { pub context_tag: ContextTag, pub mode: u32, } impl RenderModeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mode_bytes = self.mode.serialize(); let mut request0 = vec![ extension_information.major_opcode, RENDER_MODE_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != RENDER_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (mode, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(RenderModeRequest { context_tag, mode, }) } } impl Request for RenderModeRequest { type Reply = RenderModeReply; } pub fn render_mode(conn: &Conn, context_tag: ContextTag, mode: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RenderModeRequest { context_tag, mode, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct RenderModeReply { pub sequence: u16, pub length: u32, pub ret_val: u32, pub new_mode: u32, pub data: Vec, } impl TryParse for RenderModeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ret_val, remaining) = u32::try_parse(remaining)?; let (n, remaining) = u32::try_parse(remaining)?; let (new_mode, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = RenderModeReply { sequence, length, ret_val, new_mode, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl RenderModeReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct RM(u16); impl RM { pub const GL_RENDER: Self = Self(7168); pub const GL_FEEDBACK: Self = Self(7169); pub const GL_SELECT: Self = Self(7170); } impl From for u16 { #[inline] fn from(input: RM) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: RM) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: RM) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: RM) -> Self { Some(u32::from(input.0)) } } impl From for RM { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for RM { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for RM { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::GL_RENDER.0.into(), "GL_RENDER", "GL_RENDER"), (Self::GL_FEEDBACK.0.into(), "GL_FEEDBACK", "GL_FEEDBACK"), (Self::GL_SELECT.0.into(), "GL_SELECT", "GL_SELECT"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the Finish request pub const FINISH_REQUEST: u8 = 108; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FinishRequest { pub context_tag: ContextTag, } impl FinishRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, FINISH_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FINISH_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let _ = remaining; Ok(FinishRequest { context_tag, }) } } impl Request for FinishRequest { type Reply = FinishReply; } pub fn finish(conn: &Conn, context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FinishRequest { context_tag, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FinishReply { pub sequence: u16, pub length: u32, } impl TryParse for FinishReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = FinishReply { sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PixelStoref request pub const PIXEL_STOREF_REQUEST: u8 = 109; #[derive(Debug, Clone, Copy, PartialEq)] pub struct PixelStorefRequest { pub context_tag: ContextTag, pub pname: u32, pub datum: Float32, } impl PixelStorefRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let pname_bytes = self.pname.serialize(); let datum_bytes = self.datum.serialize(); let mut request0 = vec![ extension_information.major_opcode, PIXEL_STOREF_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], datum_bytes[0], datum_bytes[1], datum_bytes[2], datum_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PIXEL_STOREF_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (pname, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let _ = remaining; Ok(PixelStorefRequest { context_tag, pname, datum, }) } } impl Request for PixelStorefRequest { type Reply = (); } pub fn pixel_storef(conn: &Conn, context_tag: ContextTag, pname: u32, datum: Float32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PixelStorefRequest { context_tag, pname, datum, }; request0.send(conn) } /// Opcode for the PixelStorei request pub const PIXEL_STOREI_REQUEST: u8 = 110; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PixelStoreiRequest { pub context_tag: ContextTag, pub pname: u32, pub datum: i32, } impl PixelStoreiRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let pname_bytes = self.pname.serialize(); let datum_bytes = self.datum.serialize(); let mut request0 = vec![ extension_information.major_opcode, PIXEL_STOREI_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], datum_bytes[0], datum_bytes[1], datum_bytes[2], datum_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PIXEL_STOREI_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (pname, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(PixelStoreiRequest { context_tag, pname, datum, }) } } impl Request for PixelStoreiRequest { type Reply = (); } pub fn pixel_storei(conn: &Conn, context_tag: ContextTag, pname: u32, datum: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PixelStoreiRequest { context_tag, pname, datum, }; request0.send(conn) } /// Opcode for the ReadPixels request pub const READ_PIXELS_REQUEST: u8 = 111; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ReadPixelsRequest { pub context_tag: ContextTag, pub x: i32, pub y: i32, pub width: i32, pub height: i32, pub format: u32, pub type_: u32, pub swap_bytes: bool, pub lsb_first: bool, } impl ReadPixelsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let format_bytes = self.format.serialize(); let type_bytes = self.type_.serialize(); let swap_bytes_bytes = self.swap_bytes.serialize(); let lsb_first_bytes = self.lsb_first.serialize(); let mut request0 = vec![ extension_information.major_opcode, READ_PIXELS_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], x_bytes[0], x_bytes[1], x_bytes[2], x_bytes[3], y_bytes[0], y_bytes[1], y_bytes[2], y_bytes[3], width_bytes[0], width_bytes[1], width_bytes[2], width_bytes[3], height_bytes[0], height_bytes[1], height_bytes[2], height_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], swap_bytes_bytes[0], lsb_first_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != READ_PIXELS_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (x, remaining) = i32::try_parse(remaining)?; let (y, remaining) = i32::try_parse(remaining)?; let (width, remaining) = i32::try_parse(remaining)?; let (height, remaining) = i32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let (swap_bytes, remaining) = bool::try_parse(remaining)?; let (lsb_first, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(ReadPixelsRequest { context_tag, x, y, width, height, format, type_, swap_bytes, lsb_first, }) } } impl Request for ReadPixelsRequest { type Reply = ReadPixelsReply; } pub fn read_pixels(conn: &Conn, context_tag: ContextTag, x: i32, y: i32, width: i32, height: i32, format: u32, type_: u32, swap_bytes: bool, lsb_first: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ReadPixelsRequest { context_tag, x, y, width, height, format, type_, swap_bytes, lsb_first, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ReadPixelsReply { pub sequence: u16, pub data: Vec, } impl TryParse for ReadPixelsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ReadPixelsReply { sequence, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ReadPixelsReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetBooleanv request pub const GET_BOOLEANV_REQUEST: u8 = 112; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetBooleanvRequest { pub context_tag: ContextTag, pub pname: i32, } impl GetBooleanvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_BOOLEANV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_BOOLEANV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (pname, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(GetBooleanvRequest { context_tag, pname, }) } } impl Request for GetBooleanvRequest { type Reply = GetBooleanvReply; } pub fn get_booleanv(conn: &Conn, context_tag: ContextTag, pname: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetBooleanvRequest { context_tag, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetBooleanvReply { pub sequence: u16, pub length: u32, pub datum: bool, pub data: Vec, } impl TryParse for GetBooleanvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(15..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetBooleanvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetBooleanvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetClipPlane request pub const GET_CLIP_PLANE_REQUEST: u8 = 113; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetClipPlaneRequest { pub context_tag: ContextTag, pub plane: i32, } impl GetClipPlaneRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let plane_bytes = self.plane.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CLIP_PLANE_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], plane_bytes[0], plane_bytes[1], plane_bytes[2], plane_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CLIP_PLANE_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (plane, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(GetClipPlaneRequest { context_tag, plane, }) } } impl Request for GetClipPlaneRequest { type Reply = GetClipPlaneReply; } pub fn get_clip_plane(conn: &Conn, context_tag: ContextTag, plane: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetClipPlaneRequest { context_tag, plane, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetClipPlaneReply { pub sequence: u16, pub data: Vec, } impl TryParse for GetClipPlaneReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, length.checked_div(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetClipPlaneReply { sequence, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetClipPlaneReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_mul(2).unwrap() .try_into().unwrap() } } /// Opcode for the GetDoublev request pub const GET_DOUBLEV_REQUEST: u8 = 114; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDoublevRequest { pub context_tag: ContextTag, pub pname: u32, } impl GetDoublevRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DOUBLEV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DOUBLEV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetDoublevRequest { context_tag, pname, }) } } impl Request for GetDoublevRequest { type Reply = GetDoublevReply; } pub fn get_doublev(conn: &Conn, context_tag: ContextTag, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDoublevRequest { context_tag, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetDoublevReply { pub sequence: u16, pub length: u32, pub datum: Float64, pub data: Vec, } impl TryParse for GetDoublevReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float64::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDoublevReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDoublevReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetError request pub const GET_ERROR_REQUEST: u8 = 115; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetErrorRequest { pub context_tag: ContextTag, } impl GetErrorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_ERROR_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_ERROR_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let _ = remaining; Ok(GetErrorRequest { context_tag, }) } } impl Request for GetErrorRequest { type Reply = GetErrorReply; } pub fn get_error(conn: &Conn, context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetErrorRequest { context_tag, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetErrorReply { pub sequence: u16, pub length: u32, pub error: i32, } impl TryParse for GetErrorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (error, remaining) = i32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetErrorReply { sequence, length, error }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetFloatv request pub const GET_FLOATV_REQUEST: u8 = 116; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetFloatvRequest { pub context_tag: ContextTag, pub pname: u32, } impl GetFloatvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_FLOATV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_FLOATV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetFloatvRequest { context_tag, pname, }) } } impl Request for GetFloatvRequest { type Reply = GetFloatvReply; } pub fn get_floatv(conn: &Conn, context_tag: ContextTag, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetFloatvRequest { context_tag, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetFloatvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetFloatvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetFloatvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetFloatvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetIntegerv request pub const GET_INTEGERV_REQUEST: u8 = 117; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetIntegervRequest { pub context_tag: ContextTag, pub pname: u32, } impl GetIntegervRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_INTEGERV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_INTEGERV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetIntegervRequest { context_tag, pname, }) } } impl Request for GetIntegervRequest { type Reply = GetIntegervReply; } pub fn get_integerv(conn: &Conn, context_tag: ContextTag, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetIntegervRequest { context_tag, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetIntegervReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetIntegervReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetIntegervReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetIntegervReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetLightfv request pub const GET_LIGHTFV_REQUEST: u8 = 118; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetLightfvRequest { pub context_tag: ContextTag, pub light: u32, pub pname: u32, } impl GetLightfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let light_bytes = self.light.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_LIGHTFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], light_bytes[0], light_bytes[1], light_bytes[2], light_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_LIGHTFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (light, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetLightfvRequest { context_tag, light, pname, }) } } impl Request for GetLightfvRequest { type Reply = GetLightfvReply; } pub fn get_lightfv(conn: &Conn, context_tag: ContextTag, light: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetLightfvRequest { context_tag, light, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetLightfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetLightfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetLightfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetLightfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetLightiv request pub const GET_LIGHTIV_REQUEST: u8 = 119; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetLightivRequest { pub context_tag: ContextTag, pub light: u32, pub pname: u32, } impl GetLightivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let light_bytes = self.light.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_LIGHTIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], light_bytes[0], light_bytes[1], light_bytes[2], light_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_LIGHTIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (light, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetLightivRequest { context_tag, light, pname, }) } } impl Request for GetLightivRequest { type Reply = GetLightivReply; } pub fn get_lightiv(conn: &Conn, context_tag: ContextTag, light: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetLightivRequest { context_tag, light, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetLightivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetLightivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetLightivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetLightivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetMapdv request pub const GET_MAPDV_REQUEST: u8 = 120; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMapdvRequest { pub context_tag: ContextTag, pub target: u32, pub query: u32, } impl GetMapdvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let query_bytes = self.query.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MAPDV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], query_bytes[0], query_bytes[1], query_bytes[2], query_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MAPDV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (query, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetMapdvRequest { context_tag, target, query, }) } } impl Request for GetMapdvRequest { type Reply = GetMapdvReply; } pub fn get_mapdv(conn: &Conn, context_tag: ContextTag, target: u32, query: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMapdvRequest { context_tag, target, query, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetMapdvReply { pub sequence: u16, pub length: u32, pub datum: Float64, pub data: Vec, } impl TryParse for GetMapdvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float64::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMapdvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMapdvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetMapfv request pub const GET_MAPFV_REQUEST: u8 = 121; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMapfvRequest { pub context_tag: ContextTag, pub target: u32, pub query: u32, } impl GetMapfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let query_bytes = self.query.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MAPFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], query_bytes[0], query_bytes[1], query_bytes[2], query_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MAPFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (query, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetMapfvRequest { context_tag, target, query, }) } } impl Request for GetMapfvRequest { type Reply = GetMapfvReply; } pub fn get_mapfv(conn: &Conn, context_tag: ContextTag, target: u32, query: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMapfvRequest { context_tag, target, query, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetMapfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetMapfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMapfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMapfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetMapiv request pub const GET_MAPIV_REQUEST: u8 = 122; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMapivRequest { pub context_tag: ContextTag, pub target: u32, pub query: u32, } impl GetMapivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let query_bytes = self.query.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MAPIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], query_bytes[0], query_bytes[1], query_bytes[2], query_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MAPIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (query, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetMapivRequest { context_tag, target, query, }) } } impl Request for GetMapivRequest { type Reply = GetMapivReply; } pub fn get_mapiv(conn: &Conn, context_tag: ContextTag, target: u32, query: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMapivRequest { context_tag, target, query, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetMapivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetMapivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMapivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMapivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetMaterialfv request pub const GET_MATERIALFV_REQUEST: u8 = 123; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMaterialfvRequest { pub context_tag: ContextTag, pub face: u32, pub pname: u32, } impl GetMaterialfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let face_bytes = self.face.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MATERIALFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], face_bytes[0], face_bytes[1], face_bytes[2], face_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MATERIALFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (face, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetMaterialfvRequest { context_tag, face, pname, }) } } impl Request for GetMaterialfvRequest { type Reply = GetMaterialfvReply; } pub fn get_materialfv(conn: &Conn, context_tag: ContextTag, face: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMaterialfvRequest { context_tag, face, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetMaterialfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetMaterialfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMaterialfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMaterialfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetMaterialiv request pub const GET_MATERIALIV_REQUEST: u8 = 124; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMaterialivRequest { pub context_tag: ContextTag, pub face: u32, pub pname: u32, } impl GetMaterialivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let face_bytes = self.face.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MATERIALIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], face_bytes[0], face_bytes[1], face_bytes[2], face_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MATERIALIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (face, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetMaterialivRequest { context_tag, face, pname, }) } } impl Request for GetMaterialivRequest { type Reply = GetMaterialivReply; } pub fn get_materialiv(conn: &Conn, context_tag: ContextTag, face: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMaterialivRequest { context_tag, face, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetMaterialivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetMaterialivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMaterialivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMaterialivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetPixelMapfv request pub const GET_PIXEL_MAPFV_REQUEST: u8 = 125; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPixelMapfvRequest { pub context_tag: ContextTag, pub map: u32, } impl GetPixelMapfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let map_bytes = self.map.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PIXEL_MAPFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], map_bytes[0], map_bytes[1], map_bytes[2], map_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PIXEL_MAPFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (map, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetPixelMapfvRequest { context_tag, map, }) } } impl Request for GetPixelMapfvRequest { type Reply = GetPixelMapfvReply; } pub fn get_pixel_mapfv(conn: &Conn, context_tag: ContextTag, map: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPixelMapfvRequest { context_tag, map, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetPixelMapfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetPixelMapfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPixelMapfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPixelMapfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetPixelMapuiv request pub const GET_PIXEL_MAPUIV_REQUEST: u8 = 126; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPixelMapuivRequest { pub context_tag: ContextTag, pub map: u32, } impl GetPixelMapuivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let map_bytes = self.map.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PIXEL_MAPUIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], map_bytes[0], map_bytes[1], map_bytes[2], map_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PIXEL_MAPUIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (map, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetPixelMapuivRequest { context_tag, map, }) } } impl Request for GetPixelMapuivRequest { type Reply = GetPixelMapuivReply; } pub fn get_pixel_mapuiv(conn: &Conn, context_tag: ContextTag, map: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPixelMapuivRequest { context_tag, map, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetPixelMapuivReply { pub sequence: u16, pub length: u32, pub datum: u32, pub data: Vec, } impl TryParse for GetPixelMapuivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPixelMapuivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPixelMapuivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetPixelMapusv request pub const GET_PIXEL_MAPUSV_REQUEST: u8 = 127; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPixelMapusvRequest { pub context_tag: ContextTag, pub map: u32, } impl GetPixelMapusvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let map_bytes = self.map.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PIXEL_MAPUSV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], map_bytes[0], map_bytes[1], map_bytes[2], map_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PIXEL_MAPUSV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (map, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetPixelMapusvRequest { context_tag, map, }) } } impl Request for GetPixelMapusvRequest { type Reply = GetPixelMapusvReply; } pub fn get_pixel_mapusv(conn: &Conn, context_tag: ContextTag, map: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPixelMapusvRequest { context_tag, map, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetPixelMapusvReply { pub sequence: u16, pub length: u32, pub datum: u16, pub data: Vec, } impl TryParse for GetPixelMapusvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPixelMapusvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPixelMapusvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetPolygonStipple request pub const GET_POLYGON_STIPPLE_REQUEST: u8 = 128; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPolygonStippleRequest { pub context_tag: ContextTag, pub lsb_first: bool, } impl GetPolygonStippleRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let lsb_first_bytes = self.lsb_first.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_POLYGON_STIPPLE_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], lsb_first_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_POLYGON_STIPPLE_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (lsb_first, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetPolygonStippleRequest { context_tag, lsb_first, }) } } impl Request for GetPolygonStippleRequest { type Reply = GetPolygonStippleReply; } pub fn get_polygon_stipple(conn: &Conn, context_tag: ContextTag, lsb_first: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPolygonStippleRequest { context_tag, lsb_first, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetPolygonStippleReply { pub sequence: u16, pub data: Vec, } impl TryParse for GetPolygonStippleReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPolygonStippleReply { sequence, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPolygonStippleReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetString request pub const GET_STRING_REQUEST: u8 = 129; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetStringRequest { pub context_tag: ContextTag, pub name: u32, } impl GetStringRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let name_bytes = self.name.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_STRING_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_STRING_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (name, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetStringRequest { context_tag, name, }) } } impl Request for GetStringRequest { type Reply = GetStringReply; } pub fn get_string(conn: &Conn, context_tag: ContextTag, name: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetStringRequest { context_tag, name, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetStringReply { pub sequence: u16, pub length: u32, pub string: Vec, } impl TryParse for GetStringReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, n.try_to_usize()?)?; let string = string.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetStringReply { sequence, length, string }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetStringReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `string` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.string.len() .try_into().unwrap() } } /// Opcode for the GetTexEnvfv request pub const GET_TEX_ENVFV_REQUEST: u8 = 130; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexEnvfvRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetTexEnvfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_ENVFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_ENVFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexEnvfvRequest { context_tag, target, pname, }) } } impl Request for GetTexEnvfvRequest { type Reply = GetTexEnvfvReply; } pub fn get_tex_envfv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexEnvfvRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetTexEnvfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetTexEnvfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexEnvfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexEnvfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexEnviv request pub const GET_TEX_ENVIV_REQUEST: u8 = 131; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexEnvivRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetTexEnvivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_ENVIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_ENVIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexEnvivRequest { context_tag, target, pname, }) } } impl Request for GetTexEnvivRequest { type Reply = GetTexEnvivReply; } pub fn get_tex_enviv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexEnvivRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTexEnvivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetTexEnvivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexEnvivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexEnvivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexGendv request pub const GET_TEX_GENDV_REQUEST: u8 = 132; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexGendvRequest { pub context_tag: ContextTag, pub coord: u32, pub pname: u32, } impl GetTexGendvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let coord_bytes = self.coord.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_GENDV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], coord_bytes[0], coord_bytes[1], coord_bytes[2], coord_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_GENDV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (coord, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexGendvRequest { context_tag, coord, pname, }) } } impl Request for GetTexGendvRequest { type Reply = GetTexGendvReply; } pub fn get_tex_gendv(conn: &Conn, context_tag: ContextTag, coord: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexGendvRequest { context_tag, coord, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetTexGendvReply { pub sequence: u16, pub length: u32, pub datum: Float64, pub data: Vec, } impl TryParse for GetTexGendvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float64::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexGendvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexGendvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexGenfv request pub const GET_TEX_GENFV_REQUEST: u8 = 133; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexGenfvRequest { pub context_tag: ContextTag, pub coord: u32, pub pname: u32, } impl GetTexGenfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let coord_bytes = self.coord.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_GENFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], coord_bytes[0], coord_bytes[1], coord_bytes[2], coord_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_GENFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (coord, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexGenfvRequest { context_tag, coord, pname, }) } } impl Request for GetTexGenfvRequest { type Reply = GetTexGenfvReply; } pub fn get_tex_genfv(conn: &Conn, context_tag: ContextTag, coord: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexGenfvRequest { context_tag, coord, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetTexGenfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetTexGenfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexGenfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexGenfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexGeniv request pub const GET_TEX_GENIV_REQUEST: u8 = 134; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexGenivRequest { pub context_tag: ContextTag, pub coord: u32, pub pname: u32, } impl GetTexGenivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let coord_bytes = self.coord.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_GENIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], coord_bytes[0], coord_bytes[1], coord_bytes[2], coord_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_GENIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (coord, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexGenivRequest { context_tag, coord, pname, }) } } impl Request for GetTexGenivRequest { type Reply = GetTexGenivReply; } pub fn get_tex_geniv(conn: &Conn, context_tag: ContextTag, coord: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexGenivRequest { context_tag, coord, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTexGenivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetTexGenivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexGenivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexGenivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexImage request pub const GET_TEX_IMAGE_REQUEST: u8 = 135; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexImageRequest { pub context_tag: ContextTag, pub target: u32, pub level: i32, pub format: u32, pub type_: u32, pub swap_bytes: bool, } impl GetTexImageRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let level_bytes = self.level.serialize(); let format_bytes = self.format.serialize(); let type_bytes = self.type_.serialize(); let swap_bytes_bytes = self.swap_bytes.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_IMAGE_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], level_bytes[0], level_bytes[1], level_bytes[2], level_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], swap_bytes_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_IMAGE_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (level, remaining) = i32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let (swap_bytes, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetTexImageRequest { context_tag, target, level, format, type_, swap_bytes, }) } } impl Request for GetTexImageRequest { type Reply = GetTexImageReply; } pub fn get_tex_image(conn: &Conn, context_tag: ContextTag, target: u32, level: i32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexImageRequest { context_tag, target, level, format, type_, swap_bytes, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTexImageReply { pub sequence: u16, pub width: i32, pub height: i32, pub depth: i32, pub data: Vec, } impl TryParse for GetTexImageReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (width, remaining) = i32::try_parse(remaining)?; let (height, remaining) = i32::try_parse(remaining)?; let (depth, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexImageReply { sequence, width, height, depth, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexImageReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetTexParameterfv request pub const GET_TEX_PARAMETERFV_REQUEST: u8 = 136; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexParameterfvRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetTexParameterfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_PARAMETERFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_PARAMETERFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexParameterfvRequest { context_tag, target, pname, }) } } impl Request for GetTexParameterfvRequest { type Reply = GetTexParameterfvReply; } pub fn get_tex_parameterfv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexParameterfvRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetTexParameterfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetTexParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexParameterfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexParameterfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexParameteriv request pub const GET_TEX_PARAMETERIV_REQUEST: u8 = 137; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexParameterivRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetTexParameterivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_PARAMETERIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_PARAMETERIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexParameterivRequest { context_tag, target, pname, }) } } impl Request for GetTexParameterivRequest { type Reply = GetTexParameterivReply; } pub fn get_tex_parameteriv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexParameterivRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTexParameterivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetTexParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexParameterivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexParameterivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexLevelParameterfv request pub const GET_TEX_LEVEL_PARAMETERFV_REQUEST: u8 = 138; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexLevelParameterfvRequest { pub context_tag: ContextTag, pub target: u32, pub level: i32, pub pname: u32, } impl GetTexLevelParameterfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let level_bytes = self.level.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_LEVEL_PARAMETERFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], level_bytes[0], level_bytes[1], level_bytes[2], level_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_LEVEL_PARAMETERFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (level, remaining) = i32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexLevelParameterfvRequest { context_tag, target, level, pname, }) } } impl Request for GetTexLevelParameterfvRequest { type Reply = GetTexLevelParameterfvReply; } pub fn get_tex_level_parameterfv(conn: &Conn, context_tag: ContextTag, target: u32, level: i32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexLevelParameterfvRequest { context_tag, target, level, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetTexLevelParameterfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetTexLevelParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexLevelParameterfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexLevelParameterfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetTexLevelParameteriv request pub const GET_TEX_LEVEL_PARAMETERIV_REQUEST: u8 = 139; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetTexLevelParameterivRequest { pub context_tag: ContextTag, pub target: u32, pub level: i32, pub pname: u32, } impl GetTexLevelParameterivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let level_bytes = self.level.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_TEX_LEVEL_PARAMETERIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], level_bytes[0], level_bytes[1], level_bytes[2], level_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_TEX_LEVEL_PARAMETERIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (level, remaining) = i32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetTexLevelParameterivRequest { context_tag, target, level, pname, }) } } impl Request for GetTexLevelParameterivRequest { type Reply = GetTexLevelParameterivReply; } pub fn get_tex_level_parameteriv(conn: &Conn, context_tag: ContextTag, target: u32, level: i32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetTexLevelParameterivRequest { context_tag, target, level, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetTexLevelParameterivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetTexLevelParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetTexLevelParameterivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetTexLevelParameterivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the IsEnabled request pub const IS_ENABLED_REQUEST: u8 = 140; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsEnabledRequest { pub context_tag: ContextTag, pub capability: u32, } impl IsEnabledRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let capability_bytes = self.capability.serialize(); let mut request0 = vec![ extension_information.major_opcode, IS_ENABLED_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], capability_bytes[0], capability_bytes[1], capability_bytes[2], capability_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != IS_ENABLED_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (capability, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(IsEnabledRequest { context_tag, capability, }) } } impl Request for IsEnabledRequest { type Reply = IsEnabledReply; } pub fn is_enabled(conn: &Conn, context_tag: ContextTag, capability: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = IsEnabledRequest { context_tag, capability, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsEnabledReply { pub sequence: u16, pub length: u32, pub ret_val: Bool32, } impl TryParse for IsEnabledReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ret_val, remaining) = Bool32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = IsEnabledReply { sequence, length, ret_val }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the IsList request pub const IS_LIST_REQUEST: u8 = 141; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsListRequest { pub context_tag: ContextTag, pub list: u32, } impl IsListRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let list_bytes = self.list.serialize(); let mut request0 = vec![ extension_information.major_opcode, IS_LIST_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], list_bytes[0], list_bytes[1], list_bytes[2], list_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != IS_LIST_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (list, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(IsListRequest { context_tag, list, }) } } impl Request for IsListRequest { type Reply = IsListReply; } pub fn is_list(conn: &Conn, context_tag: ContextTag, list: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = IsListRequest { context_tag, list, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsListReply { pub sequence: u16, pub length: u32, pub ret_val: Bool32, } impl TryParse for IsListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ret_val, remaining) = Bool32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = IsListReply { sequence, length, ret_val }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Flush request pub const FLUSH_REQUEST: u8 = 142; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FlushRequest { pub context_tag: ContextTag, } impl FlushRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let mut request0 = vec![ extension_information.major_opcode, FLUSH_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FLUSH_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let _ = remaining; Ok(FlushRequest { context_tag, }) } } impl Request for FlushRequest { type Reply = (); } pub fn flush(conn: &Conn, context_tag: ContextTag) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FlushRequest { context_tag, }; request0.send(conn) } /// Opcode for the AreTexturesResident request pub const ARE_TEXTURES_RESIDENT_REQUEST: u8 = 143; #[derive(Debug, Clone, PartialEq, Eq)] pub struct AreTexturesResidentRequest<'input> { pub context_tag: ContextTag, pub textures: Cow<'input, [u32]>, } impl<'input> AreTexturesResidentRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let n = i32::try_from(self.textures.len()).expect("`textures` has too many elements"); let n_bytes = n.serialize(); let mut request0 = vec![ extension_information.major_opcode, ARE_TEXTURES_RESIDENT_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], n_bytes[0], n_bytes[1], n_bytes[2], n_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let textures_bytes = self.textures.serialize(); let length_so_far = length_so_far + textures_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), textures_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != ARE_TEXTURES_RESIDENT_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (n, remaining) = i32::try_parse(remaining)?; let (textures, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; let _ = remaining; Ok(AreTexturesResidentRequest { context_tag, textures: Cow::Owned(textures), }) } /// Clone all borrowed data in this AreTexturesResidentRequest. pub fn into_owned(self) -> AreTexturesResidentRequest<'static> { AreTexturesResidentRequest { context_tag: self.context_tag, textures: Cow::Owned(self.textures.into_owned()), } } } impl<'input> Request for AreTexturesResidentRequest<'input> { type Reply = AreTexturesResidentReply; } pub fn are_textures_resident<'c, 'input, Conn>(conn: &'c Conn, context_tag: ContextTag, textures: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AreTexturesResidentRequest { context_tag, textures: Cow::Borrowed(textures), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct AreTexturesResidentReply { pub sequence: u16, pub ret_val: Bool32, pub data: Vec, } impl TryParse for AreTexturesResidentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ret_val, remaining) = Bool32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = AreTexturesResidentReply { sequence, ret_val, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl AreTexturesResidentReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the DeleteTextures request pub const DELETE_TEXTURES_REQUEST: u8 = 144; #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeleteTexturesRequest<'input> { pub context_tag: ContextTag, pub textures: Cow<'input, [u32]>, } impl<'input> DeleteTexturesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let n = i32::try_from(self.textures.len()).expect("`textures` has too many elements"); let n_bytes = n.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_TEXTURES_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], n_bytes[0], n_bytes[1], n_bytes[2], n_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let textures_bytes = self.textures.serialize(); let length_so_far = length_so_far + textures_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), textures_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != DELETE_TEXTURES_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (n, remaining) = i32::try_parse(remaining)?; let (textures, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; let _ = remaining; Ok(DeleteTexturesRequest { context_tag, textures: Cow::Owned(textures), }) } /// Clone all borrowed data in this DeleteTexturesRequest. pub fn into_owned(self) -> DeleteTexturesRequest<'static> { DeleteTexturesRequest { context_tag: self.context_tag, textures: Cow::Owned(self.textures.into_owned()), } } } impl<'input> Request for DeleteTexturesRequest<'input> { type Reply = (); } pub fn delete_textures<'c, 'input, Conn>(conn: &'c Conn, context_tag: ContextTag, textures: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteTexturesRequest { context_tag, textures: Cow::Borrowed(textures), }; request0.send(conn) } /// Opcode for the GenTextures request pub const GEN_TEXTURES_REQUEST: u8 = 145; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GenTexturesRequest { pub context_tag: ContextTag, pub n: i32, } impl GenTexturesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let n_bytes = self.n.serialize(); let mut request0 = vec![ extension_information.major_opcode, GEN_TEXTURES_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], n_bytes[0], n_bytes[1], n_bytes[2], n_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GEN_TEXTURES_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (n, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(GenTexturesRequest { context_tag, n, }) } } impl Request for GenTexturesRequest { type Reply = GenTexturesReply; } pub fn gen_textures(conn: &Conn, context_tag: ContextTag, n: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GenTexturesRequest { context_tag, n, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GenTexturesReply { pub sequence: u16, pub data: Vec, } impl TryParse for GenTexturesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GenTexturesReply { sequence, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GenTexturesReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the IsTexture request pub const IS_TEXTURE_REQUEST: u8 = 146; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsTextureRequest { pub context_tag: ContextTag, pub texture: u32, } impl IsTextureRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let texture_bytes = self.texture.serialize(); let mut request0 = vec![ extension_information.major_opcode, IS_TEXTURE_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], texture_bytes[0], texture_bytes[1], texture_bytes[2], texture_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != IS_TEXTURE_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (texture, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(IsTextureRequest { context_tag, texture, }) } } impl Request for IsTextureRequest { type Reply = IsTextureReply; } pub fn is_texture(conn: &Conn, context_tag: ContextTag, texture: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = IsTextureRequest { context_tag, texture, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsTextureReply { pub sequence: u16, pub length: u32, pub ret_val: Bool32, } impl TryParse for IsTextureReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ret_val, remaining) = Bool32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = IsTextureReply { sequence, length, ret_val }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetColorTable request pub const GET_COLOR_TABLE_REQUEST: u8 = 147; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetColorTableRequest { pub context_tag: ContextTag, pub target: u32, pub format: u32, pub type_: u32, pub swap_bytes: bool, } impl GetColorTableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let format_bytes = self.format.serialize(); let type_bytes = self.type_.serialize(); let swap_bytes_bytes = self.swap_bytes.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_COLOR_TABLE_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], swap_bytes_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_COLOR_TABLE_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let (swap_bytes, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetColorTableRequest { context_tag, target, format, type_, swap_bytes, }) } } impl Request for GetColorTableRequest { type Reply = GetColorTableReply; } pub fn get_color_table(conn: &Conn, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetColorTableRequest { context_tag, target, format, type_, swap_bytes, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetColorTableReply { pub sequence: u16, pub width: i32, pub data: Vec, } impl TryParse for GetColorTableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (width, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetColorTableReply { sequence, width, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetColorTableReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetColorTableParameterfv request pub const GET_COLOR_TABLE_PARAMETERFV_REQUEST: u8 = 148; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetColorTableParameterfvRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetColorTableParameterfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_COLOR_TABLE_PARAMETERFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_COLOR_TABLE_PARAMETERFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetColorTableParameterfvRequest { context_tag, target, pname, }) } } impl Request for GetColorTableParameterfvRequest { type Reply = GetColorTableParameterfvReply; } pub fn get_color_table_parameterfv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetColorTableParameterfvRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetColorTableParameterfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetColorTableParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetColorTableParameterfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetColorTableParameterfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetColorTableParameteriv request pub const GET_COLOR_TABLE_PARAMETERIV_REQUEST: u8 = 149; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetColorTableParameterivRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetColorTableParameterivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_COLOR_TABLE_PARAMETERIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_COLOR_TABLE_PARAMETERIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetColorTableParameterivRequest { context_tag, target, pname, }) } } impl Request for GetColorTableParameterivRequest { type Reply = GetColorTableParameterivReply; } pub fn get_color_table_parameteriv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetColorTableParameterivRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetColorTableParameterivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetColorTableParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetColorTableParameterivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetColorTableParameterivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetConvolutionFilter request pub const GET_CONVOLUTION_FILTER_REQUEST: u8 = 150; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetConvolutionFilterRequest { pub context_tag: ContextTag, pub target: u32, pub format: u32, pub type_: u32, pub swap_bytes: bool, } impl GetConvolutionFilterRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let format_bytes = self.format.serialize(); let type_bytes = self.type_.serialize(); let swap_bytes_bytes = self.swap_bytes.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CONVOLUTION_FILTER_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], swap_bytes_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CONVOLUTION_FILTER_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let (swap_bytes, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetConvolutionFilterRequest { context_tag, target, format, type_, swap_bytes, }) } } impl Request for GetConvolutionFilterRequest { type Reply = GetConvolutionFilterReply; } pub fn get_convolution_filter(conn: &Conn, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetConvolutionFilterRequest { context_tag, target, format, type_, swap_bytes, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetConvolutionFilterReply { pub sequence: u16, pub width: i32, pub height: i32, pub data: Vec, } impl TryParse for GetConvolutionFilterReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (width, remaining) = i32::try_parse(remaining)?; let (height, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetConvolutionFilterReply { sequence, width, height, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetConvolutionFilterReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetConvolutionParameterfv request pub const GET_CONVOLUTION_PARAMETERFV_REQUEST: u8 = 151; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetConvolutionParameterfvRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetConvolutionParameterfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CONVOLUTION_PARAMETERFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CONVOLUTION_PARAMETERFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetConvolutionParameterfvRequest { context_tag, target, pname, }) } } impl Request for GetConvolutionParameterfvRequest { type Reply = GetConvolutionParameterfvReply; } pub fn get_convolution_parameterfv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetConvolutionParameterfvRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetConvolutionParameterfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetConvolutionParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetConvolutionParameterfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetConvolutionParameterfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetConvolutionParameteriv request pub const GET_CONVOLUTION_PARAMETERIV_REQUEST: u8 = 152; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetConvolutionParameterivRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetConvolutionParameterivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CONVOLUTION_PARAMETERIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CONVOLUTION_PARAMETERIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetConvolutionParameterivRequest { context_tag, target, pname, }) } } impl Request for GetConvolutionParameterivRequest { type Reply = GetConvolutionParameterivReply; } pub fn get_convolution_parameteriv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetConvolutionParameterivRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetConvolutionParameterivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetConvolutionParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetConvolutionParameterivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetConvolutionParameterivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetSeparableFilter request pub const GET_SEPARABLE_FILTER_REQUEST: u8 = 153; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetSeparableFilterRequest { pub context_tag: ContextTag, pub target: u32, pub format: u32, pub type_: u32, pub swap_bytes: bool, } impl GetSeparableFilterRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let format_bytes = self.format.serialize(); let type_bytes = self.type_.serialize(); let swap_bytes_bytes = self.swap_bytes.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SEPARABLE_FILTER_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], swap_bytes_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SEPARABLE_FILTER_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let (swap_bytes, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetSeparableFilterRequest { context_tag, target, format, type_, swap_bytes, }) } } impl Request for GetSeparableFilterRequest { type Reply = GetSeparableFilterReply; } pub fn get_separable_filter(conn: &Conn, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetSeparableFilterRequest { context_tag, target, format, type_, swap_bytes, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetSeparableFilterReply { pub sequence: u16, pub row_w: i32, pub col_h: i32, pub rows_and_cols: Vec, } impl TryParse for GetSeparableFilterReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (row_w, remaining) = i32::try_parse(remaining)?; let (col_h, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (rows_and_cols, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let rows_and_cols = rows_and_cols.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetSeparableFilterReply { sequence, row_w, col_h, rows_and_cols }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetSeparableFilterReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `rows_and_cols` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.rows_and_cols.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetHistogram request pub const GET_HISTOGRAM_REQUEST: u8 = 154; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetHistogramRequest { pub context_tag: ContextTag, pub target: u32, pub format: u32, pub type_: u32, pub swap_bytes: bool, pub reset: bool, } impl GetHistogramRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let format_bytes = self.format.serialize(); let type_bytes = self.type_.serialize(); let swap_bytes_bytes = self.swap_bytes.serialize(); let reset_bytes = self.reset.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_HISTOGRAM_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], swap_bytes_bytes[0], reset_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_HISTOGRAM_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let (swap_bytes, remaining) = bool::try_parse(remaining)?; let (reset, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetHistogramRequest { context_tag, target, format, type_, swap_bytes, reset, }) } } impl Request for GetHistogramRequest { type Reply = GetHistogramReply; } pub fn get_histogram(conn: &Conn, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool, reset: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetHistogramRequest { context_tag, target, format, type_, swap_bytes, reset, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetHistogramReply { pub sequence: u16, pub width: i32, pub data: Vec, } impl TryParse for GetHistogramReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (width, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetHistogramReply { sequence, width, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetHistogramReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetHistogramParameterfv request pub const GET_HISTOGRAM_PARAMETERFV_REQUEST: u8 = 155; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetHistogramParameterfvRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetHistogramParameterfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_HISTOGRAM_PARAMETERFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_HISTOGRAM_PARAMETERFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetHistogramParameterfvRequest { context_tag, target, pname, }) } } impl Request for GetHistogramParameterfvRequest { type Reply = GetHistogramParameterfvReply; } pub fn get_histogram_parameterfv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetHistogramParameterfvRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetHistogramParameterfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetHistogramParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetHistogramParameterfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetHistogramParameterfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetHistogramParameteriv request pub const GET_HISTOGRAM_PARAMETERIV_REQUEST: u8 = 156; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetHistogramParameterivRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetHistogramParameterivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_HISTOGRAM_PARAMETERIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_HISTOGRAM_PARAMETERIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetHistogramParameterivRequest { context_tag, target, pname, }) } } impl Request for GetHistogramParameterivRequest { type Reply = GetHistogramParameterivReply; } pub fn get_histogram_parameteriv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetHistogramParameterivRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetHistogramParameterivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetHistogramParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetHistogramParameterivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetHistogramParameterivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetMinmax request pub const GET_MINMAX_REQUEST: u8 = 157; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMinmaxRequest { pub context_tag: ContextTag, pub target: u32, pub format: u32, pub type_: u32, pub swap_bytes: bool, pub reset: bool, } impl GetMinmaxRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let format_bytes = self.format.serialize(); let type_bytes = self.type_.serialize(); let swap_bytes_bytes = self.swap_bytes.serialize(); let reset_bytes = self.reset.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MINMAX_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], swap_bytes_bytes[0], reset_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MINMAX_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let (swap_bytes, remaining) = bool::try_parse(remaining)?; let (reset, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetMinmaxRequest { context_tag, target, format, type_, swap_bytes, reset, }) } } impl Request for GetMinmaxRequest { type Reply = GetMinmaxReply; } pub fn get_minmax(conn: &Conn, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool, reset: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMinmaxRequest { context_tag, target, format, type_, swap_bytes, reset, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetMinmaxReply { pub sequence: u16, pub data: Vec, } impl TryParse for GetMinmaxReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMinmaxReply { sequence, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMinmaxReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the GetMinmaxParameterfv request pub const GET_MINMAX_PARAMETERFV_REQUEST: u8 = 158; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMinmaxParameterfvRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetMinmaxParameterfvRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MINMAX_PARAMETERFV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MINMAX_PARAMETERFV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetMinmaxParameterfvRequest { context_tag, target, pname, }) } } impl Request for GetMinmaxParameterfvRequest { type Reply = GetMinmaxParameterfvReply; } pub fn get_minmax_parameterfv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMinmaxParameterfvRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq)] pub struct GetMinmaxParameterfvReply { pub sequence: u16, pub length: u32, pub datum: Float32, pub data: Vec, } impl TryParse for GetMinmaxParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = Float32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMinmaxParameterfvReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMinmaxParameterfvReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetMinmaxParameteriv request pub const GET_MINMAX_PARAMETERIV_REQUEST: u8 = 159; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMinmaxParameterivRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetMinmaxParameterivRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MINMAX_PARAMETERIV_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MINMAX_PARAMETERIV_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetMinmaxParameterivRequest { context_tag, target, pname, }) } } impl Request for GetMinmaxParameterivRequest { type Reply = GetMinmaxParameterivReply; } pub fn get_minmax_parameteriv(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMinmaxParameterivRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetMinmaxParameterivReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetMinmaxParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMinmaxParameterivReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMinmaxParameterivReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetCompressedTexImageARB request pub const GET_COMPRESSED_TEX_IMAGE_ARB_REQUEST: u8 = 160; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCompressedTexImageARBRequest { pub context_tag: ContextTag, pub target: u32, pub level: i32, } impl GetCompressedTexImageARBRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let level_bytes = self.level.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_COMPRESSED_TEX_IMAGE_ARB_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], level_bytes[0], level_bytes[1], level_bytes[2], level_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_COMPRESSED_TEX_IMAGE_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (level, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(GetCompressedTexImageARBRequest { context_tag, target, level, }) } } impl Request for GetCompressedTexImageARBRequest { type Reply = GetCompressedTexImageARBReply; } pub fn get_compressed_tex_image_arb(conn: &Conn, context_tag: ContextTag, target: u32, level: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCompressedTexImageARBRequest { context_tag, target, level, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCompressedTexImageARBReply { pub sequence: u16, pub size: i32, pub data: Vec, } impl TryParse for GetCompressedTexImageARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (size, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCompressedTexImageARBReply { sequence, size, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetCompressedTexImageARBReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the DeleteQueriesARB request pub const DELETE_QUERIES_ARB_REQUEST: u8 = 161; #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeleteQueriesARBRequest<'input> { pub context_tag: ContextTag, pub ids: Cow<'input, [u32]>, } impl<'input> DeleteQueriesARBRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let n = i32::try_from(self.ids.len()).expect("`ids` has too many elements"); let n_bytes = n.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_QUERIES_ARB_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], n_bytes[0], n_bytes[1], n_bytes[2], n_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let ids_bytes = self.ids.serialize(); let length_so_far = length_so_far + ids_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), ids_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != DELETE_QUERIES_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (n, remaining) = i32::try_parse(remaining)?; let (ids, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; let _ = remaining; Ok(DeleteQueriesARBRequest { context_tag, ids: Cow::Owned(ids), }) } /// Clone all borrowed data in this DeleteQueriesARBRequest. pub fn into_owned(self) -> DeleteQueriesARBRequest<'static> { DeleteQueriesARBRequest { context_tag: self.context_tag, ids: Cow::Owned(self.ids.into_owned()), } } } impl<'input> Request for DeleteQueriesARBRequest<'input> { type Reply = (); } pub fn delete_queries_arb<'c, 'input, Conn>(conn: &'c Conn, context_tag: ContextTag, ids: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteQueriesARBRequest { context_tag, ids: Cow::Borrowed(ids), }; request0.send(conn) } /// Opcode for the GenQueriesARB request pub const GEN_QUERIES_ARB_REQUEST: u8 = 162; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GenQueriesARBRequest { pub context_tag: ContextTag, pub n: i32, } impl GenQueriesARBRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let n_bytes = self.n.serialize(); let mut request0 = vec![ extension_information.major_opcode, GEN_QUERIES_ARB_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], n_bytes[0], n_bytes[1], n_bytes[2], n_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GEN_QUERIES_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (n, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(GenQueriesARBRequest { context_tag, n, }) } } impl Request for GenQueriesARBRequest { type Reply = GenQueriesARBReply; } pub fn gen_queries_arb(conn: &Conn, context_tag: ContextTag, n: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GenQueriesARBRequest { context_tag, n, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GenQueriesARBReply { pub sequence: u16, pub data: Vec, } impl TryParse for GenQueriesARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GenQueriesARBReply { sequence, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GenQueriesARBReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the IsQueryARB request pub const IS_QUERY_ARB_REQUEST: u8 = 163; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsQueryARBRequest { pub context_tag: ContextTag, pub id: u32, } impl IsQueryARBRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let id_bytes = self.id.serialize(); let mut request0 = vec![ extension_information.major_opcode, IS_QUERY_ARB_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != IS_QUERY_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (id, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(IsQueryARBRequest { context_tag, id, }) } } impl Request for IsQueryARBRequest { type Reply = IsQueryARBReply; } pub fn is_query_arb(conn: &Conn, context_tag: ContextTag, id: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = IsQueryARBRequest { context_tag, id, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsQueryARBReply { pub sequence: u16, pub length: u32, pub ret_val: Bool32, } impl TryParse for IsQueryARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ret_val, remaining) = Bool32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = IsQueryARBReply { sequence, length, ret_val }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetQueryivARB request pub const GET_QUERYIV_ARB_REQUEST: u8 = 164; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetQueryivARBRequest { pub context_tag: ContextTag, pub target: u32, pub pname: u32, } impl GetQueryivARBRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let target_bytes = self.target.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_QUERYIV_ARB_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], target_bytes[0], target_bytes[1], target_bytes[2], target_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_QUERYIV_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (target, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetQueryivARBRequest { context_tag, target, pname, }) } } impl Request for GetQueryivARBRequest { type Reply = GetQueryivARBReply; } pub fn get_queryiv_arb(conn: &Conn, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetQueryivARBRequest { context_tag, target, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetQueryivARBReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetQueryivARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetQueryivARBReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetQueryivARBReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetQueryObjectivARB request pub const GET_QUERY_OBJECTIV_ARB_REQUEST: u8 = 165; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetQueryObjectivARBRequest { pub context_tag: ContextTag, pub id: u32, pub pname: u32, } impl GetQueryObjectivARBRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let id_bytes = self.id.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_QUERY_OBJECTIV_ARB_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_QUERY_OBJECTIV_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (id, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetQueryObjectivARBRequest { context_tag, id, pname, }) } } impl Request for GetQueryObjectivARBRequest { type Reply = GetQueryObjectivARBReply; } pub fn get_query_objectiv_arb(conn: &Conn, context_tag: ContextTag, id: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetQueryObjectivARBRequest { context_tag, id, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetQueryObjectivARBReply { pub sequence: u16, pub length: u32, pub datum: i32, pub data: Vec, } impl TryParse for GetQueryObjectivARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = i32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetQueryObjectivARBReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetQueryObjectivARBReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the GetQueryObjectuivARB request pub const GET_QUERY_OBJECTUIV_ARB_REQUEST: u8 = 166; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetQueryObjectuivARBRequest { pub context_tag: ContextTag, pub id: u32, pub pname: u32, } impl GetQueryObjectuivARBRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_tag_bytes = self.context_tag.serialize(); let id_bytes = self.id.serialize(); let pname_bytes = self.pname.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_QUERY_OBJECTUIV_ARB_REQUEST, 0, 0, context_tag_bytes[0], context_tag_bytes[1], context_tag_bytes[2], context_tag_bytes[3], id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], pname_bytes[0], pname_bytes[1], pname_bytes[2], pname_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_QUERY_OBJECTUIV_ARB_REQUEST { return Err(ParseError::InvalidValue); } let (context_tag, remaining) = ContextTag::try_parse(value)?; let (id, remaining) = u32::try_parse(remaining)?; let (pname, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetQueryObjectuivARBRequest { context_tag, id, pname, }) } } impl Request for GetQueryObjectuivARBRequest { type Reply = GetQueryObjectuivARBReply; } pub fn get_query_objectuiv_arb(conn: &Conn, context_tag: ContextTag, id: u32, pname: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetQueryObjectuivARBRequest { context_tag, id, pname, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetQueryObjectuivARBReply { pub sequence: u16, pub length: u32, pub datum: u32, pub data: Vec, } impl TryParse for GetQueryObjectuivARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (n, remaining) = u32::try_parse(remaining)?; let (datum, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_list::(remaining, n.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetQueryObjectuivARBReply { sequence, length, datum, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetQueryObjectuivARBReply { /// Get the value of the `n` field. /// /// The `n` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn glx_render<'c, 'input>(&'c self, context_tag: ContextTag, data: &'input [u8]) -> Result, ConnectionError> { render(self, context_tag, data) } fn glx_render_large<'c, 'input>(&'c self, context_tag: ContextTag, request_num: u16, request_total: u16, data: &'input [u8]) -> Result, ConnectionError> { render_large(self, context_tag, request_num, request_total, data) } fn glx_create_context(&self, context: Context, visual: xproto::Visualid, screen: u32, share_list: Context, is_direct: bool) -> Result, ConnectionError> { create_context(self, context, visual, screen, share_list, is_direct) } fn glx_destroy_context(&self, context: Context) -> Result, ConnectionError> { destroy_context(self, context) } fn glx_make_current(&self, drawable: Drawable, context: Context, old_context_tag: ContextTag) -> Result, ConnectionError> { make_current(self, drawable, context, old_context_tag) } fn glx_is_direct(&self, context: Context) -> Result, ConnectionError> { is_direct(self, context) } fn glx_query_version(&self, major_version: u32, minor_version: u32) -> Result, ConnectionError> { query_version(self, major_version, minor_version) } fn glx_wait_gl(&self, context_tag: ContextTag) -> Result, ConnectionError> { wait_gl(self, context_tag) } fn glx_wait_x(&self, context_tag: ContextTag) -> Result, ConnectionError> { wait_x(self, context_tag) } fn glx_copy_context(&self, src: Context, dest: Context, mask: u32, src_context_tag: ContextTag) -> Result, ConnectionError> { copy_context(self, src, dest, mask, src_context_tag) } fn glx_swap_buffers(&self, context_tag: ContextTag, drawable: Drawable) -> Result, ConnectionError> { swap_buffers(self, context_tag, drawable) } fn glx_use_x_font(&self, context_tag: ContextTag, font: xproto::Font, first: u32, count: u32, list_base: u32) -> Result, ConnectionError> { use_x_font(self, context_tag, font, first, count, list_base) } fn glx_create_glx_pixmap(&self, screen: u32, visual: xproto::Visualid, pixmap: xproto::Pixmap, glx_pixmap: Pixmap) -> Result, ConnectionError> { create_glx_pixmap(self, screen, visual, pixmap, glx_pixmap) } fn glx_get_visual_configs(&self, screen: u32) -> Result, ConnectionError> { get_visual_configs(self, screen) } fn glx_destroy_glx_pixmap(&self, glx_pixmap: Pixmap) -> Result, ConnectionError> { destroy_glx_pixmap(self, glx_pixmap) } fn glx_vendor_private<'c, 'input>(&'c self, vendor_code: u32, context_tag: ContextTag, data: &'input [u8]) -> Result, ConnectionError> { vendor_private(self, vendor_code, context_tag, data) } fn glx_vendor_private_with_reply<'c, 'input>(&'c self, vendor_code: u32, context_tag: ContextTag, data: &'input [u8]) -> Result, ConnectionError> { vendor_private_with_reply(self, vendor_code, context_tag, data) } fn glx_query_extensions_string(&self, screen: u32) -> Result, ConnectionError> { query_extensions_string(self, screen) } fn glx_query_server_string(&self, screen: u32, name: u32) -> Result, ConnectionError> { query_server_string(self, screen, name) } fn glx_client_info<'c, 'input>(&'c self, major_version: u32, minor_version: u32, string: &'input [u8]) -> Result, ConnectionError> { client_info(self, major_version, minor_version, string) } fn glx_get_fb_configs(&self, screen: u32) -> Result, ConnectionError> { get_fb_configs(self, screen) } fn glx_create_pixmap<'c, 'input>(&'c self, screen: u32, fbconfig: Fbconfig, pixmap: xproto::Pixmap, glx_pixmap: Pixmap, attribs: &'input [u32]) -> Result, ConnectionError> { create_pixmap(self, screen, fbconfig, pixmap, glx_pixmap, attribs) } fn glx_destroy_pixmap(&self, glx_pixmap: Pixmap) -> Result, ConnectionError> { destroy_pixmap(self, glx_pixmap) } fn glx_create_new_context(&self, context: Context, fbconfig: Fbconfig, screen: u32, render_type: u32, share_list: Context, is_direct: bool) -> Result, ConnectionError> { create_new_context(self, context, fbconfig, screen, render_type, share_list, is_direct) } fn glx_query_context(&self, context: Context) -> Result, ConnectionError> { query_context(self, context) } fn glx_make_context_current(&self, old_context_tag: ContextTag, drawable: Drawable, read_drawable: Drawable, context: Context) -> Result, ConnectionError> { make_context_current(self, old_context_tag, drawable, read_drawable, context) } fn glx_create_pbuffer<'c, 'input>(&'c self, screen: u32, fbconfig: Fbconfig, pbuffer: Pbuffer, attribs: &'input [u32]) -> Result, ConnectionError> { create_pbuffer(self, screen, fbconfig, pbuffer, attribs) } fn glx_destroy_pbuffer(&self, pbuffer: Pbuffer) -> Result, ConnectionError> { destroy_pbuffer(self, pbuffer) } fn glx_get_drawable_attributes(&self, drawable: Drawable) -> Result, ConnectionError> { get_drawable_attributes(self, drawable) } fn glx_change_drawable_attributes<'c, 'input>(&'c self, drawable: Drawable, attribs: &'input [u32]) -> Result, ConnectionError> { change_drawable_attributes(self, drawable, attribs) } fn glx_create_window<'c, 'input>(&'c self, screen: u32, fbconfig: Fbconfig, window: xproto::Window, glx_window: Window, attribs: &'input [u32]) -> Result, ConnectionError> { create_window(self, screen, fbconfig, window, glx_window, attribs) } fn glx_delete_window(&self, glxwindow: Window) -> Result, ConnectionError> { delete_window(self, glxwindow) } fn glx_set_client_info_arb<'c, 'input>(&'c self, major_version: u32, minor_version: u32, gl_versions: &'input [u32], gl_extension_string: &'input [u8], glx_extension_string: &'input [u8]) -> Result, ConnectionError> { set_client_info_arb(self, major_version, minor_version, gl_versions, gl_extension_string, glx_extension_string) } fn glx_create_context_attribs_arb<'c, 'input>(&'c self, context: Context, fbconfig: Fbconfig, screen: u32, share_list: Context, is_direct: bool, attribs: &'input [u32]) -> Result, ConnectionError> { create_context_attribs_arb(self, context, fbconfig, screen, share_list, is_direct, attribs) } fn glx_set_client_info2_arb<'c, 'input>(&'c self, major_version: u32, minor_version: u32, gl_versions: &'input [u32], gl_extension_string: &'input [u8], glx_extension_string: &'input [u8]) -> Result, ConnectionError> { set_client_info2_arb(self, major_version, minor_version, gl_versions, gl_extension_string, glx_extension_string) } fn glx_new_list(&self, context_tag: ContextTag, list: u32, mode: u32) -> Result, ConnectionError> { new_list(self, context_tag, list, mode) } fn glx_end_list(&self, context_tag: ContextTag) -> Result, ConnectionError> { end_list(self, context_tag) } fn glx_delete_lists(&self, context_tag: ContextTag, list: u32, range: i32) -> Result, ConnectionError> { delete_lists(self, context_tag, list, range) } fn glx_gen_lists(&self, context_tag: ContextTag, range: i32) -> Result, ConnectionError> { gen_lists(self, context_tag, range) } fn glx_feedback_buffer(&self, context_tag: ContextTag, size: i32, type_: i32) -> Result, ConnectionError> { feedback_buffer(self, context_tag, size, type_) } fn glx_select_buffer(&self, context_tag: ContextTag, size: i32) -> Result, ConnectionError> { select_buffer(self, context_tag, size) } fn glx_render_mode(&self, context_tag: ContextTag, mode: u32) -> Result, ConnectionError> { render_mode(self, context_tag, mode) } fn glx_finish(&self, context_tag: ContextTag) -> Result, ConnectionError> { finish(self, context_tag) } fn glx_pixel_storef(&self, context_tag: ContextTag, pname: u32, datum: Float32) -> Result, ConnectionError> { pixel_storef(self, context_tag, pname, datum) } fn glx_pixel_storei(&self, context_tag: ContextTag, pname: u32, datum: i32) -> Result, ConnectionError> { pixel_storei(self, context_tag, pname, datum) } fn glx_read_pixels(&self, context_tag: ContextTag, x: i32, y: i32, width: i32, height: i32, format: u32, type_: u32, swap_bytes: bool, lsb_first: bool) -> Result, ConnectionError> { read_pixels(self, context_tag, x, y, width, height, format, type_, swap_bytes, lsb_first) } fn glx_get_booleanv(&self, context_tag: ContextTag, pname: i32) -> Result, ConnectionError> { get_booleanv(self, context_tag, pname) } fn glx_get_clip_plane(&self, context_tag: ContextTag, plane: i32) -> Result, ConnectionError> { get_clip_plane(self, context_tag, plane) } fn glx_get_doublev(&self, context_tag: ContextTag, pname: u32) -> Result, ConnectionError> { get_doublev(self, context_tag, pname) } fn glx_get_error(&self, context_tag: ContextTag) -> Result, ConnectionError> { get_error(self, context_tag) } fn glx_get_floatv(&self, context_tag: ContextTag, pname: u32) -> Result, ConnectionError> { get_floatv(self, context_tag, pname) } fn glx_get_integerv(&self, context_tag: ContextTag, pname: u32) -> Result, ConnectionError> { get_integerv(self, context_tag, pname) } fn glx_get_lightfv(&self, context_tag: ContextTag, light: u32, pname: u32) -> Result, ConnectionError> { get_lightfv(self, context_tag, light, pname) } fn glx_get_lightiv(&self, context_tag: ContextTag, light: u32, pname: u32) -> Result, ConnectionError> { get_lightiv(self, context_tag, light, pname) } fn glx_get_mapdv(&self, context_tag: ContextTag, target: u32, query: u32) -> Result, ConnectionError> { get_mapdv(self, context_tag, target, query) } fn glx_get_mapfv(&self, context_tag: ContextTag, target: u32, query: u32) -> Result, ConnectionError> { get_mapfv(self, context_tag, target, query) } fn glx_get_mapiv(&self, context_tag: ContextTag, target: u32, query: u32) -> Result, ConnectionError> { get_mapiv(self, context_tag, target, query) } fn glx_get_materialfv(&self, context_tag: ContextTag, face: u32, pname: u32) -> Result, ConnectionError> { get_materialfv(self, context_tag, face, pname) } fn glx_get_materialiv(&self, context_tag: ContextTag, face: u32, pname: u32) -> Result, ConnectionError> { get_materialiv(self, context_tag, face, pname) } fn glx_get_pixel_mapfv(&self, context_tag: ContextTag, map: u32) -> Result, ConnectionError> { get_pixel_mapfv(self, context_tag, map) } fn glx_get_pixel_mapuiv(&self, context_tag: ContextTag, map: u32) -> Result, ConnectionError> { get_pixel_mapuiv(self, context_tag, map) } fn glx_get_pixel_mapusv(&self, context_tag: ContextTag, map: u32) -> Result, ConnectionError> { get_pixel_mapusv(self, context_tag, map) } fn glx_get_polygon_stipple(&self, context_tag: ContextTag, lsb_first: bool) -> Result, ConnectionError> { get_polygon_stipple(self, context_tag, lsb_first) } fn glx_get_string(&self, context_tag: ContextTag, name: u32) -> Result, ConnectionError> { get_string(self, context_tag, name) } fn glx_get_tex_envfv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_tex_envfv(self, context_tag, target, pname) } fn glx_get_tex_enviv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_tex_enviv(self, context_tag, target, pname) } fn glx_get_tex_gendv(&self, context_tag: ContextTag, coord: u32, pname: u32) -> Result, ConnectionError> { get_tex_gendv(self, context_tag, coord, pname) } fn glx_get_tex_genfv(&self, context_tag: ContextTag, coord: u32, pname: u32) -> Result, ConnectionError> { get_tex_genfv(self, context_tag, coord, pname) } fn glx_get_tex_geniv(&self, context_tag: ContextTag, coord: u32, pname: u32) -> Result, ConnectionError> { get_tex_geniv(self, context_tag, coord, pname) } fn glx_get_tex_image(&self, context_tag: ContextTag, target: u32, level: i32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> { get_tex_image(self, context_tag, target, level, format, type_, swap_bytes) } fn glx_get_tex_parameterfv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_tex_parameterfv(self, context_tag, target, pname) } fn glx_get_tex_parameteriv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_tex_parameteriv(self, context_tag, target, pname) } fn glx_get_tex_level_parameterfv(&self, context_tag: ContextTag, target: u32, level: i32, pname: u32) -> Result, ConnectionError> { get_tex_level_parameterfv(self, context_tag, target, level, pname) } fn glx_get_tex_level_parameteriv(&self, context_tag: ContextTag, target: u32, level: i32, pname: u32) -> Result, ConnectionError> { get_tex_level_parameteriv(self, context_tag, target, level, pname) } fn glx_is_enabled(&self, context_tag: ContextTag, capability: u32) -> Result, ConnectionError> { is_enabled(self, context_tag, capability) } fn glx_is_list(&self, context_tag: ContextTag, list: u32) -> Result, ConnectionError> { is_list(self, context_tag, list) } fn glx_flush(&self, context_tag: ContextTag) -> Result, ConnectionError> { flush(self, context_tag) } fn glx_are_textures_resident<'c, 'input>(&'c self, context_tag: ContextTag, textures: &'input [u32]) -> Result, ConnectionError> { are_textures_resident(self, context_tag, textures) } fn glx_delete_textures<'c, 'input>(&'c self, context_tag: ContextTag, textures: &'input [u32]) -> Result, ConnectionError> { delete_textures(self, context_tag, textures) } fn glx_gen_textures(&self, context_tag: ContextTag, n: i32) -> Result, ConnectionError> { gen_textures(self, context_tag, n) } fn glx_is_texture(&self, context_tag: ContextTag, texture: u32) -> Result, ConnectionError> { is_texture(self, context_tag, texture) } fn glx_get_color_table(&self, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> { get_color_table(self, context_tag, target, format, type_, swap_bytes) } fn glx_get_color_table_parameterfv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_color_table_parameterfv(self, context_tag, target, pname) } fn glx_get_color_table_parameteriv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_color_table_parameteriv(self, context_tag, target, pname) } fn glx_get_convolution_filter(&self, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> { get_convolution_filter(self, context_tag, target, format, type_, swap_bytes) } fn glx_get_convolution_parameterfv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_convolution_parameterfv(self, context_tag, target, pname) } fn glx_get_convolution_parameteriv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_convolution_parameteriv(self, context_tag, target, pname) } fn glx_get_separable_filter(&self, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool) -> Result, ConnectionError> { get_separable_filter(self, context_tag, target, format, type_, swap_bytes) } fn glx_get_histogram(&self, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool, reset: bool) -> Result, ConnectionError> { get_histogram(self, context_tag, target, format, type_, swap_bytes, reset) } fn glx_get_histogram_parameterfv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_histogram_parameterfv(self, context_tag, target, pname) } fn glx_get_histogram_parameteriv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_histogram_parameteriv(self, context_tag, target, pname) } fn glx_get_minmax(&self, context_tag: ContextTag, target: u32, format: u32, type_: u32, swap_bytes: bool, reset: bool) -> Result, ConnectionError> { get_minmax(self, context_tag, target, format, type_, swap_bytes, reset) } fn glx_get_minmax_parameterfv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_minmax_parameterfv(self, context_tag, target, pname) } fn glx_get_minmax_parameteriv(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_minmax_parameteriv(self, context_tag, target, pname) } fn glx_get_compressed_tex_image_arb(&self, context_tag: ContextTag, target: u32, level: i32) -> Result, ConnectionError> { get_compressed_tex_image_arb(self, context_tag, target, level) } fn glx_delete_queries_arb<'c, 'input>(&'c self, context_tag: ContextTag, ids: &'input [u32]) -> Result, ConnectionError> { delete_queries_arb(self, context_tag, ids) } fn glx_gen_queries_arb(&self, context_tag: ContextTag, n: i32) -> Result, ConnectionError> { gen_queries_arb(self, context_tag, n) } fn glx_is_query_arb(&self, context_tag: ContextTag, id: u32) -> Result, ConnectionError> { is_query_arb(self, context_tag, id) } fn glx_get_queryiv_arb(&self, context_tag: ContextTag, target: u32, pname: u32) -> Result, ConnectionError> { get_queryiv_arb(self, context_tag, target, pname) } fn glx_get_query_objectiv_arb(&self, context_tag: ContextTag, id: u32, pname: u32) -> Result, ConnectionError> { get_query_objectiv_arb(self, context_tag, id, pname) } fn glx_get_query_objectuiv_arb(&self, context_tag: ContextTag, id: u32, pname: u32) -> Result, ConnectionError> { get_query_objectuiv_arb(self, context_tag, id, pname) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/mod.rs010064400017500001750000015627471402220031600144270ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the X11 protocol. //! //! Each sub-module of this module corresponds to one X11 extension. It contains all the //! definitions from that extension. The core X11 protocol is in [`xproto`](xproto/index.html). use std::borrow::Cow; use std::convert::TryInto; use crate::errors::ParseError; use crate::utils::RawFdContainer; use crate::x11_utils::{TryParse, X11Error}; use crate::x11_utils::{ExtInfoProvider, ReplyParsingFunction, Request as RequestTrait, RequestHeader}; pub mod xproto; pub mod bigreq; #[cfg(feature = "composite")] pub mod composite; #[cfg(feature = "damage")] pub mod damage; #[cfg(feature = "dpms")] pub mod dpms; #[cfg(feature = "dri2")] pub mod dri2; #[cfg(feature = "dri3")] pub mod dri3; pub mod ge; #[cfg(feature = "glx")] pub mod glx; #[cfg(feature = "present")] pub mod present; #[cfg(feature = "randr")] pub mod randr; #[cfg(feature = "record")] pub mod record; #[cfg(feature = "render")] pub mod render; #[cfg(feature = "res")] pub mod res; #[cfg(feature = "screensaver")] pub mod screensaver; #[cfg(feature = "shape")] pub mod shape; #[cfg(feature = "shm")] pub mod shm; #[cfg(feature = "sync")] pub mod sync; pub mod xc_misc; #[cfg(feature = "xevie")] pub mod xevie; #[cfg(feature = "xf86dri")] pub mod xf86dri; #[cfg(feature = "xf86vidmode")] pub mod xf86vidmode; #[cfg(feature = "xfixes")] pub mod xfixes; #[cfg(feature = "xinerama")] pub mod xinerama; #[cfg(feature = "xinput")] pub mod xinput; #[cfg(feature = "xkb")] pub mod xkb; #[cfg(feature = "xprint")] pub mod xprint; #[cfg(feature = "xselinux")] pub mod xselinux; #[cfg(feature = "xtest")] pub mod xtest; #[cfg(feature = "xv")] pub mod xv; #[cfg(feature = "xvmc")] pub mod xvmc; /// Enumeration of all possible X11 requests. #[derive(Debug)] #[allow(clippy::large_enum_variant)] #[non_exhaustive] pub enum Request<'input> { Unknown(RequestHeader, Cow<'input, [u8]>), CreateWindow(xproto::CreateWindowRequest<'input>), ChangeWindowAttributes(xproto::ChangeWindowAttributesRequest<'input>), GetWindowAttributes(xproto::GetWindowAttributesRequest), DestroyWindow(xproto::DestroyWindowRequest), DestroySubwindows(xproto::DestroySubwindowsRequest), ChangeSaveSet(xproto::ChangeSaveSetRequest), ReparentWindow(xproto::ReparentWindowRequest), MapWindow(xproto::MapWindowRequest), MapSubwindows(xproto::MapSubwindowsRequest), UnmapWindow(xproto::UnmapWindowRequest), UnmapSubwindows(xproto::UnmapSubwindowsRequest), ConfigureWindow(xproto::ConfigureWindowRequest<'input>), CirculateWindow(xproto::CirculateWindowRequest), GetGeometry(xproto::GetGeometryRequest), QueryTree(xproto::QueryTreeRequest), InternAtom(xproto::InternAtomRequest<'input>), GetAtomName(xproto::GetAtomNameRequest), ChangeProperty(xproto::ChangePropertyRequest<'input>), DeleteProperty(xproto::DeletePropertyRequest), GetProperty(xproto::GetPropertyRequest), ListProperties(xproto::ListPropertiesRequest), SetSelectionOwner(xproto::SetSelectionOwnerRequest), GetSelectionOwner(xproto::GetSelectionOwnerRequest), ConvertSelection(xproto::ConvertSelectionRequest), SendEvent(xproto::SendEventRequest<'input>), GrabPointer(xproto::GrabPointerRequest), UngrabPointer(xproto::UngrabPointerRequest), GrabButton(xproto::GrabButtonRequest), UngrabButton(xproto::UngrabButtonRequest), ChangeActivePointerGrab(xproto::ChangeActivePointerGrabRequest), GrabKeyboard(xproto::GrabKeyboardRequest), UngrabKeyboard(xproto::UngrabKeyboardRequest), GrabKey(xproto::GrabKeyRequest), UngrabKey(xproto::UngrabKeyRequest), AllowEvents(xproto::AllowEventsRequest), GrabServer(xproto::GrabServerRequest), UngrabServer(xproto::UngrabServerRequest), QueryPointer(xproto::QueryPointerRequest), GetMotionEvents(xproto::GetMotionEventsRequest), TranslateCoordinates(xproto::TranslateCoordinatesRequest), WarpPointer(xproto::WarpPointerRequest), SetInputFocus(xproto::SetInputFocusRequest), GetInputFocus(xproto::GetInputFocusRequest), QueryKeymap(xproto::QueryKeymapRequest), OpenFont(xproto::OpenFontRequest<'input>), CloseFont(xproto::CloseFontRequest), QueryFont(xproto::QueryFontRequest), QueryTextExtents(xproto::QueryTextExtentsRequest<'input>), ListFonts(xproto::ListFontsRequest<'input>), ListFontsWithInfo(xproto::ListFontsWithInfoRequest<'input>), SetFontPath(xproto::SetFontPathRequest<'input>), GetFontPath(xproto::GetFontPathRequest), CreatePixmap(xproto::CreatePixmapRequest), FreePixmap(xproto::FreePixmapRequest), CreateGC(xproto::CreateGCRequest<'input>), ChangeGC(xproto::ChangeGCRequest<'input>), CopyGC(xproto::CopyGCRequest), SetDashes(xproto::SetDashesRequest<'input>), SetClipRectangles(xproto::SetClipRectanglesRequest<'input>), FreeGC(xproto::FreeGCRequest), ClearArea(xproto::ClearAreaRequest), CopyArea(xproto::CopyAreaRequest), CopyPlane(xproto::CopyPlaneRequest), PolyPoint(xproto::PolyPointRequest<'input>), PolyLine(xproto::PolyLineRequest<'input>), PolySegment(xproto::PolySegmentRequest<'input>), PolyRectangle(xproto::PolyRectangleRequest<'input>), PolyArc(xproto::PolyArcRequest<'input>), FillPoly(xproto::FillPolyRequest<'input>), PolyFillRectangle(xproto::PolyFillRectangleRequest<'input>), PolyFillArc(xproto::PolyFillArcRequest<'input>), PutImage(xproto::PutImageRequest<'input>), GetImage(xproto::GetImageRequest), PolyText8(xproto::PolyText8Request<'input>), PolyText16(xproto::PolyText16Request<'input>), ImageText8(xproto::ImageText8Request<'input>), ImageText16(xproto::ImageText16Request<'input>), CreateColormap(xproto::CreateColormapRequest), FreeColormap(xproto::FreeColormapRequest), CopyColormapAndFree(xproto::CopyColormapAndFreeRequest), InstallColormap(xproto::InstallColormapRequest), UninstallColormap(xproto::UninstallColormapRequest), ListInstalledColormaps(xproto::ListInstalledColormapsRequest), AllocColor(xproto::AllocColorRequest), AllocNamedColor(xproto::AllocNamedColorRequest<'input>), AllocColorCells(xproto::AllocColorCellsRequest), AllocColorPlanes(xproto::AllocColorPlanesRequest), FreeColors(xproto::FreeColorsRequest<'input>), StoreColors(xproto::StoreColorsRequest<'input>), StoreNamedColor(xproto::StoreNamedColorRequest<'input>), QueryColors(xproto::QueryColorsRequest<'input>), LookupColor(xproto::LookupColorRequest<'input>), CreateCursor(xproto::CreateCursorRequest), CreateGlyphCursor(xproto::CreateGlyphCursorRequest), FreeCursor(xproto::FreeCursorRequest), RecolorCursor(xproto::RecolorCursorRequest), QueryBestSize(xproto::QueryBestSizeRequest), QueryExtension(xproto::QueryExtensionRequest<'input>), ListExtensions(xproto::ListExtensionsRequest), ChangeKeyboardMapping(xproto::ChangeKeyboardMappingRequest<'input>), GetKeyboardMapping(xproto::GetKeyboardMappingRequest), ChangeKeyboardControl(xproto::ChangeKeyboardControlRequest<'input>), GetKeyboardControl(xproto::GetKeyboardControlRequest), Bell(xproto::BellRequest), ChangePointerControl(xproto::ChangePointerControlRequest), GetPointerControl(xproto::GetPointerControlRequest), SetScreenSaver(xproto::SetScreenSaverRequest), GetScreenSaver(xproto::GetScreenSaverRequest), ChangeHosts(xproto::ChangeHostsRequest<'input>), ListHosts(xproto::ListHostsRequest), SetAccessControl(xproto::SetAccessControlRequest), SetCloseDownMode(xproto::SetCloseDownModeRequest), KillClient(xproto::KillClientRequest), RotateProperties(xproto::RotatePropertiesRequest<'input>), ForceScreenSaver(xproto::ForceScreenSaverRequest), SetPointerMapping(xproto::SetPointerMappingRequest<'input>), GetPointerMapping(xproto::GetPointerMappingRequest), SetModifierMapping(xproto::SetModifierMappingRequest<'input>), GetModifierMapping(xproto::GetModifierMappingRequest), NoOperation(xproto::NoOperationRequest), BigreqEnable(bigreq::EnableRequest), #[cfg(feature = "composite")] CompositeQueryVersion(composite::QueryVersionRequest), #[cfg(feature = "composite")] CompositeRedirectWindow(composite::RedirectWindowRequest), #[cfg(feature = "composite")] CompositeRedirectSubwindows(composite::RedirectSubwindowsRequest), #[cfg(feature = "composite")] CompositeUnredirectWindow(composite::UnredirectWindowRequest), #[cfg(feature = "composite")] CompositeUnredirectSubwindows(composite::UnredirectSubwindowsRequest), #[cfg(feature = "composite")] CompositeCreateRegionFromBorderClip(composite::CreateRegionFromBorderClipRequest), #[cfg(feature = "composite")] CompositeNameWindowPixmap(composite::NameWindowPixmapRequest), #[cfg(feature = "composite")] CompositeGetOverlayWindow(composite::GetOverlayWindowRequest), #[cfg(feature = "composite")] CompositeReleaseOverlayWindow(composite::ReleaseOverlayWindowRequest), #[cfg(feature = "damage")] DamageQueryVersion(damage::QueryVersionRequest), #[cfg(feature = "damage")] DamageCreate(damage::CreateRequest), #[cfg(feature = "damage")] DamageDestroy(damage::DestroyRequest), #[cfg(feature = "damage")] DamageSubtract(damage::SubtractRequest), #[cfg(feature = "damage")] DamageAdd(damage::AddRequest), #[cfg(feature = "dpms")] DpmsGetVersion(dpms::GetVersionRequest), #[cfg(feature = "dpms")] DpmsCapable(dpms::CapableRequest), #[cfg(feature = "dpms")] DpmsGetTimeouts(dpms::GetTimeoutsRequest), #[cfg(feature = "dpms")] DpmsSetTimeouts(dpms::SetTimeoutsRequest), #[cfg(feature = "dpms")] DpmsEnable(dpms::EnableRequest), #[cfg(feature = "dpms")] DpmsDisable(dpms::DisableRequest), #[cfg(feature = "dpms")] DpmsForceLevel(dpms::ForceLevelRequest), #[cfg(feature = "dpms")] DpmsInfo(dpms::InfoRequest), #[cfg(feature = "dri2")] Dri2QueryVersion(dri2::QueryVersionRequest), #[cfg(feature = "dri2")] Dri2Connect(dri2::ConnectRequest), #[cfg(feature = "dri2")] Dri2Authenticate(dri2::AuthenticateRequest), #[cfg(feature = "dri2")] Dri2CreateDrawable(dri2::CreateDrawableRequest), #[cfg(feature = "dri2")] Dri2DestroyDrawable(dri2::DestroyDrawableRequest), #[cfg(feature = "dri2")] Dri2GetBuffers(dri2::GetBuffersRequest<'input>), #[cfg(feature = "dri2")] Dri2CopyRegion(dri2::CopyRegionRequest), #[cfg(feature = "dri2")] Dri2GetBuffersWithFormat(dri2::GetBuffersWithFormatRequest<'input>), #[cfg(feature = "dri2")] Dri2SwapBuffers(dri2::SwapBuffersRequest), #[cfg(feature = "dri2")] Dri2GetMSC(dri2::GetMSCRequest), #[cfg(feature = "dri2")] Dri2WaitMSC(dri2::WaitMSCRequest), #[cfg(feature = "dri2")] Dri2WaitSBC(dri2::WaitSBCRequest), #[cfg(feature = "dri2")] Dri2SwapInterval(dri2::SwapIntervalRequest), #[cfg(feature = "dri2")] Dri2GetParam(dri2::GetParamRequest), #[cfg(feature = "dri3")] Dri3QueryVersion(dri3::QueryVersionRequest), #[cfg(feature = "dri3")] Dri3Open(dri3::OpenRequest), #[cfg(feature = "dri3")] Dri3PixmapFromBuffer(dri3::PixmapFromBufferRequest), #[cfg(feature = "dri3")] Dri3BufferFromPixmap(dri3::BufferFromPixmapRequest), #[cfg(feature = "dri3")] Dri3FenceFromFD(dri3::FenceFromFDRequest), #[cfg(feature = "dri3")] Dri3FDFromFence(dri3::FDFromFenceRequest), #[cfg(feature = "dri3")] Dri3GetSupportedModifiers(dri3::GetSupportedModifiersRequest), #[cfg(feature = "dri3")] Dri3PixmapFromBuffers(dri3::PixmapFromBuffersRequest), #[cfg(feature = "dri3")] Dri3BuffersFromPixmap(dri3::BuffersFromPixmapRequest), GeQueryVersion(ge::QueryVersionRequest), #[cfg(feature = "glx")] GlxRender(glx::RenderRequest<'input>), #[cfg(feature = "glx")] GlxRenderLarge(glx::RenderLargeRequest<'input>), #[cfg(feature = "glx")] GlxCreateContext(glx::CreateContextRequest), #[cfg(feature = "glx")] GlxDestroyContext(glx::DestroyContextRequest), #[cfg(feature = "glx")] GlxMakeCurrent(glx::MakeCurrentRequest), #[cfg(feature = "glx")] GlxIsDirect(glx::IsDirectRequest), #[cfg(feature = "glx")] GlxQueryVersion(glx::QueryVersionRequest), #[cfg(feature = "glx")] GlxWaitGL(glx::WaitGLRequest), #[cfg(feature = "glx")] GlxWaitX(glx::WaitXRequest), #[cfg(feature = "glx")] GlxCopyContext(glx::CopyContextRequest), #[cfg(feature = "glx")] GlxSwapBuffers(glx::SwapBuffersRequest), #[cfg(feature = "glx")] GlxUseXFont(glx::UseXFontRequest), #[cfg(feature = "glx")] GlxCreateGLXPixmap(glx::CreateGLXPixmapRequest), #[cfg(feature = "glx")] GlxGetVisualConfigs(glx::GetVisualConfigsRequest), #[cfg(feature = "glx")] GlxDestroyGLXPixmap(glx::DestroyGLXPixmapRequest), #[cfg(feature = "glx")] GlxVendorPrivate(glx::VendorPrivateRequest<'input>), #[cfg(feature = "glx")] GlxVendorPrivateWithReply(glx::VendorPrivateWithReplyRequest<'input>), #[cfg(feature = "glx")] GlxQueryExtensionsString(glx::QueryExtensionsStringRequest), #[cfg(feature = "glx")] GlxQueryServerString(glx::QueryServerStringRequest), #[cfg(feature = "glx")] GlxClientInfo(glx::ClientInfoRequest<'input>), #[cfg(feature = "glx")] GlxGetFBConfigs(glx::GetFBConfigsRequest), #[cfg(feature = "glx")] GlxCreatePixmap(glx::CreatePixmapRequest<'input>), #[cfg(feature = "glx")] GlxDestroyPixmap(glx::DestroyPixmapRequest), #[cfg(feature = "glx")] GlxCreateNewContext(glx::CreateNewContextRequest), #[cfg(feature = "glx")] GlxQueryContext(glx::QueryContextRequest), #[cfg(feature = "glx")] GlxMakeContextCurrent(glx::MakeContextCurrentRequest), #[cfg(feature = "glx")] GlxCreatePbuffer(glx::CreatePbufferRequest<'input>), #[cfg(feature = "glx")] GlxDestroyPbuffer(glx::DestroyPbufferRequest), #[cfg(feature = "glx")] GlxGetDrawableAttributes(glx::GetDrawableAttributesRequest), #[cfg(feature = "glx")] GlxChangeDrawableAttributes(glx::ChangeDrawableAttributesRequest<'input>), #[cfg(feature = "glx")] GlxCreateWindow(glx::CreateWindowRequest<'input>), #[cfg(feature = "glx")] GlxDeleteWindow(glx::DeleteWindowRequest), #[cfg(feature = "glx")] GlxSetClientInfoARB(glx::SetClientInfoARBRequest<'input>), #[cfg(feature = "glx")] GlxCreateContextAttribsARB(glx::CreateContextAttribsARBRequest<'input>), #[cfg(feature = "glx")] GlxSetClientInfo2ARB(glx::SetClientInfo2ARBRequest<'input>), #[cfg(feature = "glx")] GlxNewList(glx::NewListRequest), #[cfg(feature = "glx")] GlxEndList(glx::EndListRequest), #[cfg(feature = "glx")] GlxDeleteLists(glx::DeleteListsRequest), #[cfg(feature = "glx")] GlxGenLists(glx::GenListsRequest), #[cfg(feature = "glx")] GlxFeedbackBuffer(glx::FeedbackBufferRequest), #[cfg(feature = "glx")] GlxSelectBuffer(glx::SelectBufferRequest), #[cfg(feature = "glx")] GlxRenderMode(glx::RenderModeRequest), #[cfg(feature = "glx")] GlxFinish(glx::FinishRequest), #[cfg(feature = "glx")] GlxPixelStoref(glx::PixelStorefRequest), #[cfg(feature = "glx")] GlxPixelStorei(glx::PixelStoreiRequest), #[cfg(feature = "glx")] GlxReadPixels(glx::ReadPixelsRequest), #[cfg(feature = "glx")] GlxGetBooleanv(glx::GetBooleanvRequest), #[cfg(feature = "glx")] GlxGetClipPlane(glx::GetClipPlaneRequest), #[cfg(feature = "glx")] GlxGetDoublev(glx::GetDoublevRequest), #[cfg(feature = "glx")] GlxGetError(glx::GetErrorRequest), #[cfg(feature = "glx")] GlxGetFloatv(glx::GetFloatvRequest), #[cfg(feature = "glx")] GlxGetIntegerv(glx::GetIntegervRequest), #[cfg(feature = "glx")] GlxGetLightfv(glx::GetLightfvRequest), #[cfg(feature = "glx")] GlxGetLightiv(glx::GetLightivRequest), #[cfg(feature = "glx")] GlxGetMapdv(glx::GetMapdvRequest), #[cfg(feature = "glx")] GlxGetMapfv(glx::GetMapfvRequest), #[cfg(feature = "glx")] GlxGetMapiv(glx::GetMapivRequest), #[cfg(feature = "glx")] GlxGetMaterialfv(glx::GetMaterialfvRequest), #[cfg(feature = "glx")] GlxGetMaterialiv(glx::GetMaterialivRequest), #[cfg(feature = "glx")] GlxGetPixelMapfv(glx::GetPixelMapfvRequest), #[cfg(feature = "glx")] GlxGetPixelMapuiv(glx::GetPixelMapuivRequest), #[cfg(feature = "glx")] GlxGetPixelMapusv(glx::GetPixelMapusvRequest), #[cfg(feature = "glx")] GlxGetPolygonStipple(glx::GetPolygonStippleRequest), #[cfg(feature = "glx")] GlxGetString(glx::GetStringRequest), #[cfg(feature = "glx")] GlxGetTexEnvfv(glx::GetTexEnvfvRequest), #[cfg(feature = "glx")] GlxGetTexEnviv(glx::GetTexEnvivRequest), #[cfg(feature = "glx")] GlxGetTexGendv(glx::GetTexGendvRequest), #[cfg(feature = "glx")] GlxGetTexGenfv(glx::GetTexGenfvRequest), #[cfg(feature = "glx")] GlxGetTexGeniv(glx::GetTexGenivRequest), #[cfg(feature = "glx")] GlxGetTexImage(glx::GetTexImageRequest), #[cfg(feature = "glx")] GlxGetTexParameterfv(glx::GetTexParameterfvRequest), #[cfg(feature = "glx")] GlxGetTexParameteriv(glx::GetTexParameterivRequest), #[cfg(feature = "glx")] GlxGetTexLevelParameterfv(glx::GetTexLevelParameterfvRequest), #[cfg(feature = "glx")] GlxGetTexLevelParameteriv(glx::GetTexLevelParameterivRequest), #[cfg(feature = "glx")] GlxIsEnabled(glx::IsEnabledRequest), #[cfg(feature = "glx")] GlxIsList(glx::IsListRequest), #[cfg(feature = "glx")] GlxFlush(glx::FlushRequest), #[cfg(feature = "glx")] GlxAreTexturesResident(glx::AreTexturesResidentRequest<'input>), #[cfg(feature = "glx")] GlxDeleteTextures(glx::DeleteTexturesRequest<'input>), #[cfg(feature = "glx")] GlxGenTextures(glx::GenTexturesRequest), #[cfg(feature = "glx")] GlxIsTexture(glx::IsTextureRequest), #[cfg(feature = "glx")] GlxGetColorTable(glx::GetColorTableRequest), #[cfg(feature = "glx")] GlxGetColorTableParameterfv(glx::GetColorTableParameterfvRequest), #[cfg(feature = "glx")] GlxGetColorTableParameteriv(glx::GetColorTableParameterivRequest), #[cfg(feature = "glx")] GlxGetConvolutionFilter(glx::GetConvolutionFilterRequest), #[cfg(feature = "glx")] GlxGetConvolutionParameterfv(glx::GetConvolutionParameterfvRequest), #[cfg(feature = "glx")] GlxGetConvolutionParameteriv(glx::GetConvolutionParameterivRequest), #[cfg(feature = "glx")] GlxGetSeparableFilter(glx::GetSeparableFilterRequest), #[cfg(feature = "glx")] GlxGetHistogram(glx::GetHistogramRequest), #[cfg(feature = "glx")] GlxGetHistogramParameterfv(glx::GetHistogramParameterfvRequest), #[cfg(feature = "glx")] GlxGetHistogramParameteriv(glx::GetHistogramParameterivRequest), #[cfg(feature = "glx")] GlxGetMinmax(glx::GetMinmaxRequest), #[cfg(feature = "glx")] GlxGetMinmaxParameterfv(glx::GetMinmaxParameterfvRequest), #[cfg(feature = "glx")] GlxGetMinmaxParameteriv(glx::GetMinmaxParameterivRequest), #[cfg(feature = "glx")] GlxGetCompressedTexImageARB(glx::GetCompressedTexImageARBRequest), #[cfg(feature = "glx")] GlxDeleteQueriesARB(glx::DeleteQueriesARBRequest<'input>), #[cfg(feature = "glx")] GlxGenQueriesARB(glx::GenQueriesARBRequest), #[cfg(feature = "glx")] GlxIsQueryARB(glx::IsQueryARBRequest), #[cfg(feature = "glx")] GlxGetQueryivARB(glx::GetQueryivARBRequest), #[cfg(feature = "glx")] GlxGetQueryObjectivARB(glx::GetQueryObjectivARBRequest), #[cfg(feature = "glx")] GlxGetQueryObjectuivARB(glx::GetQueryObjectuivARBRequest), #[cfg(feature = "present")] PresentQueryVersion(present::QueryVersionRequest), #[cfg(feature = "present")] PresentPixmap(present::PixmapRequest<'input>), #[cfg(feature = "present")] PresentNotifyMSC(present::NotifyMSCRequest), #[cfg(feature = "present")] PresentSelectInput(present::SelectInputRequest), #[cfg(feature = "present")] PresentQueryCapabilities(present::QueryCapabilitiesRequest), #[cfg(feature = "randr")] RandrQueryVersion(randr::QueryVersionRequest), #[cfg(feature = "randr")] RandrSetScreenConfig(randr::SetScreenConfigRequest), #[cfg(feature = "randr")] RandrSelectInput(randr::SelectInputRequest), #[cfg(feature = "randr")] RandrGetScreenInfo(randr::GetScreenInfoRequest), #[cfg(feature = "randr")] RandrGetScreenSizeRange(randr::GetScreenSizeRangeRequest), #[cfg(feature = "randr")] RandrSetScreenSize(randr::SetScreenSizeRequest), #[cfg(feature = "randr")] RandrGetScreenResources(randr::GetScreenResourcesRequest), #[cfg(feature = "randr")] RandrGetOutputInfo(randr::GetOutputInfoRequest), #[cfg(feature = "randr")] RandrListOutputProperties(randr::ListOutputPropertiesRequest), #[cfg(feature = "randr")] RandrQueryOutputProperty(randr::QueryOutputPropertyRequest), #[cfg(feature = "randr")] RandrConfigureOutputProperty(randr::ConfigureOutputPropertyRequest<'input>), #[cfg(feature = "randr")] RandrChangeOutputProperty(randr::ChangeOutputPropertyRequest<'input>), #[cfg(feature = "randr")] RandrDeleteOutputProperty(randr::DeleteOutputPropertyRequest), #[cfg(feature = "randr")] RandrGetOutputProperty(randr::GetOutputPropertyRequest), #[cfg(feature = "randr")] RandrCreateMode(randr::CreateModeRequest<'input>), #[cfg(feature = "randr")] RandrDestroyMode(randr::DestroyModeRequest), #[cfg(feature = "randr")] RandrAddOutputMode(randr::AddOutputModeRequest), #[cfg(feature = "randr")] RandrDeleteOutputMode(randr::DeleteOutputModeRequest), #[cfg(feature = "randr")] RandrGetCrtcInfo(randr::GetCrtcInfoRequest), #[cfg(feature = "randr")] RandrSetCrtcConfig(randr::SetCrtcConfigRequest<'input>), #[cfg(feature = "randr")] RandrGetCrtcGammaSize(randr::GetCrtcGammaSizeRequest), #[cfg(feature = "randr")] RandrGetCrtcGamma(randr::GetCrtcGammaRequest), #[cfg(feature = "randr")] RandrSetCrtcGamma(randr::SetCrtcGammaRequest<'input>), #[cfg(feature = "randr")] RandrGetScreenResourcesCurrent(randr::GetScreenResourcesCurrentRequest), #[cfg(feature = "randr")] RandrSetCrtcTransform(randr::SetCrtcTransformRequest<'input>), #[cfg(feature = "randr")] RandrGetCrtcTransform(randr::GetCrtcTransformRequest), #[cfg(feature = "randr")] RandrGetPanning(randr::GetPanningRequest), #[cfg(feature = "randr")] RandrSetPanning(randr::SetPanningRequest), #[cfg(feature = "randr")] RandrSetOutputPrimary(randr::SetOutputPrimaryRequest), #[cfg(feature = "randr")] RandrGetOutputPrimary(randr::GetOutputPrimaryRequest), #[cfg(feature = "randr")] RandrGetProviders(randr::GetProvidersRequest), #[cfg(feature = "randr")] RandrGetProviderInfo(randr::GetProviderInfoRequest), #[cfg(feature = "randr")] RandrSetProviderOffloadSink(randr::SetProviderOffloadSinkRequest), #[cfg(feature = "randr")] RandrSetProviderOutputSource(randr::SetProviderOutputSourceRequest), #[cfg(feature = "randr")] RandrListProviderProperties(randr::ListProviderPropertiesRequest), #[cfg(feature = "randr")] RandrQueryProviderProperty(randr::QueryProviderPropertyRequest), #[cfg(feature = "randr")] RandrConfigureProviderProperty(randr::ConfigureProviderPropertyRequest<'input>), #[cfg(feature = "randr")] RandrChangeProviderProperty(randr::ChangeProviderPropertyRequest<'input>), #[cfg(feature = "randr")] RandrDeleteProviderProperty(randr::DeleteProviderPropertyRequest), #[cfg(feature = "randr")] RandrGetProviderProperty(randr::GetProviderPropertyRequest), #[cfg(feature = "randr")] RandrGetMonitors(randr::GetMonitorsRequest), #[cfg(feature = "randr")] RandrSetMonitor(randr::SetMonitorRequest), #[cfg(feature = "randr")] RandrDeleteMonitor(randr::DeleteMonitorRequest), #[cfg(feature = "randr")] RandrCreateLease(randr::CreateLeaseRequest<'input>), #[cfg(feature = "randr")] RandrFreeLease(randr::FreeLeaseRequest), #[cfg(feature = "record")] RecordQueryVersion(record::QueryVersionRequest), #[cfg(feature = "record")] RecordCreateContext(record::CreateContextRequest<'input>), #[cfg(feature = "record")] RecordRegisterClients(record::RegisterClientsRequest<'input>), #[cfg(feature = "record")] RecordUnregisterClients(record::UnregisterClientsRequest<'input>), #[cfg(feature = "record")] RecordGetContext(record::GetContextRequest), #[cfg(feature = "record")] RecordEnableContext(record::EnableContextRequest), #[cfg(feature = "record")] RecordDisableContext(record::DisableContextRequest), #[cfg(feature = "record")] RecordFreeContext(record::FreeContextRequest), #[cfg(feature = "render")] RenderQueryVersion(render::QueryVersionRequest), #[cfg(feature = "render")] RenderQueryPictFormats(render::QueryPictFormatsRequest), #[cfg(feature = "render")] RenderQueryPictIndexValues(render::QueryPictIndexValuesRequest), #[cfg(feature = "render")] RenderCreatePicture(render::CreatePictureRequest<'input>), #[cfg(feature = "render")] RenderChangePicture(render::ChangePictureRequest<'input>), #[cfg(feature = "render")] RenderSetPictureClipRectangles(render::SetPictureClipRectanglesRequest<'input>), #[cfg(feature = "render")] RenderFreePicture(render::FreePictureRequest), #[cfg(feature = "render")] RenderComposite(render::CompositeRequest), #[cfg(feature = "render")] RenderTrapezoids(render::TrapezoidsRequest<'input>), #[cfg(feature = "render")] RenderTriangles(render::TrianglesRequest<'input>), #[cfg(feature = "render")] RenderTriStrip(render::TriStripRequest<'input>), #[cfg(feature = "render")] RenderTriFan(render::TriFanRequest<'input>), #[cfg(feature = "render")] RenderCreateGlyphSet(render::CreateGlyphSetRequest), #[cfg(feature = "render")] RenderReferenceGlyphSet(render::ReferenceGlyphSetRequest), #[cfg(feature = "render")] RenderFreeGlyphSet(render::FreeGlyphSetRequest), #[cfg(feature = "render")] RenderAddGlyphs(render::AddGlyphsRequest<'input>), #[cfg(feature = "render")] RenderFreeGlyphs(render::FreeGlyphsRequest<'input>), #[cfg(feature = "render")] RenderCompositeGlyphs8(render::CompositeGlyphs8Request<'input>), #[cfg(feature = "render")] RenderCompositeGlyphs16(render::CompositeGlyphs16Request<'input>), #[cfg(feature = "render")] RenderCompositeGlyphs32(render::CompositeGlyphs32Request<'input>), #[cfg(feature = "render")] RenderFillRectangles(render::FillRectanglesRequest<'input>), #[cfg(feature = "render")] RenderCreateCursor(render::CreateCursorRequest), #[cfg(feature = "render")] RenderSetPictureTransform(render::SetPictureTransformRequest), #[cfg(feature = "render")] RenderQueryFilters(render::QueryFiltersRequest), #[cfg(feature = "render")] RenderSetPictureFilter(render::SetPictureFilterRequest<'input>), #[cfg(feature = "render")] RenderCreateAnimCursor(render::CreateAnimCursorRequest<'input>), #[cfg(feature = "render")] RenderAddTraps(render::AddTrapsRequest<'input>), #[cfg(feature = "render")] RenderCreateSolidFill(render::CreateSolidFillRequest), #[cfg(feature = "render")] RenderCreateLinearGradient(render::CreateLinearGradientRequest<'input>), #[cfg(feature = "render")] RenderCreateRadialGradient(render::CreateRadialGradientRequest<'input>), #[cfg(feature = "render")] RenderCreateConicalGradient(render::CreateConicalGradientRequest<'input>), #[cfg(feature = "res")] ResQueryVersion(res::QueryVersionRequest), #[cfg(feature = "res")] ResQueryClients(res::QueryClientsRequest), #[cfg(feature = "res")] ResQueryClientResources(res::QueryClientResourcesRequest), #[cfg(feature = "res")] ResQueryClientPixmapBytes(res::QueryClientPixmapBytesRequest), #[cfg(feature = "res")] ResQueryClientIds(res::QueryClientIdsRequest<'input>), #[cfg(feature = "res")] ResQueryResourceBytes(res::QueryResourceBytesRequest<'input>), #[cfg(feature = "screensaver")] ScreensaverQueryVersion(screensaver::QueryVersionRequest), #[cfg(feature = "screensaver")] ScreensaverQueryInfo(screensaver::QueryInfoRequest), #[cfg(feature = "screensaver")] ScreensaverSelectInput(screensaver::SelectInputRequest), #[cfg(feature = "screensaver")] ScreensaverSetAttributes(screensaver::SetAttributesRequest<'input>), #[cfg(feature = "screensaver")] ScreensaverUnsetAttributes(screensaver::UnsetAttributesRequest), #[cfg(feature = "screensaver")] ScreensaverSuspend(screensaver::SuspendRequest), #[cfg(feature = "shape")] ShapeQueryVersion(shape::QueryVersionRequest), #[cfg(feature = "shape")] ShapeRectangles(shape::RectanglesRequest<'input>), #[cfg(feature = "shape")] ShapeMask(shape::MaskRequest), #[cfg(feature = "shape")] ShapeCombine(shape::CombineRequest), #[cfg(feature = "shape")] ShapeOffset(shape::OffsetRequest), #[cfg(feature = "shape")] ShapeQueryExtents(shape::QueryExtentsRequest), #[cfg(feature = "shape")] ShapeSelectInput(shape::SelectInputRequest), #[cfg(feature = "shape")] ShapeInputSelected(shape::InputSelectedRequest), #[cfg(feature = "shape")] ShapeGetRectangles(shape::GetRectanglesRequest), #[cfg(feature = "shm")] ShmQueryVersion(shm::QueryVersionRequest), #[cfg(feature = "shm")] ShmAttach(shm::AttachRequest), #[cfg(feature = "shm")] ShmDetach(shm::DetachRequest), #[cfg(feature = "shm")] ShmPutImage(shm::PutImageRequest), #[cfg(feature = "shm")] ShmGetImage(shm::GetImageRequest), #[cfg(feature = "shm")] ShmCreatePixmap(shm::CreatePixmapRequest), #[cfg(feature = "shm")] ShmAttachFd(shm::AttachFdRequest), #[cfg(feature = "shm")] ShmCreateSegment(shm::CreateSegmentRequest), #[cfg(feature = "sync")] SyncInitialize(sync::InitializeRequest), #[cfg(feature = "sync")] SyncListSystemCounters(sync::ListSystemCountersRequest), #[cfg(feature = "sync")] SyncCreateCounter(sync::CreateCounterRequest), #[cfg(feature = "sync")] SyncDestroyCounter(sync::DestroyCounterRequest), #[cfg(feature = "sync")] SyncQueryCounter(sync::QueryCounterRequest), #[cfg(feature = "sync")] SyncAwait(sync::AwaitRequest<'input>), #[cfg(feature = "sync")] SyncChangeCounter(sync::ChangeCounterRequest), #[cfg(feature = "sync")] SyncSetCounter(sync::SetCounterRequest), #[cfg(feature = "sync")] SyncCreateAlarm(sync::CreateAlarmRequest<'input>), #[cfg(feature = "sync")] SyncChangeAlarm(sync::ChangeAlarmRequest<'input>), #[cfg(feature = "sync")] SyncDestroyAlarm(sync::DestroyAlarmRequest), #[cfg(feature = "sync")] SyncQueryAlarm(sync::QueryAlarmRequest), #[cfg(feature = "sync")] SyncSetPriority(sync::SetPriorityRequest), #[cfg(feature = "sync")] SyncGetPriority(sync::GetPriorityRequest), #[cfg(feature = "sync")] SyncCreateFence(sync::CreateFenceRequest), #[cfg(feature = "sync")] SyncTriggerFence(sync::TriggerFenceRequest), #[cfg(feature = "sync")] SyncResetFence(sync::ResetFenceRequest), #[cfg(feature = "sync")] SyncDestroyFence(sync::DestroyFenceRequest), #[cfg(feature = "sync")] SyncQueryFence(sync::QueryFenceRequest), #[cfg(feature = "sync")] SyncAwaitFence(sync::AwaitFenceRequest<'input>), XcMiscGetVersion(xc_misc::GetVersionRequest), XcMiscGetXIDRange(xc_misc::GetXIDRangeRequest), XcMiscGetXIDList(xc_misc::GetXIDListRequest), #[cfg(feature = "xevie")] XevieQueryVersion(xevie::QueryVersionRequest), #[cfg(feature = "xevie")] XevieStart(xevie::StartRequest), #[cfg(feature = "xevie")] XevieEnd(xevie::EndRequest), #[cfg(feature = "xevie")] XevieSend(xevie::SendRequest), #[cfg(feature = "xevie")] XevieSelectInput(xevie::SelectInputRequest), #[cfg(feature = "xf86dri")] Xf86driQueryVersion(xf86dri::QueryVersionRequest), #[cfg(feature = "xf86dri")] Xf86driQueryDirectRenderingCapable(xf86dri::QueryDirectRenderingCapableRequest), #[cfg(feature = "xf86dri")] Xf86driOpenConnection(xf86dri::OpenConnectionRequest), #[cfg(feature = "xf86dri")] Xf86driCloseConnection(xf86dri::CloseConnectionRequest), #[cfg(feature = "xf86dri")] Xf86driGetClientDriverName(xf86dri::GetClientDriverNameRequest), #[cfg(feature = "xf86dri")] Xf86driCreateContext(xf86dri::CreateContextRequest), #[cfg(feature = "xf86dri")] Xf86driDestroyContext(xf86dri::DestroyContextRequest), #[cfg(feature = "xf86dri")] Xf86driCreateDrawable(xf86dri::CreateDrawableRequest), #[cfg(feature = "xf86dri")] Xf86driDestroyDrawable(xf86dri::DestroyDrawableRequest), #[cfg(feature = "xf86dri")] Xf86driGetDrawableInfo(xf86dri::GetDrawableInfoRequest), #[cfg(feature = "xf86dri")] Xf86driGetDeviceInfo(xf86dri::GetDeviceInfoRequest), #[cfg(feature = "xf86dri")] Xf86driAuthConnection(xf86dri::AuthConnectionRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeQueryVersion(xf86vidmode::QueryVersionRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetModeLine(xf86vidmode::GetModeLineRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeModModeLine(xf86vidmode::ModModeLineRequest<'input>), #[cfg(feature = "xf86vidmode")] Xf86vidmodeSwitchMode(xf86vidmode::SwitchModeRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetMonitor(xf86vidmode::GetMonitorRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeLockModeSwitch(xf86vidmode::LockModeSwitchRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetAllModeLines(xf86vidmode::GetAllModeLinesRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeAddModeLine(xf86vidmode::AddModeLineRequest<'input>), #[cfg(feature = "xf86vidmode")] Xf86vidmodeDeleteModeLine(xf86vidmode::DeleteModeLineRequest<'input>), #[cfg(feature = "xf86vidmode")] Xf86vidmodeValidateModeLine(xf86vidmode::ValidateModeLineRequest<'input>), #[cfg(feature = "xf86vidmode")] Xf86vidmodeSwitchToMode(xf86vidmode::SwitchToModeRequest<'input>), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetViewPort(xf86vidmode::GetViewPortRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeSetViewPort(xf86vidmode::SetViewPortRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetDotClocks(xf86vidmode::GetDotClocksRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeSetClientVersion(xf86vidmode::SetClientVersionRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeSetGamma(xf86vidmode::SetGammaRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetGamma(xf86vidmode::GetGammaRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetGammaRamp(xf86vidmode::GetGammaRampRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeSetGammaRamp(xf86vidmode::SetGammaRampRequest<'input>), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetGammaRampSize(xf86vidmode::GetGammaRampSizeRequest), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetPermissions(xf86vidmode::GetPermissionsRequest), #[cfg(feature = "xfixes")] XfixesQueryVersion(xfixes::QueryVersionRequest), #[cfg(feature = "xfixes")] XfixesChangeSaveSet(xfixes::ChangeSaveSetRequest), #[cfg(feature = "xfixes")] XfixesSelectSelectionInput(xfixes::SelectSelectionInputRequest), #[cfg(feature = "xfixes")] XfixesSelectCursorInput(xfixes::SelectCursorInputRequest), #[cfg(feature = "xfixes")] XfixesGetCursorImage(xfixes::GetCursorImageRequest), #[cfg(feature = "xfixes")] XfixesCreateRegion(xfixes::CreateRegionRequest<'input>), #[cfg(feature = "xfixes")] XfixesCreateRegionFromBitmap(xfixes::CreateRegionFromBitmapRequest), #[cfg(feature = "xfixes")] XfixesCreateRegionFromWindow(xfixes::CreateRegionFromWindowRequest), #[cfg(feature = "xfixes")] XfixesCreateRegionFromGC(xfixes::CreateRegionFromGCRequest), #[cfg(feature = "xfixes")] XfixesCreateRegionFromPicture(xfixes::CreateRegionFromPictureRequest), #[cfg(feature = "xfixes")] XfixesDestroyRegion(xfixes::DestroyRegionRequest), #[cfg(feature = "xfixes")] XfixesSetRegion(xfixes::SetRegionRequest<'input>), #[cfg(feature = "xfixes")] XfixesCopyRegion(xfixes::CopyRegionRequest), #[cfg(feature = "xfixes")] XfixesUnionRegion(xfixes::UnionRegionRequest), #[cfg(feature = "xfixes")] XfixesIntersectRegion(xfixes::IntersectRegionRequest), #[cfg(feature = "xfixes")] XfixesSubtractRegion(xfixes::SubtractRegionRequest), #[cfg(feature = "xfixes")] XfixesInvertRegion(xfixes::InvertRegionRequest), #[cfg(feature = "xfixes")] XfixesTranslateRegion(xfixes::TranslateRegionRequest), #[cfg(feature = "xfixes")] XfixesRegionExtents(xfixes::RegionExtentsRequest), #[cfg(feature = "xfixes")] XfixesFetchRegion(xfixes::FetchRegionRequest), #[cfg(feature = "xfixes")] XfixesSetGCClipRegion(xfixes::SetGCClipRegionRequest), #[cfg(feature = "xfixes")] XfixesSetWindowShapeRegion(xfixes::SetWindowShapeRegionRequest), #[cfg(feature = "xfixes")] XfixesSetPictureClipRegion(xfixes::SetPictureClipRegionRequest), #[cfg(feature = "xfixes")] XfixesSetCursorName(xfixes::SetCursorNameRequest<'input>), #[cfg(feature = "xfixes")] XfixesGetCursorName(xfixes::GetCursorNameRequest), #[cfg(feature = "xfixes")] XfixesGetCursorImageAndName(xfixes::GetCursorImageAndNameRequest), #[cfg(feature = "xfixes")] XfixesChangeCursor(xfixes::ChangeCursorRequest), #[cfg(feature = "xfixes")] XfixesChangeCursorByName(xfixes::ChangeCursorByNameRequest<'input>), #[cfg(feature = "xfixes")] XfixesExpandRegion(xfixes::ExpandRegionRequest), #[cfg(feature = "xfixes")] XfixesHideCursor(xfixes::HideCursorRequest), #[cfg(feature = "xfixes")] XfixesShowCursor(xfixes::ShowCursorRequest), #[cfg(feature = "xfixes")] XfixesCreatePointerBarrier(xfixes::CreatePointerBarrierRequest<'input>), #[cfg(feature = "xfixes")] XfixesDeletePointerBarrier(xfixes::DeletePointerBarrierRequest), #[cfg(feature = "xinerama")] XineramaQueryVersion(xinerama::QueryVersionRequest), #[cfg(feature = "xinerama")] XineramaGetState(xinerama::GetStateRequest), #[cfg(feature = "xinerama")] XineramaGetScreenCount(xinerama::GetScreenCountRequest), #[cfg(feature = "xinerama")] XineramaGetScreenSize(xinerama::GetScreenSizeRequest), #[cfg(feature = "xinerama")] XineramaIsActive(xinerama::IsActiveRequest), #[cfg(feature = "xinerama")] XineramaQueryScreens(xinerama::QueryScreensRequest), #[cfg(feature = "xinput")] XinputGetExtensionVersion(xinput::GetExtensionVersionRequest<'input>), #[cfg(feature = "xinput")] XinputListInputDevices(xinput::ListInputDevicesRequest), #[cfg(feature = "xinput")] XinputOpenDevice(xinput::OpenDeviceRequest), #[cfg(feature = "xinput")] XinputCloseDevice(xinput::CloseDeviceRequest), #[cfg(feature = "xinput")] XinputSetDeviceMode(xinput::SetDeviceModeRequest), #[cfg(feature = "xinput")] XinputSelectExtensionEvent(xinput::SelectExtensionEventRequest<'input>), #[cfg(feature = "xinput")] XinputGetSelectedExtensionEvents(xinput::GetSelectedExtensionEventsRequest), #[cfg(feature = "xinput")] XinputChangeDeviceDontPropagateList(xinput::ChangeDeviceDontPropagateListRequest<'input>), #[cfg(feature = "xinput")] XinputGetDeviceDontPropagateList(xinput::GetDeviceDontPropagateListRequest), #[cfg(feature = "xinput")] XinputGetDeviceMotionEvents(xinput::GetDeviceMotionEventsRequest), #[cfg(feature = "xinput")] XinputChangeKeyboardDevice(xinput::ChangeKeyboardDeviceRequest), #[cfg(feature = "xinput")] XinputChangePointerDevice(xinput::ChangePointerDeviceRequest), #[cfg(feature = "xinput")] XinputGrabDevice(xinput::GrabDeviceRequest<'input>), #[cfg(feature = "xinput")] XinputUngrabDevice(xinput::UngrabDeviceRequest), #[cfg(feature = "xinput")] XinputGrabDeviceKey(xinput::GrabDeviceKeyRequest<'input>), #[cfg(feature = "xinput")] XinputUngrabDeviceKey(xinput::UngrabDeviceKeyRequest), #[cfg(feature = "xinput")] XinputGrabDeviceButton(xinput::GrabDeviceButtonRequest<'input>), #[cfg(feature = "xinput")] XinputUngrabDeviceButton(xinput::UngrabDeviceButtonRequest), #[cfg(feature = "xinput")] XinputAllowDeviceEvents(xinput::AllowDeviceEventsRequest), #[cfg(feature = "xinput")] XinputGetDeviceFocus(xinput::GetDeviceFocusRequest), #[cfg(feature = "xinput")] XinputSetDeviceFocus(xinput::SetDeviceFocusRequest), #[cfg(feature = "xinput")] XinputGetFeedbackControl(xinput::GetFeedbackControlRequest), #[cfg(feature = "xinput")] XinputChangeFeedbackControl(xinput::ChangeFeedbackControlRequest), #[cfg(feature = "xinput")] XinputGetDeviceKeyMapping(xinput::GetDeviceKeyMappingRequest), #[cfg(feature = "xinput")] XinputChangeDeviceKeyMapping(xinput::ChangeDeviceKeyMappingRequest<'input>), #[cfg(feature = "xinput")] XinputGetDeviceModifierMapping(xinput::GetDeviceModifierMappingRequest), #[cfg(feature = "xinput")] XinputSetDeviceModifierMapping(xinput::SetDeviceModifierMappingRequest<'input>), #[cfg(feature = "xinput")] XinputGetDeviceButtonMapping(xinput::GetDeviceButtonMappingRequest), #[cfg(feature = "xinput")] XinputSetDeviceButtonMapping(xinput::SetDeviceButtonMappingRequest<'input>), #[cfg(feature = "xinput")] XinputQueryDeviceState(xinput::QueryDeviceStateRequest), #[cfg(feature = "xinput")] XinputDeviceBell(xinput::DeviceBellRequest), #[cfg(feature = "xinput")] XinputSetDeviceValuators(xinput::SetDeviceValuatorsRequest<'input>), #[cfg(feature = "xinput")] XinputGetDeviceControl(xinput::GetDeviceControlRequest), #[cfg(feature = "xinput")] XinputChangeDeviceControl(xinput::ChangeDeviceControlRequest), #[cfg(feature = "xinput")] XinputListDeviceProperties(xinput::ListDevicePropertiesRequest), #[cfg(feature = "xinput")] XinputChangeDeviceProperty(xinput::ChangeDevicePropertyRequest<'input>), #[cfg(feature = "xinput")] XinputDeleteDeviceProperty(xinput::DeleteDevicePropertyRequest), #[cfg(feature = "xinput")] XinputGetDeviceProperty(xinput::GetDevicePropertyRequest), #[cfg(feature = "xinput")] XinputXIQueryPointer(xinput::XIQueryPointerRequest), #[cfg(feature = "xinput")] XinputXIWarpPointer(xinput::XIWarpPointerRequest), #[cfg(feature = "xinput")] XinputXIChangeCursor(xinput::XIChangeCursorRequest), #[cfg(feature = "xinput")] XinputXIChangeHierarchy(xinput::XIChangeHierarchyRequest<'input>), #[cfg(feature = "xinput")] XinputXISetClientPointer(xinput::XISetClientPointerRequest), #[cfg(feature = "xinput")] XinputXIGetClientPointer(xinput::XIGetClientPointerRequest), #[cfg(feature = "xinput")] XinputXISelectEvents(xinput::XISelectEventsRequest<'input>), #[cfg(feature = "xinput")] XinputXIQueryVersion(xinput::XIQueryVersionRequest), #[cfg(feature = "xinput")] XinputXIQueryDevice(xinput::XIQueryDeviceRequest), #[cfg(feature = "xinput")] XinputXISetFocus(xinput::XISetFocusRequest), #[cfg(feature = "xinput")] XinputXIGetFocus(xinput::XIGetFocusRequest), #[cfg(feature = "xinput")] XinputXIGrabDevice(xinput::XIGrabDeviceRequest<'input>), #[cfg(feature = "xinput")] XinputXIUngrabDevice(xinput::XIUngrabDeviceRequest), #[cfg(feature = "xinput")] XinputXIAllowEvents(xinput::XIAllowEventsRequest), #[cfg(feature = "xinput")] XinputXIPassiveGrabDevice(xinput::XIPassiveGrabDeviceRequest<'input>), #[cfg(feature = "xinput")] XinputXIPassiveUngrabDevice(xinput::XIPassiveUngrabDeviceRequest<'input>), #[cfg(feature = "xinput")] XinputXIListProperties(xinput::XIListPropertiesRequest), #[cfg(feature = "xinput")] XinputXIChangeProperty(xinput::XIChangePropertyRequest<'input>), #[cfg(feature = "xinput")] XinputXIDeleteProperty(xinput::XIDeletePropertyRequest), #[cfg(feature = "xinput")] XinputXIGetProperty(xinput::XIGetPropertyRequest), #[cfg(feature = "xinput")] XinputXIGetSelectedEvents(xinput::XIGetSelectedEventsRequest), #[cfg(feature = "xinput")] XinputXIBarrierReleasePointer(xinput::XIBarrierReleasePointerRequest<'input>), #[cfg(feature = "xinput")] XinputSendExtensionEvent(xinput::SendExtensionEventRequest<'input>), #[cfg(feature = "xkb")] XkbUseExtension(xkb::UseExtensionRequest), #[cfg(feature = "xkb")] XkbSelectEvents(xkb::SelectEventsRequest<'input>), #[cfg(feature = "xkb")] XkbBell(xkb::BellRequest), #[cfg(feature = "xkb")] XkbGetState(xkb::GetStateRequest), #[cfg(feature = "xkb")] XkbLatchLockState(xkb::LatchLockStateRequest), #[cfg(feature = "xkb")] XkbGetControls(xkb::GetControlsRequest), #[cfg(feature = "xkb")] XkbSetControls(xkb::SetControlsRequest<'input>), #[cfg(feature = "xkb")] XkbGetMap(xkb::GetMapRequest), #[cfg(feature = "xkb")] XkbSetMap(xkb::SetMapRequest<'input>), #[cfg(feature = "xkb")] XkbGetCompatMap(xkb::GetCompatMapRequest), #[cfg(feature = "xkb")] XkbSetCompatMap(xkb::SetCompatMapRequest<'input>), #[cfg(feature = "xkb")] XkbGetIndicatorState(xkb::GetIndicatorStateRequest), #[cfg(feature = "xkb")] XkbGetIndicatorMap(xkb::GetIndicatorMapRequest), #[cfg(feature = "xkb")] XkbSetIndicatorMap(xkb::SetIndicatorMapRequest<'input>), #[cfg(feature = "xkb")] XkbGetNamedIndicator(xkb::GetNamedIndicatorRequest), #[cfg(feature = "xkb")] XkbSetNamedIndicator(xkb::SetNamedIndicatorRequest), #[cfg(feature = "xkb")] XkbGetNames(xkb::GetNamesRequest), #[cfg(feature = "xkb")] XkbSetNames(xkb::SetNamesRequest<'input>), #[cfg(feature = "xkb")] XkbPerClientFlags(xkb::PerClientFlagsRequest), #[cfg(feature = "xkb")] XkbListComponents(xkb::ListComponentsRequest), #[cfg(feature = "xkb")] XkbGetKbdByName(xkb::GetKbdByNameRequest), #[cfg(feature = "xkb")] XkbGetDeviceInfo(xkb::GetDeviceInfoRequest), #[cfg(feature = "xkb")] XkbSetDeviceInfo(xkb::SetDeviceInfoRequest<'input>), #[cfg(feature = "xkb")] XkbSetDebuggingFlags(xkb::SetDebuggingFlagsRequest<'input>), #[cfg(feature = "xprint")] XprintPrintQueryVersion(xprint::PrintQueryVersionRequest), #[cfg(feature = "xprint")] XprintPrintGetPrinterList(xprint::PrintGetPrinterListRequest<'input>), #[cfg(feature = "xprint")] XprintPrintRehashPrinterList(xprint::PrintRehashPrinterListRequest), #[cfg(feature = "xprint")] XprintCreateContext(xprint::CreateContextRequest<'input>), #[cfg(feature = "xprint")] XprintPrintSetContext(xprint::PrintSetContextRequest), #[cfg(feature = "xprint")] XprintPrintGetContext(xprint::PrintGetContextRequest), #[cfg(feature = "xprint")] XprintPrintDestroyContext(xprint::PrintDestroyContextRequest), #[cfg(feature = "xprint")] XprintPrintGetScreenOfContext(xprint::PrintGetScreenOfContextRequest), #[cfg(feature = "xprint")] XprintPrintStartJob(xprint::PrintStartJobRequest), #[cfg(feature = "xprint")] XprintPrintEndJob(xprint::PrintEndJobRequest), #[cfg(feature = "xprint")] XprintPrintStartDoc(xprint::PrintStartDocRequest), #[cfg(feature = "xprint")] XprintPrintEndDoc(xprint::PrintEndDocRequest), #[cfg(feature = "xprint")] XprintPrintPutDocumentData(xprint::PrintPutDocumentDataRequest<'input>), #[cfg(feature = "xprint")] XprintPrintGetDocumentData(xprint::PrintGetDocumentDataRequest), #[cfg(feature = "xprint")] XprintPrintStartPage(xprint::PrintStartPageRequest), #[cfg(feature = "xprint")] XprintPrintEndPage(xprint::PrintEndPageRequest), #[cfg(feature = "xprint")] XprintPrintSelectInput(xprint::PrintSelectInputRequest), #[cfg(feature = "xprint")] XprintPrintInputSelected(xprint::PrintInputSelectedRequest), #[cfg(feature = "xprint")] XprintPrintGetAttributes(xprint::PrintGetAttributesRequest), #[cfg(feature = "xprint")] XprintPrintGetOneAttributes(xprint::PrintGetOneAttributesRequest<'input>), #[cfg(feature = "xprint")] XprintPrintSetAttributes(xprint::PrintSetAttributesRequest<'input>), #[cfg(feature = "xprint")] XprintPrintGetPageDimensions(xprint::PrintGetPageDimensionsRequest), #[cfg(feature = "xprint")] XprintPrintQueryScreens(xprint::PrintQueryScreensRequest), #[cfg(feature = "xprint")] XprintPrintSetImageResolution(xprint::PrintSetImageResolutionRequest), #[cfg(feature = "xprint")] XprintPrintGetImageResolution(xprint::PrintGetImageResolutionRequest), #[cfg(feature = "xselinux")] XselinuxQueryVersion(xselinux::QueryVersionRequest), #[cfg(feature = "xselinux")] XselinuxSetDeviceCreateContext(xselinux::SetDeviceCreateContextRequest<'input>), #[cfg(feature = "xselinux")] XselinuxGetDeviceCreateContext(xselinux::GetDeviceCreateContextRequest), #[cfg(feature = "xselinux")] XselinuxSetDeviceContext(xselinux::SetDeviceContextRequest<'input>), #[cfg(feature = "xselinux")] XselinuxGetDeviceContext(xselinux::GetDeviceContextRequest), #[cfg(feature = "xselinux")] XselinuxSetWindowCreateContext(xselinux::SetWindowCreateContextRequest<'input>), #[cfg(feature = "xselinux")] XselinuxGetWindowCreateContext(xselinux::GetWindowCreateContextRequest), #[cfg(feature = "xselinux")] XselinuxGetWindowContext(xselinux::GetWindowContextRequest), #[cfg(feature = "xselinux")] XselinuxSetPropertyCreateContext(xselinux::SetPropertyCreateContextRequest<'input>), #[cfg(feature = "xselinux")] XselinuxGetPropertyCreateContext(xselinux::GetPropertyCreateContextRequest), #[cfg(feature = "xselinux")] XselinuxSetPropertyUseContext(xselinux::SetPropertyUseContextRequest<'input>), #[cfg(feature = "xselinux")] XselinuxGetPropertyUseContext(xselinux::GetPropertyUseContextRequest), #[cfg(feature = "xselinux")] XselinuxGetPropertyContext(xselinux::GetPropertyContextRequest), #[cfg(feature = "xselinux")] XselinuxGetPropertyDataContext(xselinux::GetPropertyDataContextRequest), #[cfg(feature = "xselinux")] XselinuxListProperties(xselinux::ListPropertiesRequest), #[cfg(feature = "xselinux")] XselinuxSetSelectionCreateContext(xselinux::SetSelectionCreateContextRequest<'input>), #[cfg(feature = "xselinux")] XselinuxGetSelectionCreateContext(xselinux::GetSelectionCreateContextRequest), #[cfg(feature = "xselinux")] XselinuxSetSelectionUseContext(xselinux::SetSelectionUseContextRequest<'input>), #[cfg(feature = "xselinux")] XselinuxGetSelectionUseContext(xselinux::GetSelectionUseContextRequest), #[cfg(feature = "xselinux")] XselinuxGetSelectionContext(xselinux::GetSelectionContextRequest), #[cfg(feature = "xselinux")] XselinuxGetSelectionDataContext(xselinux::GetSelectionDataContextRequest), #[cfg(feature = "xselinux")] XselinuxListSelections(xselinux::ListSelectionsRequest), #[cfg(feature = "xselinux")] XselinuxGetClientContext(xselinux::GetClientContextRequest), #[cfg(feature = "xtest")] XtestGetVersion(xtest::GetVersionRequest), #[cfg(feature = "xtest")] XtestCompareCursor(xtest::CompareCursorRequest), #[cfg(feature = "xtest")] XtestFakeInput(xtest::FakeInputRequest), #[cfg(feature = "xtest")] XtestGrabControl(xtest::GrabControlRequest), #[cfg(feature = "xv")] XvQueryExtension(xv::QueryExtensionRequest), #[cfg(feature = "xv")] XvQueryAdaptors(xv::QueryAdaptorsRequest), #[cfg(feature = "xv")] XvQueryEncodings(xv::QueryEncodingsRequest), #[cfg(feature = "xv")] XvGrabPort(xv::GrabPortRequest), #[cfg(feature = "xv")] XvUngrabPort(xv::UngrabPortRequest), #[cfg(feature = "xv")] XvPutVideo(xv::PutVideoRequest), #[cfg(feature = "xv")] XvPutStill(xv::PutStillRequest), #[cfg(feature = "xv")] XvGetVideo(xv::GetVideoRequest), #[cfg(feature = "xv")] XvGetStill(xv::GetStillRequest), #[cfg(feature = "xv")] XvStopVideo(xv::StopVideoRequest), #[cfg(feature = "xv")] XvSelectVideoNotify(xv::SelectVideoNotifyRequest), #[cfg(feature = "xv")] XvSelectPortNotify(xv::SelectPortNotifyRequest), #[cfg(feature = "xv")] XvQueryBestSize(xv::QueryBestSizeRequest), #[cfg(feature = "xv")] XvSetPortAttribute(xv::SetPortAttributeRequest), #[cfg(feature = "xv")] XvGetPortAttribute(xv::GetPortAttributeRequest), #[cfg(feature = "xv")] XvQueryPortAttributes(xv::QueryPortAttributesRequest), #[cfg(feature = "xv")] XvListImageFormats(xv::ListImageFormatsRequest), #[cfg(feature = "xv")] XvQueryImageAttributes(xv::QueryImageAttributesRequest), #[cfg(feature = "xv")] XvPutImage(xv::PutImageRequest<'input>), #[cfg(feature = "xv")] XvShmPutImage(xv::ShmPutImageRequest), #[cfg(feature = "xvmc")] XvmcQueryVersion(xvmc::QueryVersionRequest), #[cfg(feature = "xvmc")] XvmcListSurfaceTypes(xvmc::ListSurfaceTypesRequest), #[cfg(feature = "xvmc")] XvmcCreateContext(xvmc::CreateContextRequest), #[cfg(feature = "xvmc")] XvmcDestroyContext(xvmc::DestroyContextRequest), #[cfg(feature = "xvmc")] XvmcCreateSurface(xvmc::CreateSurfaceRequest), #[cfg(feature = "xvmc")] XvmcDestroySurface(xvmc::DestroySurfaceRequest), #[cfg(feature = "xvmc")] XvmcCreateSubpicture(xvmc::CreateSubpictureRequest), #[cfg(feature = "xvmc")] XvmcDestroySubpicture(xvmc::DestroySubpictureRequest), #[cfg(feature = "xvmc")] XvmcListSubpictureTypes(xvmc::ListSubpictureTypesRequest), } impl<'input> Request<'input> { // Parse a X11 request into a concrete type #[allow(clippy::cognitive_complexity, clippy::single_match)] pub fn parse( header: RequestHeader, body: &'input [u8], // Might not be used if none of the extensions that use FD passing is enabled #[allow(unused_variables)] fds: &mut Vec, ext_info_provider: &dyn ExtInfoProvider, ) -> Result { let remaining = body; // Check if this is a core protocol request. match header.major_opcode { xproto::CREATE_WINDOW_REQUEST => return Ok(Request::CreateWindow(xproto::CreateWindowRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_WINDOW_ATTRIBUTES_REQUEST => return Ok(Request::ChangeWindowAttributes(xproto::ChangeWindowAttributesRequest::try_parse_request(header, remaining)?)), xproto::GET_WINDOW_ATTRIBUTES_REQUEST => return Ok(Request::GetWindowAttributes(xproto::GetWindowAttributesRequest::try_parse_request(header, remaining)?)), xproto::DESTROY_WINDOW_REQUEST => return Ok(Request::DestroyWindow(xproto::DestroyWindowRequest::try_parse_request(header, remaining)?)), xproto::DESTROY_SUBWINDOWS_REQUEST => return Ok(Request::DestroySubwindows(xproto::DestroySubwindowsRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_SAVE_SET_REQUEST => return Ok(Request::ChangeSaveSet(xproto::ChangeSaveSetRequest::try_parse_request(header, remaining)?)), xproto::REPARENT_WINDOW_REQUEST => return Ok(Request::ReparentWindow(xproto::ReparentWindowRequest::try_parse_request(header, remaining)?)), xproto::MAP_WINDOW_REQUEST => return Ok(Request::MapWindow(xproto::MapWindowRequest::try_parse_request(header, remaining)?)), xproto::MAP_SUBWINDOWS_REQUEST => return Ok(Request::MapSubwindows(xproto::MapSubwindowsRequest::try_parse_request(header, remaining)?)), xproto::UNMAP_WINDOW_REQUEST => return Ok(Request::UnmapWindow(xproto::UnmapWindowRequest::try_parse_request(header, remaining)?)), xproto::UNMAP_SUBWINDOWS_REQUEST => return Ok(Request::UnmapSubwindows(xproto::UnmapSubwindowsRequest::try_parse_request(header, remaining)?)), xproto::CONFIGURE_WINDOW_REQUEST => return Ok(Request::ConfigureWindow(xproto::ConfigureWindowRequest::try_parse_request(header, remaining)?)), xproto::CIRCULATE_WINDOW_REQUEST => return Ok(Request::CirculateWindow(xproto::CirculateWindowRequest::try_parse_request(header, remaining)?)), xproto::GET_GEOMETRY_REQUEST => return Ok(Request::GetGeometry(xproto::GetGeometryRequest::try_parse_request(header, remaining)?)), xproto::QUERY_TREE_REQUEST => return Ok(Request::QueryTree(xproto::QueryTreeRequest::try_parse_request(header, remaining)?)), xproto::INTERN_ATOM_REQUEST => return Ok(Request::InternAtom(xproto::InternAtomRequest::try_parse_request(header, remaining)?)), xproto::GET_ATOM_NAME_REQUEST => return Ok(Request::GetAtomName(xproto::GetAtomNameRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_PROPERTY_REQUEST => return Ok(Request::ChangeProperty(xproto::ChangePropertyRequest::try_parse_request(header, remaining)?)), xproto::DELETE_PROPERTY_REQUEST => return Ok(Request::DeleteProperty(xproto::DeletePropertyRequest::try_parse_request(header, remaining)?)), xproto::GET_PROPERTY_REQUEST => return Ok(Request::GetProperty(xproto::GetPropertyRequest::try_parse_request(header, remaining)?)), xproto::LIST_PROPERTIES_REQUEST => return Ok(Request::ListProperties(xproto::ListPropertiesRequest::try_parse_request(header, remaining)?)), xproto::SET_SELECTION_OWNER_REQUEST => return Ok(Request::SetSelectionOwner(xproto::SetSelectionOwnerRequest::try_parse_request(header, remaining)?)), xproto::GET_SELECTION_OWNER_REQUEST => return Ok(Request::GetSelectionOwner(xproto::GetSelectionOwnerRequest::try_parse_request(header, remaining)?)), xproto::CONVERT_SELECTION_REQUEST => return Ok(Request::ConvertSelection(xproto::ConvertSelectionRequest::try_parse_request(header, remaining)?)), xproto::SEND_EVENT_REQUEST => return Ok(Request::SendEvent(xproto::SendEventRequest::try_parse_request(header, remaining)?)), xproto::GRAB_POINTER_REQUEST => return Ok(Request::GrabPointer(xproto::GrabPointerRequest::try_parse_request(header, remaining)?)), xproto::UNGRAB_POINTER_REQUEST => return Ok(Request::UngrabPointer(xproto::UngrabPointerRequest::try_parse_request(header, remaining)?)), xproto::GRAB_BUTTON_REQUEST => return Ok(Request::GrabButton(xproto::GrabButtonRequest::try_parse_request(header, remaining)?)), xproto::UNGRAB_BUTTON_REQUEST => return Ok(Request::UngrabButton(xproto::UngrabButtonRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_ACTIVE_POINTER_GRAB_REQUEST => return Ok(Request::ChangeActivePointerGrab(xproto::ChangeActivePointerGrabRequest::try_parse_request(header, remaining)?)), xproto::GRAB_KEYBOARD_REQUEST => return Ok(Request::GrabKeyboard(xproto::GrabKeyboardRequest::try_parse_request(header, remaining)?)), xproto::UNGRAB_KEYBOARD_REQUEST => return Ok(Request::UngrabKeyboard(xproto::UngrabKeyboardRequest::try_parse_request(header, remaining)?)), xproto::GRAB_KEY_REQUEST => return Ok(Request::GrabKey(xproto::GrabKeyRequest::try_parse_request(header, remaining)?)), xproto::UNGRAB_KEY_REQUEST => return Ok(Request::UngrabKey(xproto::UngrabKeyRequest::try_parse_request(header, remaining)?)), xproto::ALLOW_EVENTS_REQUEST => return Ok(Request::AllowEvents(xproto::AllowEventsRequest::try_parse_request(header, remaining)?)), xproto::GRAB_SERVER_REQUEST => return Ok(Request::GrabServer(xproto::GrabServerRequest::try_parse_request(header, remaining)?)), xproto::UNGRAB_SERVER_REQUEST => return Ok(Request::UngrabServer(xproto::UngrabServerRequest::try_parse_request(header, remaining)?)), xproto::QUERY_POINTER_REQUEST => return Ok(Request::QueryPointer(xproto::QueryPointerRequest::try_parse_request(header, remaining)?)), xproto::GET_MOTION_EVENTS_REQUEST => return Ok(Request::GetMotionEvents(xproto::GetMotionEventsRequest::try_parse_request(header, remaining)?)), xproto::TRANSLATE_COORDINATES_REQUEST => return Ok(Request::TranslateCoordinates(xproto::TranslateCoordinatesRequest::try_parse_request(header, remaining)?)), xproto::WARP_POINTER_REQUEST => return Ok(Request::WarpPointer(xproto::WarpPointerRequest::try_parse_request(header, remaining)?)), xproto::SET_INPUT_FOCUS_REQUEST => return Ok(Request::SetInputFocus(xproto::SetInputFocusRequest::try_parse_request(header, remaining)?)), xproto::GET_INPUT_FOCUS_REQUEST => return Ok(Request::GetInputFocus(xproto::GetInputFocusRequest::try_parse_request(header, remaining)?)), xproto::QUERY_KEYMAP_REQUEST => return Ok(Request::QueryKeymap(xproto::QueryKeymapRequest::try_parse_request(header, remaining)?)), xproto::OPEN_FONT_REQUEST => return Ok(Request::OpenFont(xproto::OpenFontRequest::try_parse_request(header, remaining)?)), xproto::CLOSE_FONT_REQUEST => return Ok(Request::CloseFont(xproto::CloseFontRequest::try_parse_request(header, remaining)?)), xproto::QUERY_FONT_REQUEST => return Ok(Request::QueryFont(xproto::QueryFontRequest::try_parse_request(header, remaining)?)), xproto::QUERY_TEXT_EXTENTS_REQUEST => return Ok(Request::QueryTextExtents(xproto::QueryTextExtentsRequest::try_parse_request(header, remaining)?)), xproto::LIST_FONTS_REQUEST => return Ok(Request::ListFonts(xproto::ListFontsRequest::try_parse_request(header, remaining)?)), xproto::LIST_FONTS_WITH_INFO_REQUEST => return Ok(Request::ListFontsWithInfo(xproto::ListFontsWithInfoRequest::try_parse_request(header, remaining)?)), xproto::SET_FONT_PATH_REQUEST => return Ok(Request::SetFontPath(xproto::SetFontPathRequest::try_parse_request(header, remaining)?)), xproto::GET_FONT_PATH_REQUEST => return Ok(Request::GetFontPath(xproto::GetFontPathRequest::try_parse_request(header, remaining)?)), xproto::CREATE_PIXMAP_REQUEST => return Ok(Request::CreatePixmap(xproto::CreatePixmapRequest::try_parse_request(header, remaining)?)), xproto::FREE_PIXMAP_REQUEST => return Ok(Request::FreePixmap(xproto::FreePixmapRequest::try_parse_request(header, remaining)?)), xproto::CREATE_GC_REQUEST => return Ok(Request::CreateGC(xproto::CreateGCRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_GC_REQUEST => return Ok(Request::ChangeGC(xproto::ChangeGCRequest::try_parse_request(header, remaining)?)), xproto::COPY_GC_REQUEST => return Ok(Request::CopyGC(xproto::CopyGCRequest::try_parse_request(header, remaining)?)), xproto::SET_DASHES_REQUEST => return Ok(Request::SetDashes(xproto::SetDashesRequest::try_parse_request(header, remaining)?)), xproto::SET_CLIP_RECTANGLES_REQUEST => return Ok(Request::SetClipRectangles(xproto::SetClipRectanglesRequest::try_parse_request(header, remaining)?)), xproto::FREE_GC_REQUEST => return Ok(Request::FreeGC(xproto::FreeGCRequest::try_parse_request(header, remaining)?)), xproto::CLEAR_AREA_REQUEST => return Ok(Request::ClearArea(xproto::ClearAreaRequest::try_parse_request(header, remaining)?)), xproto::COPY_AREA_REQUEST => return Ok(Request::CopyArea(xproto::CopyAreaRequest::try_parse_request(header, remaining)?)), xproto::COPY_PLANE_REQUEST => return Ok(Request::CopyPlane(xproto::CopyPlaneRequest::try_parse_request(header, remaining)?)), xproto::POLY_POINT_REQUEST => return Ok(Request::PolyPoint(xproto::PolyPointRequest::try_parse_request(header, remaining)?)), xproto::POLY_LINE_REQUEST => return Ok(Request::PolyLine(xproto::PolyLineRequest::try_parse_request(header, remaining)?)), xproto::POLY_SEGMENT_REQUEST => return Ok(Request::PolySegment(xproto::PolySegmentRequest::try_parse_request(header, remaining)?)), xproto::POLY_RECTANGLE_REQUEST => return Ok(Request::PolyRectangle(xproto::PolyRectangleRequest::try_parse_request(header, remaining)?)), xproto::POLY_ARC_REQUEST => return Ok(Request::PolyArc(xproto::PolyArcRequest::try_parse_request(header, remaining)?)), xproto::FILL_POLY_REQUEST => return Ok(Request::FillPoly(xproto::FillPolyRequest::try_parse_request(header, remaining)?)), xproto::POLY_FILL_RECTANGLE_REQUEST => return Ok(Request::PolyFillRectangle(xproto::PolyFillRectangleRequest::try_parse_request(header, remaining)?)), xproto::POLY_FILL_ARC_REQUEST => return Ok(Request::PolyFillArc(xproto::PolyFillArcRequest::try_parse_request(header, remaining)?)), xproto::PUT_IMAGE_REQUEST => return Ok(Request::PutImage(xproto::PutImageRequest::try_parse_request(header, remaining)?)), xproto::GET_IMAGE_REQUEST => return Ok(Request::GetImage(xproto::GetImageRequest::try_parse_request(header, remaining)?)), xproto::POLY_TEXT8_REQUEST => return Ok(Request::PolyText8(xproto::PolyText8Request::try_parse_request(header, remaining)?)), xproto::POLY_TEXT16_REQUEST => return Ok(Request::PolyText16(xproto::PolyText16Request::try_parse_request(header, remaining)?)), xproto::IMAGE_TEXT8_REQUEST => return Ok(Request::ImageText8(xproto::ImageText8Request::try_parse_request(header, remaining)?)), xproto::IMAGE_TEXT16_REQUEST => return Ok(Request::ImageText16(xproto::ImageText16Request::try_parse_request(header, remaining)?)), xproto::CREATE_COLORMAP_REQUEST => return Ok(Request::CreateColormap(xproto::CreateColormapRequest::try_parse_request(header, remaining)?)), xproto::FREE_COLORMAP_REQUEST => return Ok(Request::FreeColormap(xproto::FreeColormapRequest::try_parse_request(header, remaining)?)), xproto::COPY_COLORMAP_AND_FREE_REQUEST => return Ok(Request::CopyColormapAndFree(xproto::CopyColormapAndFreeRequest::try_parse_request(header, remaining)?)), xproto::INSTALL_COLORMAP_REQUEST => return Ok(Request::InstallColormap(xproto::InstallColormapRequest::try_parse_request(header, remaining)?)), xproto::UNINSTALL_COLORMAP_REQUEST => return Ok(Request::UninstallColormap(xproto::UninstallColormapRequest::try_parse_request(header, remaining)?)), xproto::LIST_INSTALLED_COLORMAPS_REQUEST => return Ok(Request::ListInstalledColormaps(xproto::ListInstalledColormapsRequest::try_parse_request(header, remaining)?)), xproto::ALLOC_COLOR_REQUEST => return Ok(Request::AllocColor(xproto::AllocColorRequest::try_parse_request(header, remaining)?)), xproto::ALLOC_NAMED_COLOR_REQUEST => return Ok(Request::AllocNamedColor(xproto::AllocNamedColorRequest::try_parse_request(header, remaining)?)), xproto::ALLOC_COLOR_CELLS_REQUEST => return Ok(Request::AllocColorCells(xproto::AllocColorCellsRequest::try_parse_request(header, remaining)?)), xproto::ALLOC_COLOR_PLANES_REQUEST => return Ok(Request::AllocColorPlanes(xproto::AllocColorPlanesRequest::try_parse_request(header, remaining)?)), xproto::FREE_COLORS_REQUEST => return Ok(Request::FreeColors(xproto::FreeColorsRequest::try_parse_request(header, remaining)?)), xproto::STORE_COLORS_REQUEST => return Ok(Request::StoreColors(xproto::StoreColorsRequest::try_parse_request(header, remaining)?)), xproto::STORE_NAMED_COLOR_REQUEST => return Ok(Request::StoreNamedColor(xproto::StoreNamedColorRequest::try_parse_request(header, remaining)?)), xproto::QUERY_COLORS_REQUEST => return Ok(Request::QueryColors(xproto::QueryColorsRequest::try_parse_request(header, remaining)?)), xproto::LOOKUP_COLOR_REQUEST => return Ok(Request::LookupColor(xproto::LookupColorRequest::try_parse_request(header, remaining)?)), xproto::CREATE_CURSOR_REQUEST => return Ok(Request::CreateCursor(xproto::CreateCursorRequest::try_parse_request(header, remaining)?)), xproto::CREATE_GLYPH_CURSOR_REQUEST => return Ok(Request::CreateGlyphCursor(xproto::CreateGlyphCursorRequest::try_parse_request(header, remaining)?)), xproto::FREE_CURSOR_REQUEST => return Ok(Request::FreeCursor(xproto::FreeCursorRequest::try_parse_request(header, remaining)?)), xproto::RECOLOR_CURSOR_REQUEST => return Ok(Request::RecolorCursor(xproto::RecolorCursorRequest::try_parse_request(header, remaining)?)), xproto::QUERY_BEST_SIZE_REQUEST => return Ok(Request::QueryBestSize(xproto::QueryBestSizeRequest::try_parse_request(header, remaining)?)), xproto::QUERY_EXTENSION_REQUEST => return Ok(Request::QueryExtension(xproto::QueryExtensionRequest::try_parse_request(header, remaining)?)), xproto::LIST_EXTENSIONS_REQUEST => return Ok(Request::ListExtensions(xproto::ListExtensionsRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_KEYBOARD_MAPPING_REQUEST => return Ok(Request::ChangeKeyboardMapping(xproto::ChangeKeyboardMappingRequest::try_parse_request(header, remaining)?)), xproto::GET_KEYBOARD_MAPPING_REQUEST => return Ok(Request::GetKeyboardMapping(xproto::GetKeyboardMappingRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_KEYBOARD_CONTROL_REQUEST => return Ok(Request::ChangeKeyboardControl(xproto::ChangeKeyboardControlRequest::try_parse_request(header, remaining)?)), xproto::GET_KEYBOARD_CONTROL_REQUEST => return Ok(Request::GetKeyboardControl(xproto::GetKeyboardControlRequest::try_parse_request(header, remaining)?)), xproto::BELL_REQUEST => return Ok(Request::Bell(xproto::BellRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_POINTER_CONTROL_REQUEST => return Ok(Request::ChangePointerControl(xproto::ChangePointerControlRequest::try_parse_request(header, remaining)?)), xproto::GET_POINTER_CONTROL_REQUEST => return Ok(Request::GetPointerControl(xproto::GetPointerControlRequest::try_parse_request(header, remaining)?)), xproto::SET_SCREEN_SAVER_REQUEST => return Ok(Request::SetScreenSaver(xproto::SetScreenSaverRequest::try_parse_request(header, remaining)?)), xproto::GET_SCREEN_SAVER_REQUEST => return Ok(Request::GetScreenSaver(xproto::GetScreenSaverRequest::try_parse_request(header, remaining)?)), xproto::CHANGE_HOSTS_REQUEST => return Ok(Request::ChangeHosts(xproto::ChangeHostsRequest::try_parse_request(header, remaining)?)), xproto::LIST_HOSTS_REQUEST => return Ok(Request::ListHosts(xproto::ListHostsRequest::try_parse_request(header, remaining)?)), xproto::SET_ACCESS_CONTROL_REQUEST => return Ok(Request::SetAccessControl(xproto::SetAccessControlRequest::try_parse_request(header, remaining)?)), xproto::SET_CLOSE_DOWN_MODE_REQUEST => return Ok(Request::SetCloseDownMode(xproto::SetCloseDownModeRequest::try_parse_request(header, remaining)?)), xproto::KILL_CLIENT_REQUEST => return Ok(Request::KillClient(xproto::KillClientRequest::try_parse_request(header, remaining)?)), xproto::ROTATE_PROPERTIES_REQUEST => return Ok(Request::RotateProperties(xproto::RotatePropertiesRequest::try_parse_request(header, remaining)?)), xproto::FORCE_SCREEN_SAVER_REQUEST => return Ok(Request::ForceScreenSaver(xproto::ForceScreenSaverRequest::try_parse_request(header, remaining)?)), xproto::SET_POINTER_MAPPING_REQUEST => return Ok(Request::SetPointerMapping(xproto::SetPointerMappingRequest::try_parse_request(header, remaining)?)), xproto::GET_POINTER_MAPPING_REQUEST => return Ok(Request::GetPointerMapping(xproto::GetPointerMappingRequest::try_parse_request(header, remaining)?)), xproto::SET_MODIFIER_MAPPING_REQUEST => return Ok(Request::SetModifierMapping(xproto::SetModifierMappingRequest::try_parse_request(header, remaining)?)), xproto::GET_MODIFIER_MAPPING_REQUEST => return Ok(Request::GetModifierMapping(xproto::GetModifierMappingRequest::try_parse_request(header, remaining)?)), xproto::NO_OPERATION_REQUEST => return Ok(Request::NoOperation(xproto::NoOperationRequest::try_parse_request(header, remaining)?)), _ => (), } // Find the extension that this request could belong to let ext_info = ext_info_provider.get_from_major_opcode(header.major_opcode); match ext_info { Some((bigreq::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { bigreq::ENABLE_REQUEST => return Ok(Request::BigreqEnable(bigreq::EnableRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "composite")] Some((composite::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { composite::QUERY_VERSION_REQUEST => return Ok(Request::CompositeQueryVersion(composite::QueryVersionRequest::try_parse_request(header, remaining)?)), composite::REDIRECT_WINDOW_REQUEST => return Ok(Request::CompositeRedirectWindow(composite::RedirectWindowRequest::try_parse_request(header, remaining)?)), composite::REDIRECT_SUBWINDOWS_REQUEST => return Ok(Request::CompositeRedirectSubwindows(composite::RedirectSubwindowsRequest::try_parse_request(header, remaining)?)), composite::UNREDIRECT_WINDOW_REQUEST => return Ok(Request::CompositeUnredirectWindow(composite::UnredirectWindowRequest::try_parse_request(header, remaining)?)), composite::UNREDIRECT_SUBWINDOWS_REQUEST => return Ok(Request::CompositeUnredirectSubwindows(composite::UnredirectSubwindowsRequest::try_parse_request(header, remaining)?)), composite::CREATE_REGION_FROM_BORDER_CLIP_REQUEST => return Ok(Request::CompositeCreateRegionFromBorderClip(composite::CreateRegionFromBorderClipRequest::try_parse_request(header, remaining)?)), composite::NAME_WINDOW_PIXMAP_REQUEST => return Ok(Request::CompositeNameWindowPixmap(composite::NameWindowPixmapRequest::try_parse_request(header, remaining)?)), composite::GET_OVERLAY_WINDOW_REQUEST => return Ok(Request::CompositeGetOverlayWindow(composite::GetOverlayWindowRequest::try_parse_request(header, remaining)?)), composite::RELEASE_OVERLAY_WINDOW_REQUEST => return Ok(Request::CompositeReleaseOverlayWindow(composite::ReleaseOverlayWindowRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "damage")] Some((damage::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { damage::QUERY_VERSION_REQUEST => return Ok(Request::DamageQueryVersion(damage::QueryVersionRequest::try_parse_request(header, remaining)?)), damage::CREATE_REQUEST => return Ok(Request::DamageCreate(damage::CreateRequest::try_parse_request(header, remaining)?)), damage::DESTROY_REQUEST => return Ok(Request::DamageDestroy(damage::DestroyRequest::try_parse_request(header, remaining)?)), damage::SUBTRACT_REQUEST => return Ok(Request::DamageSubtract(damage::SubtractRequest::try_parse_request(header, remaining)?)), damage::ADD_REQUEST => return Ok(Request::DamageAdd(damage::AddRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "dpms")] Some((dpms::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { dpms::GET_VERSION_REQUEST => return Ok(Request::DpmsGetVersion(dpms::GetVersionRequest::try_parse_request(header, remaining)?)), dpms::CAPABLE_REQUEST => return Ok(Request::DpmsCapable(dpms::CapableRequest::try_parse_request(header, remaining)?)), dpms::GET_TIMEOUTS_REQUEST => return Ok(Request::DpmsGetTimeouts(dpms::GetTimeoutsRequest::try_parse_request(header, remaining)?)), dpms::SET_TIMEOUTS_REQUEST => return Ok(Request::DpmsSetTimeouts(dpms::SetTimeoutsRequest::try_parse_request(header, remaining)?)), dpms::ENABLE_REQUEST => return Ok(Request::DpmsEnable(dpms::EnableRequest::try_parse_request(header, remaining)?)), dpms::DISABLE_REQUEST => return Ok(Request::DpmsDisable(dpms::DisableRequest::try_parse_request(header, remaining)?)), dpms::FORCE_LEVEL_REQUEST => return Ok(Request::DpmsForceLevel(dpms::ForceLevelRequest::try_parse_request(header, remaining)?)), dpms::INFO_REQUEST => return Ok(Request::DpmsInfo(dpms::InfoRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "dri2")] Some((dri2::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { dri2::QUERY_VERSION_REQUEST => return Ok(Request::Dri2QueryVersion(dri2::QueryVersionRequest::try_parse_request(header, remaining)?)), dri2::CONNECT_REQUEST => return Ok(Request::Dri2Connect(dri2::ConnectRequest::try_parse_request(header, remaining)?)), dri2::AUTHENTICATE_REQUEST => return Ok(Request::Dri2Authenticate(dri2::AuthenticateRequest::try_parse_request(header, remaining)?)), dri2::CREATE_DRAWABLE_REQUEST => return Ok(Request::Dri2CreateDrawable(dri2::CreateDrawableRequest::try_parse_request(header, remaining)?)), dri2::DESTROY_DRAWABLE_REQUEST => return Ok(Request::Dri2DestroyDrawable(dri2::DestroyDrawableRequest::try_parse_request(header, remaining)?)), dri2::GET_BUFFERS_REQUEST => return Ok(Request::Dri2GetBuffers(dri2::GetBuffersRequest::try_parse_request(header, remaining)?)), dri2::COPY_REGION_REQUEST => return Ok(Request::Dri2CopyRegion(dri2::CopyRegionRequest::try_parse_request(header, remaining)?)), dri2::GET_BUFFERS_WITH_FORMAT_REQUEST => return Ok(Request::Dri2GetBuffersWithFormat(dri2::GetBuffersWithFormatRequest::try_parse_request(header, remaining)?)), dri2::SWAP_BUFFERS_REQUEST => return Ok(Request::Dri2SwapBuffers(dri2::SwapBuffersRequest::try_parse_request(header, remaining)?)), dri2::GET_MSC_REQUEST => return Ok(Request::Dri2GetMSC(dri2::GetMSCRequest::try_parse_request(header, remaining)?)), dri2::WAIT_MSC_REQUEST => return Ok(Request::Dri2WaitMSC(dri2::WaitMSCRequest::try_parse_request(header, remaining)?)), dri2::WAIT_SBC_REQUEST => return Ok(Request::Dri2WaitSBC(dri2::WaitSBCRequest::try_parse_request(header, remaining)?)), dri2::SWAP_INTERVAL_REQUEST => return Ok(Request::Dri2SwapInterval(dri2::SwapIntervalRequest::try_parse_request(header, remaining)?)), dri2::GET_PARAM_REQUEST => return Ok(Request::Dri2GetParam(dri2::GetParamRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "dri3")] Some((dri3::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { dri3::QUERY_VERSION_REQUEST => return Ok(Request::Dri3QueryVersion(dri3::QueryVersionRequest::try_parse_request(header, remaining)?)), dri3::OPEN_REQUEST => return Ok(Request::Dri3Open(dri3::OpenRequest::try_parse_request(header, remaining)?)), dri3::PIXMAP_FROM_BUFFER_REQUEST => return Ok(Request::Dri3PixmapFromBuffer(dri3::PixmapFromBufferRequest::try_parse_request_fd(header, remaining, fds)?)), dri3::BUFFER_FROM_PIXMAP_REQUEST => return Ok(Request::Dri3BufferFromPixmap(dri3::BufferFromPixmapRequest::try_parse_request(header, remaining)?)), dri3::FENCE_FROM_FD_REQUEST => return Ok(Request::Dri3FenceFromFD(dri3::FenceFromFDRequest::try_parse_request_fd(header, remaining, fds)?)), dri3::FD_FROM_FENCE_REQUEST => return Ok(Request::Dri3FDFromFence(dri3::FDFromFenceRequest::try_parse_request(header, remaining)?)), dri3::GET_SUPPORTED_MODIFIERS_REQUEST => return Ok(Request::Dri3GetSupportedModifiers(dri3::GetSupportedModifiersRequest::try_parse_request(header, remaining)?)), dri3::PIXMAP_FROM_BUFFERS_REQUEST => return Ok(Request::Dri3PixmapFromBuffers(dri3::PixmapFromBuffersRequest::try_parse_request_fd(header, remaining, fds)?)), dri3::BUFFERS_FROM_PIXMAP_REQUEST => return Ok(Request::Dri3BuffersFromPixmap(dri3::BuffersFromPixmapRequest::try_parse_request(header, remaining)?)), _ => (), } } Some((ge::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { ge::QUERY_VERSION_REQUEST => return Ok(Request::GeQueryVersion(ge::QueryVersionRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "glx")] Some((glx::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { glx::RENDER_REQUEST => return Ok(Request::GlxRender(glx::RenderRequest::try_parse_request(header, remaining)?)), glx::RENDER_LARGE_REQUEST => return Ok(Request::GlxRenderLarge(glx::RenderLargeRequest::try_parse_request(header, remaining)?)), glx::CREATE_CONTEXT_REQUEST => return Ok(Request::GlxCreateContext(glx::CreateContextRequest::try_parse_request(header, remaining)?)), glx::DESTROY_CONTEXT_REQUEST => return Ok(Request::GlxDestroyContext(glx::DestroyContextRequest::try_parse_request(header, remaining)?)), glx::MAKE_CURRENT_REQUEST => return Ok(Request::GlxMakeCurrent(glx::MakeCurrentRequest::try_parse_request(header, remaining)?)), glx::IS_DIRECT_REQUEST => return Ok(Request::GlxIsDirect(glx::IsDirectRequest::try_parse_request(header, remaining)?)), glx::QUERY_VERSION_REQUEST => return Ok(Request::GlxQueryVersion(glx::QueryVersionRequest::try_parse_request(header, remaining)?)), glx::WAIT_GL_REQUEST => return Ok(Request::GlxWaitGL(glx::WaitGLRequest::try_parse_request(header, remaining)?)), glx::WAIT_X_REQUEST => return Ok(Request::GlxWaitX(glx::WaitXRequest::try_parse_request(header, remaining)?)), glx::COPY_CONTEXT_REQUEST => return Ok(Request::GlxCopyContext(glx::CopyContextRequest::try_parse_request(header, remaining)?)), glx::SWAP_BUFFERS_REQUEST => return Ok(Request::GlxSwapBuffers(glx::SwapBuffersRequest::try_parse_request(header, remaining)?)), glx::USE_X_FONT_REQUEST => return Ok(Request::GlxUseXFont(glx::UseXFontRequest::try_parse_request(header, remaining)?)), glx::CREATE_GLX_PIXMAP_REQUEST => return Ok(Request::GlxCreateGLXPixmap(glx::CreateGLXPixmapRequest::try_parse_request(header, remaining)?)), glx::GET_VISUAL_CONFIGS_REQUEST => return Ok(Request::GlxGetVisualConfigs(glx::GetVisualConfigsRequest::try_parse_request(header, remaining)?)), glx::DESTROY_GLX_PIXMAP_REQUEST => return Ok(Request::GlxDestroyGLXPixmap(glx::DestroyGLXPixmapRequest::try_parse_request(header, remaining)?)), glx::VENDOR_PRIVATE_REQUEST => return Ok(Request::GlxVendorPrivate(glx::VendorPrivateRequest::try_parse_request(header, remaining)?)), glx::VENDOR_PRIVATE_WITH_REPLY_REQUEST => return Ok(Request::GlxVendorPrivateWithReply(glx::VendorPrivateWithReplyRequest::try_parse_request(header, remaining)?)), glx::QUERY_EXTENSIONS_STRING_REQUEST => return Ok(Request::GlxQueryExtensionsString(glx::QueryExtensionsStringRequest::try_parse_request(header, remaining)?)), glx::QUERY_SERVER_STRING_REQUEST => return Ok(Request::GlxQueryServerString(glx::QueryServerStringRequest::try_parse_request(header, remaining)?)), glx::CLIENT_INFO_REQUEST => return Ok(Request::GlxClientInfo(glx::ClientInfoRequest::try_parse_request(header, remaining)?)), glx::GET_FB_CONFIGS_REQUEST => return Ok(Request::GlxGetFBConfigs(glx::GetFBConfigsRequest::try_parse_request(header, remaining)?)), glx::CREATE_PIXMAP_REQUEST => return Ok(Request::GlxCreatePixmap(glx::CreatePixmapRequest::try_parse_request(header, remaining)?)), glx::DESTROY_PIXMAP_REQUEST => return Ok(Request::GlxDestroyPixmap(glx::DestroyPixmapRequest::try_parse_request(header, remaining)?)), glx::CREATE_NEW_CONTEXT_REQUEST => return Ok(Request::GlxCreateNewContext(glx::CreateNewContextRequest::try_parse_request(header, remaining)?)), glx::QUERY_CONTEXT_REQUEST => return Ok(Request::GlxQueryContext(glx::QueryContextRequest::try_parse_request(header, remaining)?)), glx::MAKE_CONTEXT_CURRENT_REQUEST => return Ok(Request::GlxMakeContextCurrent(glx::MakeContextCurrentRequest::try_parse_request(header, remaining)?)), glx::CREATE_PBUFFER_REQUEST => return Ok(Request::GlxCreatePbuffer(glx::CreatePbufferRequest::try_parse_request(header, remaining)?)), glx::DESTROY_PBUFFER_REQUEST => return Ok(Request::GlxDestroyPbuffer(glx::DestroyPbufferRequest::try_parse_request(header, remaining)?)), glx::GET_DRAWABLE_ATTRIBUTES_REQUEST => return Ok(Request::GlxGetDrawableAttributes(glx::GetDrawableAttributesRequest::try_parse_request(header, remaining)?)), glx::CHANGE_DRAWABLE_ATTRIBUTES_REQUEST => return Ok(Request::GlxChangeDrawableAttributes(glx::ChangeDrawableAttributesRequest::try_parse_request(header, remaining)?)), glx::CREATE_WINDOW_REQUEST => return Ok(Request::GlxCreateWindow(glx::CreateWindowRequest::try_parse_request(header, remaining)?)), glx::DELETE_WINDOW_REQUEST => return Ok(Request::GlxDeleteWindow(glx::DeleteWindowRequest::try_parse_request(header, remaining)?)), glx::SET_CLIENT_INFO_ARB_REQUEST => return Ok(Request::GlxSetClientInfoARB(glx::SetClientInfoARBRequest::try_parse_request(header, remaining)?)), glx::CREATE_CONTEXT_ATTRIBS_ARB_REQUEST => return Ok(Request::GlxCreateContextAttribsARB(glx::CreateContextAttribsARBRequest::try_parse_request(header, remaining)?)), glx::SET_CLIENT_INFO2_ARB_REQUEST => return Ok(Request::GlxSetClientInfo2ARB(glx::SetClientInfo2ARBRequest::try_parse_request(header, remaining)?)), glx::NEW_LIST_REQUEST => return Ok(Request::GlxNewList(glx::NewListRequest::try_parse_request(header, remaining)?)), glx::END_LIST_REQUEST => return Ok(Request::GlxEndList(glx::EndListRequest::try_parse_request(header, remaining)?)), glx::DELETE_LISTS_REQUEST => return Ok(Request::GlxDeleteLists(glx::DeleteListsRequest::try_parse_request(header, remaining)?)), glx::GEN_LISTS_REQUEST => return Ok(Request::GlxGenLists(glx::GenListsRequest::try_parse_request(header, remaining)?)), glx::FEEDBACK_BUFFER_REQUEST => return Ok(Request::GlxFeedbackBuffer(glx::FeedbackBufferRequest::try_parse_request(header, remaining)?)), glx::SELECT_BUFFER_REQUEST => return Ok(Request::GlxSelectBuffer(glx::SelectBufferRequest::try_parse_request(header, remaining)?)), glx::RENDER_MODE_REQUEST => return Ok(Request::GlxRenderMode(glx::RenderModeRequest::try_parse_request(header, remaining)?)), glx::FINISH_REQUEST => return Ok(Request::GlxFinish(glx::FinishRequest::try_parse_request(header, remaining)?)), glx::PIXEL_STOREF_REQUEST => return Ok(Request::GlxPixelStoref(glx::PixelStorefRequest::try_parse_request(header, remaining)?)), glx::PIXEL_STOREI_REQUEST => return Ok(Request::GlxPixelStorei(glx::PixelStoreiRequest::try_parse_request(header, remaining)?)), glx::READ_PIXELS_REQUEST => return Ok(Request::GlxReadPixels(glx::ReadPixelsRequest::try_parse_request(header, remaining)?)), glx::GET_BOOLEANV_REQUEST => return Ok(Request::GlxGetBooleanv(glx::GetBooleanvRequest::try_parse_request(header, remaining)?)), glx::GET_CLIP_PLANE_REQUEST => return Ok(Request::GlxGetClipPlane(glx::GetClipPlaneRequest::try_parse_request(header, remaining)?)), glx::GET_DOUBLEV_REQUEST => return Ok(Request::GlxGetDoublev(glx::GetDoublevRequest::try_parse_request(header, remaining)?)), glx::GET_ERROR_REQUEST => return Ok(Request::GlxGetError(glx::GetErrorRequest::try_parse_request(header, remaining)?)), glx::GET_FLOATV_REQUEST => return Ok(Request::GlxGetFloatv(glx::GetFloatvRequest::try_parse_request(header, remaining)?)), glx::GET_INTEGERV_REQUEST => return Ok(Request::GlxGetIntegerv(glx::GetIntegervRequest::try_parse_request(header, remaining)?)), glx::GET_LIGHTFV_REQUEST => return Ok(Request::GlxGetLightfv(glx::GetLightfvRequest::try_parse_request(header, remaining)?)), glx::GET_LIGHTIV_REQUEST => return Ok(Request::GlxGetLightiv(glx::GetLightivRequest::try_parse_request(header, remaining)?)), glx::GET_MAPDV_REQUEST => return Ok(Request::GlxGetMapdv(glx::GetMapdvRequest::try_parse_request(header, remaining)?)), glx::GET_MAPFV_REQUEST => return Ok(Request::GlxGetMapfv(glx::GetMapfvRequest::try_parse_request(header, remaining)?)), glx::GET_MAPIV_REQUEST => return Ok(Request::GlxGetMapiv(glx::GetMapivRequest::try_parse_request(header, remaining)?)), glx::GET_MATERIALFV_REQUEST => return Ok(Request::GlxGetMaterialfv(glx::GetMaterialfvRequest::try_parse_request(header, remaining)?)), glx::GET_MATERIALIV_REQUEST => return Ok(Request::GlxGetMaterialiv(glx::GetMaterialivRequest::try_parse_request(header, remaining)?)), glx::GET_PIXEL_MAPFV_REQUEST => return Ok(Request::GlxGetPixelMapfv(glx::GetPixelMapfvRequest::try_parse_request(header, remaining)?)), glx::GET_PIXEL_MAPUIV_REQUEST => return Ok(Request::GlxGetPixelMapuiv(glx::GetPixelMapuivRequest::try_parse_request(header, remaining)?)), glx::GET_PIXEL_MAPUSV_REQUEST => return Ok(Request::GlxGetPixelMapusv(glx::GetPixelMapusvRequest::try_parse_request(header, remaining)?)), glx::GET_POLYGON_STIPPLE_REQUEST => return Ok(Request::GlxGetPolygonStipple(glx::GetPolygonStippleRequest::try_parse_request(header, remaining)?)), glx::GET_STRING_REQUEST => return Ok(Request::GlxGetString(glx::GetStringRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_ENVFV_REQUEST => return Ok(Request::GlxGetTexEnvfv(glx::GetTexEnvfvRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_ENVIV_REQUEST => return Ok(Request::GlxGetTexEnviv(glx::GetTexEnvivRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_GENDV_REQUEST => return Ok(Request::GlxGetTexGendv(glx::GetTexGendvRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_GENFV_REQUEST => return Ok(Request::GlxGetTexGenfv(glx::GetTexGenfvRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_GENIV_REQUEST => return Ok(Request::GlxGetTexGeniv(glx::GetTexGenivRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_IMAGE_REQUEST => return Ok(Request::GlxGetTexImage(glx::GetTexImageRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_PARAMETERFV_REQUEST => return Ok(Request::GlxGetTexParameterfv(glx::GetTexParameterfvRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_PARAMETERIV_REQUEST => return Ok(Request::GlxGetTexParameteriv(glx::GetTexParameterivRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_LEVEL_PARAMETERFV_REQUEST => return Ok(Request::GlxGetTexLevelParameterfv(glx::GetTexLevelParameterfvRequest::try_parse_request(header, remaining)?)), glx::GET_TEX_LEVEL_PARAMETERIV_REQUEST => return Ok(Request::GlxGetTexLevelParameteriv(glx::GetTexLevelParameterivRequest::try_parse_request(header, remaining)?)), glx::IS_ENABLED_REQUEST => return Ok(Request::GlxIsEnabled(glx::IsEnabledRequest::try_parse_request(header, remaining)?)), glx::IS_LIST_REQUEST => return Ok(Request::GlxIsList(glx::IsListRequest::try_parse_request(header, remaining)?)), glx::FLUSH_REQUEST => return Ok(Request::GlxFlush(glx::FlushRequest::try_parse_request(header, remaining)?)), glx::ARE_TEXTURES_RESIDENT_REQUEST => return Ok(Request::GlxAreTexturesResident(glx::AreTexturesResidentRequest::try_parse_request(header, remaining)?)), glx::DELETE_TEXTURES_REQUEST => return Ok(Request::GlxDeleteTextures(glx::DeleteTexturesRequest::try_parse_request(header, remaining)?)), glx::GEN_TEXTURES_REQUEST => return Ok(Request::GlxGenTextures(glx::GenTexturesRequest::try_parse_request(header, remaining)?)), glx::IS_TEXTURE_REQUEST => return Ok(Request::GlxIsTexture(glx::IsTextureRequest::try_parse_request(header, remaining)?)), glx::GET_COLOR_TABLE_REQUEST => return Ok(Request::GlxGetColorTable(glx::GetColorTableRequest::try_parse_request(header, remaining)?)), glx::GET_COLOR_TABLE_PARAMETERFV_REQUEST => return Ok(Request::GlxGetColorTableParameterfv(glx::GetColorTableParameterfvRequest::try_parse_request(header, remaining)?)), glx::GET_COLOR_TABLE_PARAMETERIV_REQUEST => return Ok(Request::GlxGetColorTableParameteriv(glx::GetColorTableParameterivRequest::try_parse_request(header, remaining)?)), glx::GET_CONVOLUTION_FILTER_REQUEST => return Ok(Request::GlxGetConvolutionFilter(glx::GetConvolutionFilterRequest::try_parse_request(header, remaining)?)), glx::GET_CONVOLUTION_PARAMETERFV_REQUEST => return Ok(Request::GlxGetConvolutionParameterfv(glx::GetConvolutionParameterfvRequest::try_parse_request(header, remaining)?)), glx::GET_CONVOLUTION_PARAMETERIV_REQUEST => return Ok(Request::GlxGetConvolutionParameteriv(glx::GetConvolutionParameterivRequest::try_parse_request(header, remaining)?)), glx::GET_SEPARABLE_FILTER_REQUEST => return Ok(Request::GlxGetSeparableFilter(glx::GetSeparableFilterRequest::try_parse_request(header, remaining)?)), glx::GET_HISTOGRAM_REQUEST => return Ok(Request::GlxGetHistogram(glx::GetHistogramRequest::try_parse_request(header, remaining)?)), glx::GET_HISTOGRAM_PARAMETERFV_REQUEST => return Ok(Request::GlxGetHistogramParameterfv(glx::GetHistogramParameterfvRequest::try_parse_request(header, remaining)?)), glx::GET_HISTOGRAM_PARAMETERIV_REQUEST => return Ok(Request::GlxGetHistogramParameteriv(glx::GetHistogramParameterivRequest::try_parse_request(header, remaining)?)), glx::GET_MINMAX_REQUEST => return Ok(Request::GlxGetMinmax(glx::GetMinmaxRequest::try_parse_request(header, remaining)?)), glx::GET_MINMAX_PARAMETERFV_REQUEST => return Ok(Request::GlxGetMinmaxParameterfv(glx::GetMinmaxParameterfvRequest::try_parse_request(header, remaining)?)), glx::GET_MINMAX_PARAMETERIV_REQUEST => return Ok(Request::GlxGetMinmaxParameteriv(glx::GetMinmaxParameterivRequest::try_parse_request(header, remaining)?)), glx::GET_COMPRESSED_TEX_IMAGE_ARB_REQUEST => return Ok(Request::GlxGetCompressedTexImageARB(glx::GetCompressedTexImageARBRequest::try_parse_request(header, remaining)?)), glx::DELETE_QUERIES_ARB_REQUEST => return Ok(Request::GlxDeleteQueriesARB(glx::DeleteQueriesARBRequest::try_parse_request(header, remaining)?)), glx::GEN_QUERIES_ARB_REQUEST => return Ok(Request::GlxGenQueriesARB(glx::GenQueriesARBRequest::try_parse_request(header, remaining)?)), glx::IS_QUERY_ARB_REQUEST => return Ok(Request::GlxIsQueryARB(glx::IsQueryARBRequest::try_parse_request(header, remaining)?)), glx::GET_QUERYIV_ARB_REQUEST => return Ok(Request::GlxGetQueryivARB(glx::GetQueryivARBRequest::try_parse_request(header, remaining)?)), glx::GET_QUERY_OBJECTIV_ARB_REQUEST => return Ok(Request::GlxGetQueryObjectivARB(glx::GetQueryObjectivARBRequest::try_parse_request(header, remaining)?)), glx::GET_QUERY_OBJECTUIV_ARB_REQUEST => return Ok(Request::GlxGetQueryObjectuivARB(glx::GetQueryObjectuivARBRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "present")] Some((present::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { present::QUERY_VERSION_REQUEST => return Ok(Request::PresentQueryVersion(present::QueryVersionRequest::try_parse_request(header, remaining)?)), present::PIXMAP_REQUEST => return Ok(Request::PresentPixmap(present::PixmapRequest::try_parse_request(header, remaining)?)), present::NOTIFY_MSC_REQUEST => return Ok(Request::PresentNotifyMSC(present::NotifyMSCRequest::try_parse_request(header, remaining)?)), present::SELECT_INPUT_REQUEST => return Ok(Request::PresentSelectInput(present::SelectInputRequest::try_parse_request(header, remaining)?)), present::QUERY_CAPABILITIES_REQUEST => return Ok(Request::PresentQueryCapabilities(present::QueryCapabilitiesRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "randr")] Some((randr::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { randr::QUERY_VERSION_REQUEST => return Ok(Request::RandrQueryVersion(randr::QueryVersionRequest::try_parse_request(header, remaining)?)), randr::SET_SCREEN_CONFIG_REQUEST => return Ok(Request::RandrSetScreenConfig(randr::SetScreenConfigRequest::try_parse_request(header, remaining)?)), randr::SELECT_INPUT_REQUEST => return Ok(Request::RandrSelectInput(randr::SelectInputRequest::try_parse_request(header, remaining)?)), randr::GET_SCREEN_INFO_REQUEST => return Ok(Request::RandrGetScreenInfo(randr::GetScreenInfoRequest::try_parse_request(header, remaining)?)), randr::GET_SCREEN_SIZE_RANGE_REQUEST => return Ok(Request::RandrGetScreenSizeRange(randr::GetScreenSizeRangeRequest::try_parse_request(header, remaining)?)), randr::SET_SCREEN_SIZE_REQUEST => return Ok(Request::RandrSetScreenSize(randr::SetScreenSizeRequest::try_parse_request(header, remaining)?)), randr::GET_SCREEN_RESOURCES_REQUEST => return Ok(Request::RandrGetScreenResources(randr::GetScreenResourcesRequest::try_parse_request(header, remaining)?)), randr::GET_OUTPUT_INFO_REQUEST => return Ok(Request::RandrGetOutputInfo(randr::GetOutputInfoRequest::try_parse_request(header, remaining)?)), randr::LIST_OUTPUT_PROPERTIES_REQUEST => return Ok(Request::RandrListOutputProperties(randr::ListOutputPropertiesRequest::try_parse_request(header, remaining)?)), randr::QUERY_OUTPUT_PROPERTY_REQUEST => return Ok(Request::RandrQueryOutputProperty(randr::QueryOutputPropertyRequest::try_parse_request(header, remaining)?)), randr::CONFIGURE_OUTPUT_PROPERTY_REQUEST => return Ok(Request::RandrConfigureOutputProperty(randr::ConfigureOutputPropertyRequest::try_parse_request(header, remaining)?)), randr::CHANGE_OUTPUT_PROPERTY_REQUEST => return Ok(Request::RandrChangeOutputProperty(randr::ChangeOutputPropertyRequest::try_parse_request(header, remaining)?)), randr::DELETE_OUTPUT_PROPERTY_REQUEST => return Ok(Request::RandrDeleteOutputProperty(randr::DeleteOutputPropertyRequest::try_parse_request(header, remaining)?)), randr::GET_OUTPUT_PROPERTY_REQUEST => return Ok(Request::RandrGetOutputProperty(randr::GetOutputPropertyRequest::try_parse_request(header, remaining)?)), randr::CREATE_MODE_REQUEST => return Ok(Request::RandrCreateMode(randr::CreateModeRequest::try_parse_request(header, remaining)?)), randr::DESTROY_MODE_REQUEST => return Ok(Request::RandrDestroyMode(randr::DestroyModeRequest::try_parse_request(header, remaining)?)), randr::ADD_OUTPUT_MODE_REQUEST => return Ok(Request::RandrAddOutputMode(randr::AddOutputModeRequest::try_parse_request(header, remaining)?)), randr::DELETE_OUTPUT_MODE_REQUEST => return Ok(Request::RandrDeleteOutputMode(randr::DeleteOutputModeRequest::try_parse_request(header, remaining)?)), randr::GET_CRTC_INFO_REQUEST => return Ok(Request::RandrGetCrtcInfo(randr::GetCrtcInfoRequest::try_parse_request(header, remaining)?)), randr::SET_CRTC_CONFIG_REQUEST => return Ok(Request::RandrSetCrtcConfig(randr::SetCrtcConfigRequest::try_parse_request(header, remaining)?)), randr::GET_CRTC_GAMMA_SIZE_REQUEST => return Ok(Request::RandrGetCrtcGammaSize(randr::GetCrtcGammaSizeRequest::try_parse_request(header, remaining)?)), randr::GET_CRTC_GAMMA_REQUEST => return Ok(Request::RandrGetCrtcGamma(randr::GetCrtcGammaRequest::try_parse_request(header, remaining)?)), randr::SET_CRTC_GAMMA_REQUEST => return Ok(Request::RandrSetCrtcGamma(randr::SetCrtcGammaRequest::try_parse_request(header, remaining)?)), randr::GET_SCREEN_RESOURCES_CURRENT_REQUEST => return Ok(Request::RandrGetScreenResourcesCurrent(randr::GetScreenResourcesCurrentRequest::try_parse_request(header, remaining)?)), randr::SET_CRTC_TRANSFORM_REQUEST => return Ok(Request::RandrSetCrtcTransform(randr::SetCrtcTransformRequest::try_parse_request(header, remaining)?)), randr::GET_CRTC_TRANSFORM_REQUEST => return Ok(Request::RandrGetCrtcTransform(randr::GetCrtcTransformRequest::try_parse_request(header, remaining)?)), randr::GET_PANNING_REQUEST => return Ok(Request::RandrGetPanning(randr::GetPanningRequest::try_parse_request(header, remaining)?)), randr::SET_PANNING_REQUEST => return Ok(Request::RandrSetPanning(randr::SetPanningRequest::try_parse_request(header, remaining)?)), randr::SET_OUTPUT_PRIMARY_REQUEST => return Ok(Request::RandrSetOutputPrimary(randr::SetOutputPrimaryRequest::try_parse_request(header, remaining)?)), randr::GET_OUTPUT_PRIMARY_REQUEST => return Ok(Request::RandrGetOutputPrimary(randr::GetOutputPrimaryRequest::try_parse_request(header, remaining)?)), randr::GET_PROVIDERS_REQUEST => return Ok(Request::RandrGetProviders(randr::GetProvidersRequest::try_parse_request(header, remaining)?)), randr::GET_PROVIDER_INFO_REQUEST => return Ok(Request::RandrGetProviderInfo(randr::GetProviderInfoRequest::try_parse_request(header, remaining)?)), randr::SET_PROVIDER_OFFLOAD_SINK_REQUEST => return Ok(Request::RandrSetProviderOffloadSink(randr::SetProviderOffloadSinkRequest::try_parse_request(header, remaining)?)), randr::SET_PROVIDER_OUTPUT_SOURCE_REQUEST => return Ok(Request::RandrSetProviderOutputSource(randr::SetProviderOutputSourceRequest::try_parse_request(header, remaining)?)), randr::LIST_PROVIDER_PROPERTIES_REQUEST => return Ok(Request::RandrListProviderProperties(randr::ListProviderPropertiesRequest::try_parse_request(header, remaining)?)), randr::QUERY_PROVIDER_PROPERTY_REQUEST => return Ok(Request::RandrQueryProviderProperty(randr::QueryProviderPropertyRequest::try_parse_request(header, remaining)?)), randr::CONFIGURE_PROVIDER_PROPERTY_REQUEST => return Ok(Request::RandrConfigureProviderProperty(randr::ConfigureProviderPropertyRequest::try_parse_request(header, remaining)?)), randr::CHANGE_PROVIDER_PROPERTY_REQUEST => return Ok(Request::RandrChangeProviderProperty(randr::ChangeProviderPropertyRequest::try_parse_request(header, remaining)?)), randr::DELETE_PROVIDER_PROPERTY_REQUEST => return Ok(Request::RandrDeleteProviderProperty(randr::DeleteProviderPropertyRequest::try_parse_request(header, remaining)?)), randr::GET_PROVIDER_PROPERTY_REQUEST => return Ok(Request::RandrGetProviderProperty(randr::GetProviderPropertyRequest::try_parse_request(header, remaining)?)), randr::GET_MONITORS_REQUEST => return Ok(Request::RandrGetMonitors(randr::GetMonitorsRequest::try_parse_request(header, remaining)?)), randr::SET_MONITOR_REQUEST => return Ok(Request::RandrSetMonitor(randr::SetMonitorRequest::try_parse_request(header, remaining)?)), randr::DELETE_MONITOR_REQUEST => return Ok(Request::RandrDeleteMonitor(randr::DeleteMonitorRequest::try_parse_request(header, remaining)?)), randr::CREATE_LEASE_REQUEST => return Ok(Request::RandrCreateLease(randr::CreateLeaseRequest::try_parse_request(header, remaining)?)), randr::FREE_LEASE_REQUEST => return Ok(Request::RandrFreeLease(randr::FreeLeaseRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "record")] Some((record::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { record::QUERY_VERSION_REQUEST => return Ok(Request::RecordQueryVersion(record::QueryVersionRequest::try_parse_request(header, remaining)?)), record::CREATE_CONTEXT_REQUEST => return Ok(Request::RecordCreateContext(record::CreateContextRequest::try_parse_request(header, remaining)?)), record::REGISTER_CLIENTS_REQUEST => return Ok(Request::RecordRegisterClients(record::RegisterClientsRequest::try_parse_request(header, remaining)?)), record::UNREGISTER_CLIENTS_REQUEST => return Ok(Request::RecordUnregisterClients(record::UnregisterClientsRequest::try_parse_request(header, remaining)?)), record::GET_CONTEXT_REQUEST => return Ok(Request::RecordGetContext(record::GetContextRequest::try_parse_request(header, remaining)?)), record::ENABLE_CONTEXT_REQUEST => return Ok(Request::RecordEnableContext(record::EnableContextRequest::try_parse_request(header, remaining)?)), record::DISABLE_CONTEXT_REQUEST => return Ok(Request::RecordDisableContext(record::DisableContextRequest::try_parse_request(header, remaining)?)), record::FREE_CONTEXT_REQUEST => return Ok(Request::RecordFreeContext(record::FreeContextRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "render")] Some((render::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { render::QUERY_VERSION_REQUEST => return Ok(Request::RenderQueryVersion(render::QueryVersionRequest::try_parse_request(header, remaining)?)), render::QUERY_PICT_FORMATS_REQUEST => return Ok(Request::RenderQueryPictFormats(render::QueryPictFormatsRequest::try_parse_request(header, remaining)?)), render::QUERY_PICT_INDEX_VALUES_REQUEST => return Ok(Request::RenderQueryPictIndexValues(render::QueryPictIndexValuesRequest::try_parse_request(header, remaining)?)), render::CREATE_PICTURE_REQUEST => return Ok(Request::RenderCreatePicture(render::CreatePictureRequest::try_parse_request(header, remaining)?)), render::CHANGE_PICTURE_REQUEST => return Ok(Request::RenderChangePicture(render::ChangePictureRequest::try_parse_request(header, remaining)?)), render::SET_PICTURE_CLIP_RECTANGLES_REQUEST => return Ok(Request::RenderSetPictureClipRectangles(render::SetPictureClipRectanglesRequest::try_parse_request(header, remaining)?)), render::FREE_PICTURE_REQUEST => return Ok(Request::RenderFreePicture(render::FreePictureRequest::try_parse_request(header, remaining)?)), render::COMPOSITE_REQUEST => return Ok(Request::RenderComposite(render::CompositeRequest::try_parse_request(header, remaining)?)), render::TRAPEZOIDS_REQUEST => return Ok(Request::RenderTrapezoids(render::TrapezoidsRequest::try_parse_request(header, remaining)?)), render::TRIANGLES_REQUEST => return Ok(Request::RenderTriangles(render::TrianglesRequest::try_parse_request(header, remaining)?)), render::TRI_STRIP_REQUEST => return Ok(Request::RenderTriStrip(render::TriStripRequest::try_parse_request(header, remaining)?)), render::TRI_FAN_REQUEST => return Ok(Request::RenderTriFan(render::TriFanRequest::try_parse_request(header, remaining)?)), render::CREATE_GLYPH_SET_REQUEST => return Ok(Request::RenderCreateGlyphSet(render::CreateGlyphSetRequest::try_parse_request(header, remaining)?)), render::REFERENCE_GLYPH_SET_REQUEST => return Ok(Request::RenderReferenceGlyphSet(render::ReferenceGlyphSetRequest::try_parse_request(header, remaining)?)), render::FREE_GLYPH_SET_REQUEST => return Ok(Request::RenderFreeGlyphSet(render::FreeGlyphSetRequest::try_parse_request(header, remaining)?)), render::ADD_GLYPHS_REQUEST => return Ok(Request::RenderAddGlyphs(render::AddGlyphsRequest::try_parse_request(header, remaining)?)), render::FREE_GLYPHS_REQUEST => return Ok(Request::RenderFreeGlyphs(render::FreeGlyphsRequest::try_parse_request(header, remaining)?)), render::COMPOSITE_GLYPHS8_REQUEST => return Ok(Request::RenderCompositeGlyphs8(render::CompositeGlyphs8Request::try_parse_request(header, remaining)?)), render::COMPOSITE_GLYPHS16_REQUEST => return Ok(Request::RenderCompositeGlyphs16(render::CompositeGlyphs16Request::try_parse_request(header, remaining)?)), render::COMPOSITE_GLYPHS32_REQUEST => return Ok(Request::RenderCompositeGlyphs32(render::CompositeGlyphs32Request::try_parse_request(header, remaining)?)), render::FILL_RECTANGLES_REQUEST => return Ok(Request::RenderFillRectangles(render::FillRectanglesRequest::try_parse_request(header, remaining)?)), render::CREATE_CURSOR_REQUEST => return Ok(Request::RenderCreateCursor(render::CreateCursorRequest::try_parse_request(header, remaining)?)), render::SET_PICTURE_TRANSFORM_REQUEST => return Ok(Request::RenderSetPictureTransform(render::SetPictureTransformRequest::try_parse_request(header, remaining)?)), render::QUERY_FILTERS_REQUEST => return Ok(Request::RenderQueryFilters(render::QueryFiltersRequest::try_parse_request(header, remaining)?)), render::SET_PICTURE_FILTER_REQUEST => return Ok(Request::RenderSetPictureFilter(render::SetPictureFilterRequest::try_parse_request(header, remaining)?)), render::CREATE_ANIM_CURSOR_REQUEST => return Ok(Request::RenderCreateAnimCursor(render::CreateAnimCursorRequest::try_parse_request(header, remaining)?)), render::ADD_TRAPS_REQUEST => return Ok(Request::RenderAddTraps(render::AddTrapsRequest::try_parse_request(header, remaining)?)), render::CREATE_SOLID_FILL_REQUEST => return Ok(Request::RenderCreateSolidFill(render::CreateSolidFillRequest::try_parse_request(header, remaining)?)), render::CREATE_LINEAR_GRADIENT_REQUEST => return Ok(Request::RenderCreateLinearGradient(render::CreateLinearGradientRequest::try_parse_request(header, remaining)?)), render::CREATE_RADIAL_GRADIENT_REQUEST => return Ok(Request::RenderCreateRadialGradient(render::CreateRadialGradientRequest::try_parse_request(header, remaining)?)), render::CREATE_CONICAL_GRADIENT_REQUEST => return Ok(Request::RenderCreateConicalGradient(render::CreateConicalGradientRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "res")] Some((res::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { res::QUERY_VERSION_REQUEST => return Ok(Request::ResQueryVersion(res::QueryVersionRequest::try_parse_request(header, remaining)?)), res::QUERY_CLIENTS_REQUEST => return Ok(Request::ResQueryClients(res::QueryClientsRequest::try_parse_request(header, remaining)?)), res::QUERY_CLIENT_RESOURCES_REQUEST => return Ok(Request::ResQueryClientResources(res::QueryClientResourcesRequest::try_parse_request(header, remaining)?)), res::QUERY_CLIENT_PIXMAP_BYTES_REQUEST => return Ok(Request::ResQueryClientPixmapBytes(res::QueryClientPixmapBytesRequest::try_parse_request(header, remaining)?)), res::QUERY_CLIENT_IDS_REQUEST => return Ok(Request::ResQueryClientIds(res::QueryClientIdsRequest::try_parse_request(header, remaining)?)), res::QUERY_RESOURCE_BYTES_REQUEST => return Ok(Request::ResQueryResourceBytes(res::QueryResourceBytesRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "screensaver")] Some((screensaver::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { screensaver::QUERY_VERSION_REQUEST => return Ok(Request::ScreensaverQueryVersion(screensaver::QueryVersionRequest::try_parse_request(header, remaining)?)), screensaver::QUERY_INFO_REQUEST => return Ok(Request::ScreensaverQueryInfo(screensaver::QueryInfoRequest::try_parse_request(header, remaining)?)), screensaver::SELECT_INPUT_REQUEST => return Ok(Request::ScreensaverSelectInput(screensaver::SelectInputRequest::try_parse_request(header, remaining)?)), screensaver::SET_ATTRIBUTES_REQUEST => return Ok(Request::ScreensaverSetAttributes(screensaver::SetAttributesRequest::try_parse_request(header, remaining)?)), screensaver::UNSET_ATTRIBUTES_REQUEST => return Ok(Request::ScreensaverUnsetAttributes(screensaver::UnsetAttributesRequest::try_parse_request(header, remaining)?)), screensaver::SUSPEND_REQUEST => return Ok(Request::ScreensaverSuspend(screensaver::SuspendRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "shape")] Some((shape::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { shape::QUERY_VERSION_REQUEST => return Ok(Request::ShapeQueryVersion(shape::QueryVersionRequest::try_parse_request(header, remaining)?)), shape::RECTANGLES_REQUEST => return Ok(Request::ShapeRectangles(shape::RectanglesRequest::try_parse_request(header, remaining)?)), shape::MASK_REQUEST => return Ok(Request::ShapeMask(shape::MaskRequest::try_parse_request(header, remaining)?)), shape::COMBINE_REQUEST => return Ok(Request::ShapeCombine(shape::CombineRequest::try_parse_request(header, remaining)?)), shape::OFFSET_REQUEST => return Ok(Request::ShapeOffset(shape::OffsetRequest::try_parse_request(header, remaining)?)), shape::QUERY_EXTENTS_REQUEST => return Ok(Request::ShapeQueryExtents(shape::QueryExtentsRequest::try_parse_request(header, remaining)?)), shape::SELECT_INPUT_REQUEST => return Ok(Request::ShapeSelectInput(shape::SelectInputRequest::try_parse_request(header, remaining)?)), shape::INPUT_SELECTED_REQUEST => return Ok(Request::ShapeInputSelected(shape::InputSelectedRequest::try_parse_request(header, remaining)?)), shape::GET_RECTANGLES_REQUEST => return Ok(Request::ShapeGetRectangles(shape::GetRectanglesRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "shm")] Some((shm::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { shm::QUERY_VERSION_REQUEST => return Ok(Request::ShmQueryVersion(shm::QueryVersionRequest::try_parse_request(header, remaining)?)), shm::ATTACH_REQUEST => return Ok(Request::ShmAttach(shm::AttachRequest::try_parse_request(header, remaining)?)), shm::DETACH_REQUEST => return Ok(Request::ShmDetach(shm::DetachRequest::try_parse_request(header, remaining)?)), shm::PUT_IMAGE_REQUEST => return Ok(Request::ShmPutImage(shm::PutImageRequest::try_parse_request(header, remaining)?)), shm::GET_IMAGE_REQUEST => return Ok(Request::ShmGetImage(shm::GetImageRequest::try_parse_request(header, remaining)?)), shm::CREATE_PIXMAP_REQUEST => return Ok(Request::ShmCreatePixmap(shm::CreatePixmapRequest::try_parse_request(header, remaining)?)), shm::ATTACH_FD_REQUEST => return Ok(Request::ShmAttachFd(shm::AttachFdRequest::try_parse_request_fd(header, remaining, fds)?)), shm::CREATE_SEGMENT_REQUEST => return Ok(Request::ShmCreateSegment(shm::CreateSegmentRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "sync")] Some((sync::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { sync::INITIALIZE_REQUEST => return Ok(Request::SyncInitialize(sync::InitializeRequest::try_parse_request(header, remaining)?)), sync::LIST_SYSTEM_COUNTERS_REQUEST => return Ok(Request::SyncListSystemCounters(sync::ListSystemCountersRequest::try_parse_request(header, remaining)?)), sync::CREATE_COUNTER_REQUEST => return Ok(Request::SyncCreateCounter(sync::CreateCounterRequest::try_parse_request(header, remaining)?)), sync::DESTROY_COUNTER_REQUEST => return Ok(Request::SyncDestroyCounter(sync::DestroyCounterRequest::try_parse_request(header, remaining)?)), sync::QUERY_COUNTER_REQUEST => return Ok(Request::SyncQueryCounter(sync::QueryCounterRequest::try_parse_request(header, remaining)?)), sync::AWAIT_REQUEST => return Ok(Request::SyncAwait(sync::AwaitRequest::try_parse_request(header, remaining)?)), sync::CHANGE_COUNTER_REQUEST => return Ok(Request::SyncChangeCounter(sync::ChangeCounterRequest::try_parse_request(header, remaining)?)), sync::SET_COUNTER_REQUEST => return Ok(Request::SyncSetCounter(sync::SetCounterRequest::try_parse_request(header, remaining)?)), sync::CREATE_ALARM_REQUEST => return Ok(Request::SyncCreateAlarm(sync::CreateAlarmRequest::try_parse_request(header, remaining)?)), sync::CHANGE_ALARM_REQUEST => return Ok(Request::SyncChangeAlarm(sync::ChangeAlarmRequest::try_parse_request(header, remaining)?)), sync::DESTROY_ALARM_REQUEST => return Ok(Request::SyncDestroyAlarm(sync::DestroyAlarmRequest::try_parse_request(header, remaining)?)), sync::QUERY_ALARM_REQUEST => return Ok(Request::SyncQueryAlarm(sync::QueryAlarmRequest::try_parse_request(header, remaining)?)), sync::SET_PRIORITY_REQUEST => return Ok(Request::SyncSetPriority(sync::SetPriorityRequest::try_parse_request(header, remaining)?)), sync::GET_PRIORITY_REQUEST => return Ok(Request::SyncGetPriority(sync::GetPriorityRequest::try_parse_request(header, remaining)?)), sync::CREATE_FENCE_REQUEST => return Ok(Request::SyncCreateFence(sync::CreateFenceRequest::try_parse_request(header, remaining)?)), sync::TRIGGER_FENCE_REQUEST => return Ok(Request::SyncTriggerFence(sync::TriggerFenceRequest::try_parse_request(header, remaining)?)), sync::RESET_FENCE_REQUEST => return Ok(Request::SyncResetFence(sync::ResetFenceRequest::try_parse_request(header, remaining)?)), sync::DESTROY_FENCE_REQUEST => return Ok(Request::SyncDestroyFence(sync::DestroyFenceRequest::try_parse_request(header, remaining)?)), sync::QUERY_FENCE_REQUEST => return Ok(Request::SyncQueryFence(sync::QueryFenceRequest::try_parse_request(header, remaining)?)), sync::AWAIT_FENCE_REQUEST => return Ok(Request::SyncAwaitFence(sync::AwaitFenceRequest::try_parse_request(header, remaining)?)), _ => (), } } Some((xc_misc::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xc_misc::GET_VERSION_REQUEST => return Ok(Request::XcMiscGetVersion(xc_misc::GetVersionRequest::try_parse_request(header, remaining)?)), xc_misc::GET_XID_RANGE_REQUEST => return Ok(Request::XcMiscGetXIDRange(xc_misc::GetXIDRangeRequest::try_parse_request(header, remaining)?)), xc_misc::GET_XID_LIST_REQUEST => return Ok(Request::XcMiscGetXIDList(xc_misc::GetXIDListRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xevie")] Some((xevie::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xevie::QUERY_VERSION_REQUEST => return Ok(Request::XevieQueryVersion(xevie::QueryVersionRequest::try_parse_request(header, remaining)?)), xevie::START_REQUEST => return Ok(Request::XevieStart(xevie::StartRequest::try_parse_request(header, remaining)?)), xevie::END_REQUEST => return Ok(Request::XevieEnd(xevie::EndRequest::try_parse_request(header, remaining)?)), xevie::SEND_REQUEST => return Ok(Request::XevieSend(xevie::SendRequest::try_parse_request(header, remaining)?)), xevie::SELECT_INPUT_REQUEST => return Ok(Request::XevieSelectInput(xevie::SelectInputRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xf86dri")] Some((xf86dri::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xf86dri::QUERY_VERSION_REQUEST => return Ok(Request::Xf86driQueryVersion(xf86dri::QueryVersionRequest::try_parse_request(header, remaining)?)), xf86dri::QUERY_DIRECT_RENDERING_CAPABLE_REQUEST => return Ok(Request::Xf86driQueryDirectRenderingCapable(xf86dri::QueryDirectRenderingCapableRequest::try_parse_request(header, remaining)?)), xf86dri::OPEN_CONNECTION_REQUEST => return Ok(Request::Xf86driOpenConnection(xf86dri::OpenConnectionRequest::try_parse_request(header, remaining)?)), xf86dri::CLOSE_CONNECTION_REQUEST => return Ok(Request::Xf86driCloseConnection(xf86dri::CloseConnectionRequest::try_parse_request(header, remaining)?)), xf86dri::GET_CLIENT_DRIVER_NAME_REQUEST => return Ok(Request::Xf86driGetClientDriverName(xf86dri::GetClientDriverNameRequest::try_parse_request(header, remaining)?)), xf86dri::CREATE_CONTEXT_REQUEST => return Ok(Request::Xf86driCreateContext(xf86dri::CreateContextRequest::try_parse_request(header, remaining)?)), xf86dri::DESTROY_CONTEXT_REQUEST => return Ok(Request::Xf86driDestroyContext(xf86dri::DestroyContextRequest::try_parse_request(header, remaining)?)), xf86dri::CREATE_DRAWABLE_REQUEST => return Ok(Request::Xf86driCreateDrawable(xf86dri::CreateDrawableRequest::try_parse_request(header, remaining)?)), xf86dri::DESTROY_DRAWABLE_REQUEST => return Ok(Request::Xf86driDestroyDrawable(xf86dri::DestroyDrawableRequest::try_parse_request(header, remaining)?)), xf86dri::GET_DRAWABLE_INFO_REQUEST => return Ok(Request::Xf86driGetDrawableInfo(xf86dri::GetDrawableInfoRequest::try_parse_request(header, remaining)?)), xf86dri::GET_DEVICE_INFO_REQUEST => return Ok(Request::Xf86driGetDeviceInfo(xf86dri::GetDeviceInfoRequest::try_parse_request(header, remaining)?)), xf86dri::AUTH_CONNECTION_REQUEST => return Ok(Request::Xf86driAuthConnection(xf86dri::AuthConnectionRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xf86vidmode")] Some((xf86vidmode::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xf86vidmode::QUERY_VERSION_REQUEST => return Ok(Request::Xf86vidmodeQueryVersion(xf86vidmode::QueryVersionRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_MODE_LINE_REQUEST => return Ok(Request::Xf86vidmodeGetModeLine(xf86vidmode::GetModeLineRequest::try_parse_request(header, remaining)?)), xf86vidmode::MOD_MODE_LINE_REQUEST => return Ok(Request::Xf86vidmodeModModeLine(xf86vidmode::ModModeLineRequest::try_parse_request(header, remaining)?)), xf86vidmode::SWITCH_MODE_REQUEST => return Ok(Request::Xf86vidmodeSwitchMode(xf86vidmode::SwitchModeRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_MONITOR_REQUEST => return Ok(Request::Xf86vidmodeGetMonitor(xf86vidmode::GetMonitorRequest::try_parse_request(header, remaining)?)), xf86vidmode::LOCK_MODE_SWITCH_REQUEST => return Ok(Request::Xf86vidmodeLockModeSwitch(xf86vidmode::LockModeSwitchRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_ALL_MODE_LINES_REQUEST => return Ok(Request::Xf86vidmodeGetAllModeLines(xf86vidmode::GetAllModeLinesRequest::try_parse_request(header, remaining)?)), xf86vidmode::ADD_MODE_LINE_REQUEST => return Ok(Request::Xf86vidmodeAddModeLine(xf86vidmode::AddModeLineRequest::try_parse_request(header, remaining)?)), xf86vidmode::DELETE_MODE_LINE_REQUEST => return Ok(Request::Xf86vidmodeDeleteModeLine(xf86vidmode::DeleteModeLineRequest::try_parse_request(header, remaining)?)), xf86vidmode::VALIDATE_MODE_LINE_REQUEST => return Ok(Request::Xf86vidmodeValidateModeLine(xf86vidmode::ValidateModeLineRequest::try_parse_request(header, remaining)?)), xf86vidmode::SWITCH_TO_MODE_REQUEST => return Ok(Request::Xf86vidmodeSwitchToMode(xf86vidmode::SwitchToModeRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_VIEW_PORT_REQUEST => return Ok(Request::Xf86vidmodeGetViewPort(xf86vidmode::GetViewPortRequest::try_parse_request(header, remaining)?)), xf86vidmode::SET_VIEW_PORT_REQUEST => return Ok(Request::Xf86vidmodeSetViewPort(xf86vidmode::SetViewPortRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_DOT_CLOCKS_REQUEST => return Ok(Request::Xf86vidmodeGetDotClocks(xf86vidmode::GetDotClocksRequest::try_parse_request(header, remaining)?)), xf86vidmode::SET_CLIENT_VERSION_REQUEST => return Ok(Request::Xf86vidmodeSetClientVersion(xf86vidmode::SetClientVersionRequest::try_parse_request(header, remaining)?)), xf86vidmode::SET_GAMMA_REQUEST => return Ok(Request::Xf86vidmodeSetGamma(xf86vidmode::SetGammaRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_GAMMA_REQUEST => return Ok(Request::Xf86vidmodeGetGamma(xf86vidmode::GetGammaRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_GAMMA_RAMP_REQUEST => return Ok(Request::Xf86vidmodeGetGammaRamp(xf86vidmode::GetGammaRampRequest::try_parse_request(header, remaining)?)), xf86vidmode::SET_GAMMA_RAMP_REQUEST => return Ok(Request::Xf86vidmodeSetGammaRamp(xf86vidmode::SetGammaRampRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_GAMMA_RAMP_SIZE_REQUEST => return Ok(Request::Xf86vidmodeGetGammaRampSize(xf86vidmode::GetGammaRampSizeRequest::try_parse_request(header, remaining)?)), xf86vidmode::GET_PERMISSIONS_REQUEST => return Ok(Request::Xf86vidmodeGetPermissions(xf86vidmode::GetPermissionsRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xfixes")] Some((xfixes::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xfixes::QUERY_VERSION_REQUEST => return Ok(Request::XfixesQueryVersion(xfixes::QueryVersionRequest::try_parse_request(header, remaining)?)), xfixes::CHANGE_SAVE_SET_REQUEST => return Ok(Request::XfixesChangeSaveSet(xfixes::ChangeSaveSetRequest::try_parse_request(header, remaining)?)), xfixes::SELECT_SELECTION_INPUT_REQUEST => return Ok(Request::XfixesSelectSelectionInput(xfixes::SelectSelectionInputRequest::try_parse_request(header, remaining)?)), xfixes::SELECT_CURSOR_INPUT_REQUEST => return Ok(Request::XfixesSelectCursorInput(xfixes::SelectCursorInputRequest::try_parse_request(header, remaining)?)), xfixes::GET_CURSOR_IMAGE_REQUEST => return Ok(Request::XfixesGetCursorImage(xfixes::GetCursorImageRequest::try_parse_request(header, remaining)?)), xfixes::CREATE_REGION_REQUEST => return Ok(Request::XfixesCreateRegion(xfixes::CreateRegionRequest::try_parse_request(header, remaining)?)), xfixes::CREATE_REGION_FROM_BITMAP_REQUEST => return Ok(Request::XfixesCreateRegionFromBitmap(xfixes::CreateRegionFromBitmapRequest::try_parse_request(header, remaining)?)), xfixes::CREATE_REGION_FROM_WINDOW_REQUEST => return Ok(Request::XfixesCreateRegionFromWindow(xfixes::CreateRegionFromWindowRequest::try_parse_request(header, remaining)?)), xfixes::CREATE_REGION_FROM_GC_REQUEST => return Ok(Request::XfixesCreateRegionFromGC(xfixes::CreateRegionFromGCRequest::try_parse_request(header, remaining)?)), xfixes::CREATE_REGION_FROM_PICTURE_REQUEST => return Ok(Request::XfixesCreateRegionFromPicture(xfixes::CreateRegionFromPictureRequest::try_parse_request(header, remaining)?)), xfixes::DESTROY_REGION_REQUEST => return Ok(Request::XfixesDestroyRegion(xfixes::DestroyRegionRequest::try_parse_request(header, remaining)?)), xfixes::SET_REGION_REQUEST => return Ok(Request::XfixesSetRegion(xfixes::SetRegionRequest::try_parse_request(header, remaining)?)), xfixes::COPY_REGION_REQUEST => return Ok(Request::XfixesCopyRegion(xfixes::CopyRegionRequest::try_parse_request(header, remaining)?)), xfixes::UNION_REGION_REQUEST => return Ok(Request::XfixesUnionRegion(xfixes::UnionRegionRequest::try_parse_request(header, remaining)?)), xfixes::INTERSECT_REGION_REQUEST => return Ok(Request::XfixesIntersectRegion(xfixes::IntersectRegionRequest::try_parse_request(header, remaining)?)), xfixes::SUBTRACT_REGION_REQUEST => return Ok(Request::XfixesSubtractRegion(xfixes::SubtractRegionRequest::try_parse_request(header, remaining)?)), xfixes::INVERT_REGION_REQUEST => return Ok(Request::XfixesInvertRegion(xfixes::InvertRegionRequest::try_parse_request(header, remaining)?)), xfixes::TRANSLATE_REGION_REQUEST => return Ok(Request::XfixesTranslateRegion(xfixes::TranslateRegionRequest::try_parse_request(header, remaining)?)), xfixes::REGION_EXTENTS_REQUEST => return Ok(Request::XfixesRegionExtents(xfixes::RegionExtentsRequest::try_parse_request(header, remaining)?)), xfixes::FETCH_REGION_REQUEST => return Ok(Request::XfixesFetchRegion(xfixes::FetchRegionRequest::try_parse_request(header, remaining)?)), xfixes::SET_GC_CLIP_REGION_REQUEST => return Ok(Request::XfixesSetGCClipRegion(xfixes::SetGCClipRegionRequest::try_parse_request(header, remaining)?)), xfixes::SET_WINDOW_SHAPE_REGION_REQUEST => return Ok(Request::XfixesSetWindowShapeRegion(xfixes::SetWindowShapeRegionRequest::try_parse_request(header, remaining)?)), xfixes::SET_PICTURE_CLIP_REGION_REQUEST => return Ok(Request::XfixesSetPictureClipRegion(xfixes::SetPictureClipRegionRequest::try_parse_request(header, remaining)?)), xfixes::SET_CURSOR_NAME_REQUEST => return Ok(Request::XfixesSetCursorName(xfixes::SetCursorNameRequest::try_parse_request(header, remaining)?)), xfixes::GET_CURSOR_NAME_REQUEST => return Ok(Request::XfixesGetCursorName(xfixes::GetCursorNameRequest::try_parse_request(header, remaining)?)), xfixes::GET_CURSOR_IMAGE_AND_NAME_REQUEST => return Ok(Request::XfixesGetCursorImageAndName(xfixes::GetCursorImageAndNameRequest::try_parse_request(header, remaining)?)), xfixes::CHANGE_CURSOR_REQUEST => return Ok(Request::XfixesChangeCursor(xfixes::ChangeCursorRequest::try_parse_request(header, remaining)?)), xfixes::CHANGE_CURSOR_BY_NAME_REQUEST => return Ok(Request::XfixesChangeCursorByName(xfixes::ChangeCursorByNameRequest::try_parse_request(header, remaining)?)), xfixes::EXPAND_REGION_REQUEST => return Ok(Request::XfixesExpandRegion(xfixes::ExpandRegionRequest::try_parse_request(header, remaining)?)), xfixes::HIDE_CURSOR_REQUEST => return Ok(Request::XfixesHideCursor(xfixes::HideCursorRequest::try_parse_request(header, remaining)?)), xfixes::SHOW_CURSOR_REQUEST => return Ok(Request::XfixesShowCursor(xfixes::ShowCursorRequest::try_parse_request(header, remaining)?)), xfixes::CREATE_POINTER_BARRIER_REQUEST => return Ok(Request::XfixesCreatePointerBarrier(xfixes::CreatePointerBarrierRequest::try_parse_request(header, remaining)?)), xfixes::DELETE_POINTER_BARRIER_REQUEST => return Ok(Request::XfixesDeletePointerBarrier(xfixes::DeletePointerBarrierRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xinerama")] Some((xinerama::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xinerama::QUERY_VERSION_REQUEST => return Ok(Request::XineramaQueryVersion(xinerama::QueryVersionRequest::try_parse_request(header, remaining)?)), xinerama::GET_STATE_REQUEST => return Ok(Request::XineramaGetState(xinerama::GetStateRequest::try_parse_request(header, remaining)?)), xinerama::GET_SCREEN_COUNT_REQUEST => return Ok(Request::XineramaGetScreenCount(xinerama::GetScreenCountRequest::try_parse_request(header, remaining)?)), xinerama::GET_SCREEN_SIZE_REQUEST => return Ok(Request::XineramaGetScreenSize(xinerama::GetScreenSizeRequest::try_parse_request(header, remaining)?)), xinerama::IS_ACTIVE_REQUEST => return Ok(Request::XineramaIsActive(xinerama::IsActiveRequest::try_parse_request(header, remaining)?)), xinerama::QUERY_SCREENS_REQUEST => return Ok(Request::XineramaQueryScreens(xinerama::QueryScreensRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xinput")] Some((xinput::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xinput::GET_EXTENSION_VERSION_REQUEST => return Ok(Request::XinputGetExtensionVersion(xinput::GetExtensionVersionRequest::try_parse_request(header, remaining)?)), xinput::LIST_INPUT_DEVICES_REQUEST => return Ok(Request::XinputListInputDevices(xinput::ListInputDevicesRequest::try_parse_request(header, remaining)?)), xinput::OPEN_DEVICE_REQUEST => return Ok(Request::XinputOpenDevice(xinput::OpenDeviceRequest::try_parse_request(header, remaining)?)), xinput::CLOSE_DEVICE_REQUEST => return Ok(Request::XinputCloseDevice(xinput::CloseDeviceRequest::try_parse_request(header, remaining)?)), xinput::SET_DEVICE_MODE_REQUEST => return Ok(Request::XinputSetDeviceMode(xinput::SetDeviceModeRequest::try_parse_request(header, remaining)?)), xinput::SELECT_EXTENSION_EVENT_REQUEST => return Ok(Request::XinputSelectExtensionEvent(xinput::SelectExtensionEventRequest::try_parse_request(header, remaining)?)), xinput::GET_SELECTED_EXTENSION_EVENTS_REQUEST => return Ok(Request::XinputGetSelectedExtensionEvents(xinput::GetSelectedExtensionEventsRequest::try_parse_request(header, remaining)?)), xinput::CHANGE_DEVICE_DONT_PROPAGATE_LIST_REQUEST => return Ok(Request::XinputChangeDeviceDontPropagateList(xinput::ChangeDeviceDontPropagateListRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_DONT_PROPAGATE_LIST_REQUEST => return Ok(Request::XinputGetDeviceDontPropagateList(xinput::GetDeviceDontPropagateListRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_MOTION_EVENTS_REQUEST => return Ok(Request::XinputGetDeviceMotionEvents(xinput::GetDeviceMotionEventsRequest::try_parse_request(header, remaining)?)), xinput::CHANGE_KEYBOARD_DEVICE_REQUEST => return Ok(Request::XinputChangeKeyboardDevice(xinput::ChangeKeyboardDeviceRequest::try_parse_request(header, remaining)?)), xinput::CHANGE_POINTER_DEVICE_REQUEST => return Ok(Request::XinputChangePointerDevice(xinput::ChangePointerDeviceRequest::try_parse_request(header, remaining)?)), xinput::GRAB_DEVICE_REQUEST => return Ok(Request::XinputGrabDevice(xinput::GrabDeviceRequest::try_parse_request(header, remaining)?)), xinput::UNGRAB_DEVICE_REQUEST => return Ok(Request::XinputUngrabDevice(xinput::UngrabDeviceRequest::try_parse_request(header, remaining)?)), xinput::GRAB_DEVICE_KEY_REQUEST => return Ok(Request::XinputGrabDeviceKey(xinput::GrabDeviceKeyRequest::try_parse_request(header, remaining)?)), xinput::UNGRAB_DEVICE_KEY_REQUEST => return Ok(Request::XinputUngrabDeviceKey(xinput::UngrabDeviceKeyRequest::try_parse_request(header, remaining)?)), xinput::GRAB_DEVICE_BUTTON_REQUEST => return Ok(Request::XinputGrabDeviceButton(xinput::GrabDeviceButtonRequest::try_parse_request(header, remaining)?)), xinput::UNGRAB_DEVICE_BUTTON_REQUEST => return Ok(Request::XinputUngrabDeviceButton(xinput::UngrabDeviceButtonRequest::try_parse_request(header, remaining)?)), xinput::ALLOW_DEVICE_EVENTS_REQUEST => return Ok(Request::XinputAllowDeviceEvents(xinput::AllowDeviceEventsRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_FOCUS_REQUEST => return Ok(Request::XinputGetDeviceFocus(xinput::GetDeviceFocusRequest::try_parse_request(header, remaining)?)), xinput::SET_DEVICE_FOCUS_REQUEST => return Ok(Request::XinputSetDeviceFocus(xinput::SetDeviceFocusRequest::try_parse_request(header, remaining)?)), xinput::GET_FEEDBACK_CONTROL_REQUEST => return Ok(Request::XinputGetFeedbackControl(xinput::GetFeedbackControlRequest::try_parse_request(header, remaining)?)), xinput::CHANGE_FEEDBACK_CONTROL_REQUEST => return Ok(Request::XinputChangeFeedbackControl(xinput::ChangeFeedbackControlRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_KEY_MAPPING_REQUEST => return Ok(Request::XinputGetDeviceKeyMapping(xinput::GetDeviceKeyMappingRequest::try_parse_request(header, remaining)?)), xinput::CHANGE_DEVICE_KEY_MAPPING_REQUEST => return Ok(Request::XinputChangeDeviceKeyMapping(xinput::ChangeDeviceKeyMappingRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_MODIFIER_MAPPING_REQUEST => return Ok(Request::XinputGetDeviceModifierMapping(xinput::GetDeviceModifierMappingRequest::try_parse_request(header, remaining)?)), xinput::SET_DEVICE_MODIFIER_MAPPING_REQUEST => return Ok(Request::XinputSetDeviceModifierMapping(xinput::SetDeviceModifierMappingRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_BUTTON_MAPPING_REQUEST => return Ok(Request::XinputGetDeviceButtonMapping(xinput::GetDeviceButtonMappingRequest::try_parse_request(header, remaining)?)), xinput::SET_DEVICE_BUTTON_MAPPING_REQUEST => return Ok(Request::XinputSetDeviceButtonMapping(xinput::SetDeviceButtonMappingRequest::try_parse_request(header, remaining)?)), xinput::QUERY_DEVICE_STATE_REQUEST => return Ok(Request::XinputQueryDeviceState(xinput::QueryDeviceStateRequest::try_parse_request(header, remaining)?)), xinput::DEVICE_BELL_REQUEST => return Ok(Request::XinputDeviceBell(xinput::DeviceBellRequest::try_parse_request(header, remaining)?)), xinput::SET_DEVICE_VALUATORS_REQUEST => return Ok(Request::XinputSetDeviceValuators(xinput::SetDeviceValuatorsRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_CONTROL_REQUEST => return Ok(Request::XinputGetDeviceControl(xinput::GetDeviceControlRequest::try_parse_request(header, remaining)?)), xinput::CHANGE_DEVICE_CONTROL_REQUEST => return Ok(Request::XinputChangeDeviceControl(xinput::ChangeDeviceControlRequest::try_parse_request(header, remaining)?)), xinput::LIST_DEVICE_PROPERTIES_REQUEST => return Ok(Request::XinputListDeviceProperties(xinput::ListDevicePropertiesRequest::try_parse_request(header, remaining)?)), xinput::CHANGE_DEVICE_PROPERTY_REQUEST => return Ok(Request::XinputChangeDeviceProperty(xinput::ChangeDevicePropertyRequest::try_parse_request(header, remaining)?)), xinput::DELETE_DEVICE_PROPERTY_REQUEST => return Ok(Request::XinputDeleteDeviceProperty(xinput::DeleteDevicePropertyRequest::try_parse_request(header, remaining)?)), xinput::GET_DEVICE_PROPERTY_REQUEST => return Ok(Request::XinputGetDeviceProperty(xinput::GetDevicePropertyRequest::try_parse_request(header, remaining)?)), xinput::XI_QUERY_POINTER_REQUEST => return Ok(Request::XinputXIQueryPointer(xinput::XIQueryPointerRequest::try_parse_request(header, remaining)?)), xinput::XI_WARP_POINTER_REQUEST => return Ok(Request::XinputXIWarpPointer(xinput::XIWarpPointerRequest::try_parse_request(header, remaining)?)), xinput::XI_CHANGE_CURSOR_REQUEST => return Ok(Request::XinputXIChangeCursor(xinput::XIChangeCursorRequest::try_parse_request(header, remaining)?)), xinput::XI_CHANGE_HIERARCHY_REQUEST => return Ok(Request::XinputXIChangeHierarchy(xinput::XIChangeHierarchyRequest::try_parse_request(header, remaining)?)), xinput::XI_SET_CLIENT_POINTER_REQUEST => return Ok(Request::XinputXISetClientPointer(xinput::XISetClientPointerRequest::try_parse_request(header, remaining)?)), xinput::XI_GET_CLIENT_POINTER_REQUEST => return Ok(Request::XinputXIGetClientPointer(xinput::XIGetClientPointerRequest::try_parse_request(header, remaining)?)), xinput::XI_SELECT_EVENTS_REQUEST => return Ok(Request::XinputXISelectEvents(xinput::XISelectEventsRequest::try_parse_request(header, remaining)?)), xinput::XI_QUERY_VERSION_REQUEST => return Ok(Request::XinputXIQueryVersion(xinput::XIQueryVersionRequest::try_parse_request(header, remaining)?)), xinput::XI_QUERY_DEVICE_REQUEST => return Ok(Request::XinputXIQueryDevice(xinput::XIQueryDeviceRequest::try_parse_request(header, remaining)?)), xinput::XI_SET_FOCUS_REQUEST => return Ok(Request::XinputXISetFocus(xinput::XISetFocusRequest::try_parse_request(header, remaining)?)), xinput::XI_GET_FOCUS_REQUEST => return Ok(Request::XinputXIGetFocus(xinput::XIGetFocusRequest::try_parse_request(header, remaining)?)), xinput::XI_GRAB_DEVICE_REQUEST => return Ok(Request::XinputXIGrabDevice(xinput::XIGrabDeviceRequest::try_parse_request(header, remaining)?)), xinput::XI_UNGRAB_DEVICE_REQUEST => return Ok(Request::XinputXIUngrabDevice(xinput::XIUngrabDeviceRequest::try_parse_request(header, remaining)?)), xinput::XI_ALLOW_EVENTS_REQUEST => return Ok(Request::XinputXIAllowEvents(xinput::XIAllowEventsRequest::try_parse_request(header, remaining)?)), xinput::XI_PASSIVE_GRAB_DEVICE_REQUEST => return Ok(Request::XinputXIPassiveGrabDevice(xinput::XIPassiveGrabDeviceRequest::try_parse_request(header, remaining)?)), xinput::XI_PASSIVE_UNGRAB_DEVICE_REQUEST => return Ok(Request::XinputXIPassiveUngrabDevice(xinput::XIPassiveUngrabDeviceRequest::try_parse_request(header, remaining)?)), xinput::XI_LIST_PROPERTIES_REQUEST => return Ok(Request::XinputXIListProperties(xinput::XIListPropertiesRequest::try_parse_request(header, remaining)?)), xinput::XI_CHANGE_PROPERTY_REQUEST => return Ok(Request::XinputXIChangeProperty(xinput::XIChangePropertyRequest::try_parse_request(header, remaining)?)), xinput::XI_DELETE_PROPERTY_REQUEST => return Ok(Request::XinputXIDeleteProperty(xinput::XIDeletePropertyRequest::try_parse_request(header, remaining)?)), xinput::XI_GET_PROPERTY_REQUEST => return Ok(Request::XinputXIGetProperty(xinput::XIGetPropertyRequest::try_parse_request(header, remaining)?)), xinput::XI_GET_SELECTED_EVENTS_REQUEST => return Ok(Request::XinputXIGetSelectedEvents(xinput::XIGetSelectedEventsRequest::try_parse_request(header, remaining)?)), xinput::XI_BARRIER_RELEASE_POINTER_REQUEST => return Ok(Request::XinputXIBarrierReleasePointer(xinput::XIBarrierReleasePointerRequest::try_parse_request(header, remaining)?)), xinput::SEND_EXTENSION_EVENT_REQUEST => return Ok(Request::XinputSendExtensionEvent(xinput::SendExtensionEventRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xkb")] Some((xkb::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xkb::USE_EXTENSION_REQUEST => return Ok(Request::XkbUseExtension(xkb::UseExtensionRequest::try_parse_request(header, remaining)?)), xkb::SELECT_EVENTS_REQUEST => return Ok(Request::XkbSelectEvents(xkb::SelectEventsRequest::try_parse_request(header, remaining)?)), xkb::BELL_REQUEST => return Ok(Request::XkbBell(xkb::BellRequest::try_parse_request(header, remaining)?)), xkb::GET_STATE_REQUEST => return Ok(Request::XkbGetState(xkb::GetStateRequest::try_parse_request(header, remaining)?)), xkb::LATCH_LOCK_STATE_REQUEST => return Ok(Request::XkbLatchLockState(xkb::LatchLockStateRequest::try_parse_request(header, remaining)?)), xkb::GET_CONTROLS_REQUEST => return Ok(Request::XkbGetControls(xkb::GetControlsRequest::try_parse_request(header, remaining)?)), xkb::SET_CONTROLS_REQUEST => return Ok(Request::XkbSetControls(xkb::SetControlsRequest::try_parse_request(header, remaining)?)), xkb::GET_MAP_REQUEST => return Ok(Request::XkbGetMap(xkb::GetMapRequest::try_parse_request(header, remaining)?)), xkb::SET_MAP_REQUEST => return Ok(Request::XkbSetMap(xkb::SetMapRequest::try_parse_request(header, remaining)?)), xkb::GET_COMPAT_MAP_REQUEST => return Ok(Request::XkbGetCompatMap(xkb::GetCompatMapRequest::try_parse_request(header, remaining)?)), xkb::SET_COMPAT_MAP_REQUEST => return Ok(Request::XkbSetCompatMap(xkb::SetCompatMapRequest::try_parse_request(header, remaining)?)), xkb::GET_INDICATOR_STATE_REQUEST => return Ok(Request::XkbGetIndicatorState(xkb::GetIndicatorStateRequest::try_parse_request(header, remaining)?)), xkb::GET_INDICATOR_MAP_REQUEST => return Ok(Request::XkbGetIndicatorMap(xkb::GetIndicatorMapRequest::try_parse_request(header, remaining)?)), xkb::SET_INDICATOR_MAP_REQUEST => return Ok(Request::XkbSetIndicatorMap(xkb::SetIndicatorMapRequest::try_parse_request(header, remaining)?)), xkb::GET_NAMED_INDICATOR_REQUEST => return Ok(Request::XkbGetNamedIndicator(xkb::GetNamedIndicatorRequest::try_parse_request(header, remaining)?)), xkb::SET_NAMED_INDICATOR_REQUEST => return Ok(Request::XkbSetNamedIndicator(xkb::SetNamedIndicatorRequest::try_parse_request(header, remaining)?)), xkb::GET_NAMES_REQUEST => return Ok(Request::XkbGetNames(xkb::GetNamesRequest::try_parse_request(header, remaining)?)), xkb::SET_NAMES_REQUEST => return Ok(Request::XkbSetNames(xkb::SetNamesRequest::try_parse_request(header, remaining)?)), xkb::PER_CLIENT_FLAGS_REQUEST => return Ok(Request::XkbPerClientFlags(xkb::PerClientFlagsRequest::try_parse_request(header, remaining)?)), xkb::LIST_COMPONENTS_REQUEST => return Ok(Request::XkbListComponents(xkb::ListComponentsRequest::try_parse_request(header, remaining)?)), xkb::GET_KBD_BY_NAME_REQUEST => return Ok(Request::XkbGetKbdByName(xkb::GetKbdByNameRequest::try_parse_request(header, remaining)?)), xkb::GET_DEVICE_INFO_REQUEST => return Ok(Request::XkbGetDeviceInfo(xkb::GetDeviceInfoRequest::try_parse_request(header, remaining)?)), xkb::SET_DEVICE_INFO_REQUEST => return Ok(Request::XkbSetDeviceInfo(xkb::SetDeviceInfoRequest::try_parse_request(header, remaining)?)), xkb::SET_DEBUGGING_FLAGS_REQUEST => return Ok(Request::XkbSetDebuggingFlags(xkb::SetDebuggingFlagsRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xprint")] Some((xprint::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xprint::PRINT_QUERY_VERSION_REQUEST => return Ok(Request::XprintPrintQueryVersion(xprint::PrintQueryVersionRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_PRINTER_LIST_REQUEST => return Ok(Request::XprintPrintGetPrinterList(xprint::PrintGetPrinterListRequest::try_parse_request(header, remaining)?)), xprint::PRINT_REHASH_PRINTER_LIST_REQUEST => return Ok(Request::XprintPrintRehashPrinterList(xprint::PrintRehashPrinterListRequest::try_parse_request(header, remaining)?)), xprint::CREATE_CONTEXT_REQUEST => return Ok(Request::XprintCreateContext(xprint::CreateContextRequest::try_parse_request(header, remaining)?)), xprint::PRINT_SET_CONTEXT_REQUEST => return Ok(Request::XprintPrintSetContext(xprint::PrintSetContextRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_CONTEXT_REQUEST => return Ok(Request::XprintPrintGetContext(xprint::PrintGetContextRequest::try_parse_request(header, remaining)?)), xprint::PRINT_DESTROY_CONTEXT_REQUEST => return Ok(Request::XprintPrintDestroyContext(xprint::PrintDestroyContextRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_SCREEN_OF_CONTEXT_REQUEST => return Ok(Request::XprintPrintGetScreenOfContext(xprint::PrintGetScreenOfContextRequest::try_parse_request(header, remaining)?)), xprint::PRINT_START_JOB_REQUEST => return Ok(Request::XprintPrintStartJob(xprint::PrintStartJobRequest::try_parse_request(header, remaining)?)), xprint::PRINT_END_JOB_REQUEST => return Ok(Request::XprintPrintEndJob(xprint::PrintEndJobRequest::try_parse_request(header, remaining)?)), xprint::PRINT_START_DOC_REQUEST => return Ok(Request::XprintPrintStartDoc(xprint::PrintStartDocRequest::try_parse_request(header, remaining)?)), xprint::PRINT_END_DOC_REQUEST => return Ok(Request::XprintPrintEndDoc(xprint::PrintEndDocRequest::try_parse_request(header, remaining)?)), xprint::PRINT_PUT_DOCUMENT_DATA_REQUEST => return Ok(Request::XprintPrintPutDocumentData(xprint::PrintPutDocumentDataRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_DOCUMENT_DATA_REQUEST => return Ok(Request::XprintPrintGetDocumentData(xprint::PrintGetDocumentDataRequest::try_parse_request(header, remaining)?)), xprint::PRINT_START_PAGE_REQUEST => return Ok(Request::XprintPrintStartPage(xprint::PrintStartPageRequest::try_parse_request(header, remaining)?)), xprint::PRINT_END_PAGE_REQUEST => return Ok(Request::XprintPrintEndPage(xprint::PrintEndPageRequest::try_parse_request(header, remaining)?)), xprint::PRINT_SELECT_INPUT_REQUEST => return Ok(Request::XprintPrintSelectInput(xprint::PrintSelectInputRequest::try_parse_request(header, remaining)?)), xprint::PRINT_INPUT_SELECTED_REQUEST => return Ok(Request::XprintPrintInputSelected(xprint::PrintInputSelectedRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_ATTRIBUTES_REQUEST => return Ok(Request::XprintPrintGetAttributes(xprint::PrintGetAttributesRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_ONE_ATTRIBUTES_REQUEST => return Ok(Request::XprintPrintGetOneAttributes(xprint::PrintGetOneAttributesRequest::try_parse_request(header, remaining)?)), xprint::PRINT_SET_ATTRIBUTES_REQUEST => return Ok(Request::XprintPrintSetAttributes(xprint::PrintSetAttributesRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_PAGE_DIMENSIONS_REQUEST => return Ok(Request::XprintPrintGetPageDimensions(xprint::PrintGetPageDimensionsRequest::try_parse_request(header, remaining)?)), xprint::PRINT_QUERY_SCREENS_REQUEST => return Ok(Request::XprintPrintQueryScreens(xprint::PrintQueryScreensRequest::try_parse_request(header, remaining)?)), xprint::PRINT_SET_IMAGE_RESOLUTION_REQUEST => return Ok(Request::XprintPrintSetImageResolution(xprint::PrintSetImageResolutionRequest::try_parse_request(header, remaining)?)), xprint::PRINT_GET_IMAGE_RESOLUTION_REQUEST => return Ok(Request::XprintPrintGetImageResolution(xprint::PrintGetImageResolutionRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xselinux")] Some((xselinux::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xselinux::QUERY_VERSION_REQUEST => return Ok(Request::XselinuxQueryVersion(xselinux::QueryVersionRequest::try_parse_request(header, remaining)?)), xselinux::SET_DEVICE_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxSetDeviceCreateContext(xselinux::SetDeviceCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_DEVICE_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxGetDeviceCreateContext(xselinux::GetDeviceCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::SET_DEVICE_CONTEXT_REQUEST => return Ok(Request::XselinuxSetDeviceContext(xselinux::SetDeviceContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_DEVICE_CONTEXT_REQUEST => return Ok(Request::XselinuxGetDeviceContext(xselinux::GetDeviceContextRequest::try_parse_request(header, remaining)?)), xselinux::SET_WINDOW_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxSetWindowCreateContext(xselinux::SetWindowCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_WINDOW_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxGetWindowCreateContext(xselinux::GetWindowCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_WINDOW_CONTEXT_REQUEST => return Ok(Request::XselinuxGetWindowContext(xselinux::GetWindowContextRequest::try_parse_request(header, remaining)?)), xselinux::SET_PROPERTY_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxSetPropertyCreateContext(xselinux::SetPropertyCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_PROPERTY_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxGetPropertyCreateContext(xselinux::GetPropertyCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::SET_PROPERTY_USE_CONTEXT_REQUEST => return Ok(Request::XselinuxSetPropertyUseContext(xselinux::SetPropertyUseContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_PROPERTY_USE_CONTEXT_REQUEST => return Ok(Request::XselinuxGetPropertyUseContext(xselinux::GetPropertyUseContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_PROPERTY_CONTEXT_REQUEST => return Ok(Request::XselinuxGetPropertyContext(xselinux::GetPropertyContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_PROPERTY_DATA_CONTEXT_REQUEST => return Ok(Request::XselinuxGetPropertyDataContext(xselinux::GetPropertyDataContextRequest::try_parse_request(header, remaining)?)), xselinux::LIST_PROPERTIES_REQUEST => return Ok(Request::XselinuxListProperties(xselinux::ListPropertiesRequest::try_parse_request(header, remaining)?)), xselinux::SET_SELECTION_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxSetSelectionCreateContext(xselinux::SetSelectionCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_SELECTION_CREATE_CONTEXT_REQUEST => return Ok(Request::XselinuxGetSelectionCreateContext(xselinux::GetSelectionCreateContextRequest::try_parse_request(header, remaining)?)), xselinux::SET_SELECTION_USE_CONTEXT_REQUEST => return Ok(Request::XselinuxSetSelectionUseContext(xselinux::SetSelectionUseContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_SELECTION_USE_CONTEXT_REQUEST => return Ok(Request::XselinuxGetSelectionUseContext(xselinux::GetSelectionUseContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_SELECTION_CONTEXT_REQUEST => return Ok(Request::XselinuxGetSelectionContext(xselinux::GetSelectionContextRequest::try_parse_request(header, remaining)?)), xselinux::GET_SELECTION_DATA_CONTEXT_REQUEST => return Ok(Request::XselinuxGetSelectionDataContext(xselinux::GetSelectionDataContextRequest::try_parse_request(header, remaining)?)), xselinux::LIST_SELECTIONS_REQUEST => return Ok(Request::XselinuxListSelections(xselinux::ListSelectionsRequest::try_parse_request(header, remaining)?)), xselinux::GET_CLIENT_CONTEXT_REQUEST => return Ok(Request::XselinuxGetClientContext(xselinux::GetClientContextRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xtest")] Some((xtest::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xtest::GET_VERSION_REQUEST => return Ok(Request::XtestGetVersion(xtest::GetVersionRequest::try_parse_request(header, remaining)?)), xtest::COMPARE_CURSOR_REQUEST => return Ok(Request::XtestCompareCursor(xtest::CompareCursorRequest::try_parse_request(header, remaining)?)), xtest::FAKE_INPUT_REQUEST => return Ok(Request::XtestFakeInput(xtest::FakeInputRequest::try_parse_request(header, remaining)?)), xtest::GRAB_CONTROL_REQUEST => return Ok(Request::XtestGrabControl(xtest::GrabControlRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xv")] Some((xv::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xv::QUERY_EXTENSION_REQUEST => return Ok(Request::XvQueryExtension(xv::QueryExtensionRequest::try_parse_request(header, remaining)?)), xv::QUERY_ADAPTORS_REQUEST => return Ok(Request::XvQueryAdaptors(xv::QueryAdaptorsRequest::try_parse_request(header, remaining)?)), xv::QUERY_ENCODINGS_REQUEST => return Ok(Request::XvQueryEncodings(xv::QueryEncodingsRequest::try_parse_request(header, remaining)?)), xv::GRAB_PORT_REQUEST => return Ok(Request::XvGrabPort(xv::GrabPortRequest::try_parse_request(header, remaining)?)), xv::UNGRAB_PORT_REQUEST => return Ok(Request::XvUngrabPort(xv::UngrabPortRequest::try_parse_request(header, remaining)?)), xv::PUT_VIDEO_REQUEST => return Ok(Request::XvPutVideo(xv::PutVideoRequest::try_parse_request(header, remaining)?)), xv::PUT_STILL_REQUEST => return Ok(Request::XvPutStill(xv::PutStillRequest::try_parse_request(header, remaining)?)), xv::GET_VIDEO_REQUEST => return Ok(Request::XvGetVideo(xv::GetVideoRequest::try_parse_request(header, remaining)?)), xv::GET_STILL_REQUEST => return Ok(Request::XvGetStill(xv::GetStillRequest::try_parse_request(header, remaining)?)), xv::STOP_VIDEO_REQUEST => return Ok(Request::XvStopVideo(xv::StopVideoRequest::try_parse_request(header, remaining)?)), xv::SELECT_VIDEO_NOTIFY_REQUEST => return Ok(Request::XvSelectVideoNotify(xv::SelectVideoNotifyRequest::try_parse_request(header, remaining)?)), xv::SELECT_PORT_NOTIFY_REQUEST => return Ok(Request::XvSelectPortNotify(xv::SelectPortNotifyRequest::try_parse_request(header, remaining)?)), xv::QUERY_BEST_SIZE_REQUEST => return Ok(Request::XvQueryBestSize(xv::QueryBestSizeRequest::try_parse_request(header, remaining)?)), xv::SET_PORT_ATTRIBUTE_REQUEST => return Ok(Request::XvSetPortAttribute(xv::SetPortAttributeRequest::try_parse_request(header, remaining)?)), xv::GET_PORT_ATTRIBUTE_REQUEST => return Ok(Request::XvGetPortAttribute(xv::GetPortAttributeRequest::try_parse_request(header, remaining)?)), xv::QUERY_PORT_ATTRIBUTES_REQUEST => return Ok(Request::XvQueryPortAttributes(xv::QueryPortAttributesRequest::try_parse_request(header, remaining)?)), xv::LIST_IMAGE_FORMATS_REQUEST => return Ok(Request::XvListImageFormats(xv::ListImageFormatsRequest::try_parse_request(header, remaining)?)), xv::QUERY_IMAGE_ATTRIBUTES_REQUEST => return Ok(Request::XvQueryImageAttributes(xv::QueryImageAttributesRequest::try_parse_request(header, remaining)?)), xv::PUT_IMAGE_REQUEST => return Ok(Request::XvPutImage(xv::PutImageRequest::try_parse_request(header, remaining)?)), xv::SHM_PUT_IMAGE_REQUEST => return Ok(Request::XvShmPutImage(xv::ShmPutImageRequest::try_parse_request(header, remaining)?)), _ => (), } } #[cfg(feature = "xvmc")] Some((xvmc::X11_EXTENSION_NAME, _)) => { match header.minor_opcode { xvmc::QUERY_VERSION_REQUEST => return Ok(Request::XvmcQueryVersion(xvmc::QueryVersionRequest::try_parse_request(header, remaining)?)), xvmc::LIST_SURFACE_TYPES_REQUEST => return Ok(Request::XvmcListSurfaceTypes(xvmc::ListSurfaceTypesRequest::try_parse_request(header, remaining)?)), xvmc::CREATE_CONTEXT_REQUEST => return Ok(Request::XvmcCreateContext(xvmc::CreateContextRequest::try_parse_request(header, remaining)?)), xvmc::DESTROY_CONTEXT_REQUEST => return Ok(Request::XvmcDestroyContext(xvmc::DestroyContextRequest::try_parse_request(header, remaining)?)), xvmc::CREATE_SURFACE_REQUEST => return Ok(Request::XvmcCreateSurface(xvmc::CreateSurfaceRequest::try_parse_request(header, remaining)?)), xvmc::DESTROY_SURFACE_REQUEST => return Ok(Request::XvmcDestroySurface(xvmc::DestroySurfaceRequest::try_parse_request(header, remaining)?)), xvmc::CREATE_SUBPICTURE_REQUEST => return Ok(Request::XvmcCreateSubpicture(xvmc::CreateSubpictureRequest::try_parse_request(header, remaining)?)), xvmc::DESTROY_SUBPICTURE_REQUEST => return Ok(Request::XvmcDestroySubpicture(xvmc::DestroySubpictureRequest::try_parse_request(header, remaining)?)), xvmc::LIST_SUBPICTURE_TYPES_REQUEST => return Ok(Request::XvmcListSubpictureTypes(xvmc::ListSubpictureTypesRequest::try_parse_request(header, remaining)?)), _ => (), } } _ => (), } Ok(Request::Unknown(header, Cow::Borrowed(remaining))) } /// Get the matching reply parser (if any) for this request. /// For `Request::Unknown`, `None` is also returned. pub fn reply_parser(&self) -> Option { match self { Request::Unknown(_, _) => None, Request::CreateWindow(_) => None, Request::ChangeWindowAttributes(_) => None, Request::GetWindowAttributes(_) => Some(xproto::GetWindowAttributesRequest::parse_reply), Request::DestroyWindow(_) => None, Request::DestroySubwindows(_) => None, Request::ChangeSaveSet(_) => None, Request::ReparentWindow(_) => None, Request::MapWindow(_) => None, Request::MapSubwindows(_) => None, Request::UnmapWindow(_) => None, Request::UnmapSubwindows(_) => None, Request::ConfigureWindow(_) => None, Request::CirculateWindow(_) => None, Request::GetGeometry(_) => Some(xproto::GetGeometryRequest::parse_reply), Request::QueryTree(_) => Some(xproto::QueryTreeRequest::parse_reply), Request::InternAtom(_) => Some(xproto::InternAtomRequest::parse_reply), Request::GetAtomName(_) => Some(xproto::GetAtomNameRequest::parse_reply), Request::ChangeProperty(_) => None, Request::DeleteProperty(_) => None, Request::GetProperty(_) => Some(xproto::GetPropertyRequest::parse_reply), Request::ListProperties(_) => Some(xproto::ListPropertiesRequest::parse_reply), Request::SetSelectionOwner(_) => None, Request::GetSelectionOwner(_) => Some(xproto::GetSelectionOwnerRequest::parse_reply), Request::ConvertSelection(_) => None, Request::SendEvent(_) => None, Request::GrabPointer(_) => Some(xproto::GrabPointerRequest::parse_reply), Request::UngrabPointer(_) => None, Request::GrabButton(_) => None, Request::UngrabButton(_) => None, Request::ChangeActivePointerGrab(_) => None, Request::GrabKeyboard(_) => Some(xproto::GrabKeyboardRequest::parse_reply), Request::UngrabKeyboard(_) => None, Request::GrabKey(_) => None, Request::UngrabKey(_) => None, Request::AllowEvents(_) => None, Request::GrabServer(_) => None, Request::UngrabServer(_) => None, Request::QueryPointer(_) => Some(xproto::QueryPointerRequest::parse_reply), Request::GetMotionEvents(_) => Some(xproto::GetMotionEventsRequest::parse_reply), Request::TranslateCoordinates(_) => Some(xproto::TranslateCoordinatesRequest::parse_reply), Request::WarpPointer(_) => None, Request::SetInputFocus(_) => None, Request::GetInputFocus(_) => Some(xproto::GetInputFocusRequest::parse_reply), Request::QueryKeymap(_) => Some(xproto::QueryKeymapRequest::parse_reply), Request::OpenFont(_) => None, Request::CloseFont(_) => None, Request::QueryFont(_) => Some(xproto::QueryFontRequest::parse_reply), Request::QueryTextExtents(_) => Some(xproto::QueryTextExtentsRequest::parse_reply), Request::ListFonts(_) => Some(xproto::ListFontsRequest::parse_reply), Request::ListFontsWithInfo(_) => Some(xproto::ListFontsWithInfoRequest::parse_reply), Request::SetFontPath(_) => None, Request::GetFontPath(_) => Some(xproto::GetFontPathRequest::parse_reply), Request::CreatePixmap(_) => None, Request::FreePixmap(_) => None, Request::CreateGC(_) => None, Request::ChangeGC(_) => None, Request::CopyGC(_) => None, Request::SetDashes(_) => None, Request::SetClipRectangles(_) => None, Request::FreeGC(_) => None, Request::ClearArea(_) => None, Request::CopyArea(_) => None, Request::CopyPlane(_) => None, Request::PolyPoint(_) => None, Request::PolyLine(_) => None, Request::PolySegment(_) => None, Request::PolyRectangle(_) => None, Request::PolyArc(_) => None, Request::FillPoly(_) => None, Request::PolyFillRectangle(_) => None, Request::PolyFillArc(_) => None, Request::PutImage(_) => None, Request::GetImage(_) => Some(xproto::GetImageRequest::parse_reply), Request::PolyText8(_) => None, Request::PolyText16(_) => None, Request::ImageText8(_) => None, Request::ImageText16(_) => None, Request::CreateColormap(_) => None, Request::FreeColormap(_) => None, Request::CopyColormapAndFree(_) => None, Request::InstallColormap(_) => None, Request::UninstallColormap(_) => None, Request::ListInstalledColormaps(_) => Some(xproto::ListInstalledColormapsRequest::parse_reply), Request::AllocColor(_) => Some(xproto::AllocColorRequest::parse_reply), Request::AllocNamedColor(_) => Some(xproto::AllocNamedColorRequest::parse_reply), Request::AllocColorCells(_) => Some(xproto::AllocColorCellsRequest::parse_reply), Request::AllocColorPlanes(_) => Some(xproto::AllocColorPlanesRequest::parse_reply), Request::FreeColors(_) => None, Request::StoreColors(_) => None, Request::StoreNamedColor(_) => None, Request::QueryColors(_) => Some(xproto::QueryColorsRequest::parse_reply), Request::LookupColor(_) => Some(xproto::LookupColorRequest::parse_reply), Request::CreateCursor(_) => None, Request::CreateGlyphCursor(_) => None, Request::FreeCursor(_) => None, Request::RecolorCursor(_) => None, Request::QueryBestSize(_) => Some(xproto::QueryBestSizeRequest::parse_reply), Request::QueryExtension(_) => Some(xproto::QueryExtensionRequest::parse_reply), Request::ListExtensions(_) => Some(xproto::ListExtensionsRequest::parse_reply), Request::ChangeKeyboardMapping(_) => None, Request::GetKeyboardMapping(_) => Some(xproto::GetKeyboardMappingRequest::parse_reply), Request::ChangeKeyboardControl(_) => None, Request::GetKeyboardControl(_) => Some(xproto::GetKeyboardControlRequest::parse_reply), Request::Bell(_) => None, Request::ChangePointerControl(_) => None, Request::GetPointerControl(_) => Some(xproto::GetPointerControlRequest::parse_reply), Request::SetScreenSaver(_) => None, Request::GetScreenSaver(_) => Some(xproto::GetScreenSaverRequest::parse_reply), Request::ChangeHosts(_) => None, Request::ListHosts(_) => Some(xproto::ListHostsRequest::parse_reply), Request::SetAccessControl(_) => None, Request::SetCloseDownMode(_) => None, Request::KillClient(_) => None, Request::RotateProperties(_) => None, Request::ForceScreenSaver(_) => None, Request::SetPointerMapping(_) => Some(xproto::SetPointerMappingRequest::parse_reply), Request::GetPointerMapping(_) => Some(xproto::GetPointerMappingRequest::parse_reply), Request::SetModifierMapping(_) => Some(xproto::SetModifierMappingRequest::parse_reply), Request::GetModifierMapping(_) => Some(xproto::GetModifierMappingRequest::parse_reply), Request::NoOperation(_) => None, Request::BigreqEnable(_) => Some(bigreq::EnableRequest::parse_reply), #[cfg(feature = "composite")] Request::CompositeQueryVersion(_) => Some(composite::QueryVersionRequest::parse_reply), #[cfg(feature = "composite")] Request::CompositeRedirectWindow(_) => None, #[cfg(feature = "composite")] Request::CompositeRedirectSubwindows(_) => None, #[cfg(feature = "composite")] Request::CompositeUnredirectWindow(_) => None, #[cfg(feature = "composite")] Request::CompositeUnredirectSubwindows(_) => None, #[cfg(feature = "composite")] Request::CompositeCreateRegionFromBorderClip(_) => None, #[cfg(feature = "composite")] Request::CompositeNameWindowPixmap(_) => None, #[cfg(feature = "composite")] Request::CompositeGetOverlayWindow(_) => Some(composite::GetOverlayWindowRequest::parse_reply), #[cfg(feature = "composite")] Request::CompositeReleaseOverlayWindow(_) => None, #[cfg(feature = "damage")] Request::DamageQueryVersion(_) => Some(damage::QueryVersionRequest::parse_reply), #[cfg(feature = "damage")] Request::DamageCreate(_) => None, #[cfg(feature = "damage")] Request::DamageDestroy(_) => None, #[cfg(feature = "damage")] Request::DamageSubtract(_) => None, #[cfg(feature = "damage")] Request::DamageAdd(_) => None, #[cfg(feature = "dpms")] Request::DpmsGetVersion(_) => Some(dpms::GetVersionRequest::parse_reply), #[cfg(feature = "dpms")] Request::DpmsCapable(_) => Some(dpms::CapableRequest::parse_reply), #[cfg(feature = "dpms")] Request::DpmsGetTimeouts(_) => Some(dpms::GetTimeoutsRequest::parse_reply), #[cfg(feature = "dpms")] Request::DpmsSetTimeouts(_) => None, #[cfg(feature = "dpms")] Request::DpmsEnable(_) => None, #[cfg(feature = "dpms")] Request::DpmsDisable(_) => None, #[cfg(feature = "dpms")] Request::DpmsForceLevel(_) => None, #[cfg(feature = "dpms")] Request::DpmsInfo(_) => Some(dpms::InfoRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2QueryVersion(_) => Some(dri2::QueryVersionRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2Connect(_) => Some(dri2::ConnectRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2Authenticate(_) => Some(dri2::AuthenticateRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2CreateDrawable(_) => None, #[cfg(feature = "dri2")] Request::Dri2DestroyDrawable(_) => None, #[cfg(feature = "dri2")] Request::Dri2GetBuffers(_) => Some(dri2::GetBuffersRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2CopyRegion(_) => Some(dri2::CopyRegionRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2GetBuffersWithFormat(_) => Some(dri2::GetBuffersWithFormatRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2SwapBuffers(_) => Some(dri2::SwapBuffersRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2GetMSC(_) => Some(dri2::GetMSCRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2WaitMSC(_) => Some(dri2::WaitMSCRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2WaitSBC(_) => Some(dri2::WaitSBCRequest::parse_reply), #[cfg(feature = "dri2")] Request::Dri2SwapInterval(_) => None, #[cfg(feature = "dri2")] Request::Dri2GetParam(_) => Some(dri2::GetParamRequest::parse_reply), #[cfg(feature = "dri3")] Request::Dri3QueryVersion(_) => Some(dri3::QueryVersionRequest::parse_reply), #[cfg(feature = "dri3")] Request::Dri3Open(_) => Some(dri3::OpenRequest::parse_reply), #[cfg(feature = "dri3")] Request::Dri3PixmapFromBuffer(_) => None, #[cfg(feature = "dri3")] Request::Dri3BufferFromPixmap(_) => Some(dri3::BufferFromPixmapRequest::parse_reply), #[cfg(feature = "dri3")] Request::Dri3FenceFromFD(_) => None, #[cfg(feature = "dri3")] Request::Dri3FDFromFence(_) => Some(dri3::FDFromFenceRequest::parse_reply), #[cfg(feature = "dri3")] Request::Dri3GetSupportedModifiers(_) => Some(dri3::GetSupportedModifiersRequest::parse_reply), #[cfg(feature = "dri3")] Request::Dri3PixmapFromBuffers(_) => None, #[cfg(feature = "dri3")] Request::Dri3BuffersFromPixmap(_) => Some(dri3::BuffersFromPixmapRequest::parse_reply), Request::GeQueryVersion(_) => Some(ge::QueryVersionRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxRender(_) => None, #[cfg(feature = "glx")] Request::GlxRenderLarge(_) => None, #[cfg(feature = "glx")] Request::GlxCreateContext(_) => None, #[cfg(feature = "glx")] Request::GlxDestroyContext(_) => None, #[cfg(feature = "glx")] Request::GlxMakeCurrent(_) => Some(glx::MakeCurrentRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxIsDirect(_) => Some(glx::IsDirectRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxQueryVersion(_) => Some(glx::QueryVersionRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxWaitGL(_) => None, #[cfg(feature = "glx")] Request::GlxWaitX(_) => None, #[cfg(feature = "glx")] Request::GlxCopyContext(_) => None, #[cfg(feature = "glx")] Request::GlxSwapBuffers(_) => None, #[cfg(feature = "glx")] Request::GlxUseXFont(_) => None, #[cfg(feature = "glx")] Request::GlxCreateGLXPixmap(_) => None, #[cfg(feature = "glx")] Request::GlxGetVisualConfigs(_) => Some(glx::GetVisualConfigsRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxDestroyGLXPixmap(_) => None, #[cfg(feature = "glx")] Request::GlxVendorPrivate(_) => None, #[cfg(feature = "glx")] Request::GlxVendorPrivateWithReply(_) => Some(glx::VendorPrivateWithReplyRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxQueryExtensionsString(_) => Some(glx::QueryExtensionsStringRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxQueryServerString(_) => Some(glx::QueryServerStringRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxClientInfo(_) => None, #[cfg(feature = "glx")] Request::GlxGetFBConfigs(_) => Some(glx::GetFBConfigsRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxCreatePixmap(_) => None, #[cfg(feature = "glx")] Request::GlxDestroyPixmap(_) => None, #[cfg(feature = "glx")] Request::GlxCreateNewContext(_) => None, #[cfg(feature = "glx")] Request::GlxQueryContext(_) => Some(glx::QueryContextRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxMakeContextCurrent(_) => Some(glx::MakeContextCurrentRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxCreatePbuffer(_) => None, #[cfg(feature = "glx")] Request::GlxDestroyPbuffer(_) => None, #[cfg(feature = "glx")] Request::GlxGetDrawableAttributes(_) => Some(glx::GetDrawableAttributesRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxChangeDrawableAttributes(_) => None, #[cfg(feature = "glx")] Request::GlxCreateWindow(_) => None, #[cfg(feature = "glx")] Request::GlxDeleteWindow(_) => None, #[cfg(feature = "glx")] Request::GlxSetClientInfoARB(_) => None, #[cfg(feature = "glx")] Request::GlxCreateContextAttribsARB(_) => None, #[cfg(feature = "glx")] Request::GlxSetClientInfo2ARB(_) => None, #[cfg(feature = "glx")] Request::GlxNewList(_) => None, #[cfg(feature = "glx")] Request::GlxEndList(_) => None, #[cfg(feature = "glx")] Request::GlxDeleteLists(_) => None, #[cfg(feature = "glx")] Request::GlxGenLists(_) => Some(glx::GenListsRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxFeedbackBuffer(_) => None, #[cfg(feature = "glx")] Request::GlxSelectBuffer(_) => None, #[cfg(feature = "glx")] Request::GlxRenderMode(_) => Some(glx::RenderModeRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxFinish(_) => Some(glx::FinishRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxPixelStoref(_) => None, #[cfg(feature = "glx")] Request::GlxPixelStorei(_) => None, #[cfg(feature = "glx")] Request::GlxReadPixels(_) => Some(glx::ReadPixelsRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetBooleanv(_) => Some(glx::GetBooleanvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetClipPlane(_) => Some(glx::GetClipPlaneRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetDoublev(_) => Some(glx::GetDoublevRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetError(_) => Some(glx::GetErrorRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetFloatv(_) => Some(glx::GetFloatvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetIntegerv(_) => Some(glx::GetIntegervRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetLightfv(_) => Some(glx::GetLightfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetLightiv(_) => Some(glx::GetLightivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMapdv(_) => Some(glx::GetMapdvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMapfv(_) => Some(glx::GetMapfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMapiv(_) => Some(glx::GetMapivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMaterialfv(_) => Some(glx::GetMaterialfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMaterialiv(_) => Some(glx::GetMaterialivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetPixelMapfv(_) => Some(glx::GetPixelMapfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetPixelMapuiv(_) => Some(glx::GetPixelMapuivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetPixelMapusv(_) => Some(glx::GetPixelMapusvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetPolygonStipple(_) => Some(glx::GetPolygonStippleRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetString(_) => Some(glx::GetStringRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexEnvfv(_) => Some(glx::GetTexEnvfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexEnviv(_) => Some(glx::GetTexEnvivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexGendv(_) => Some(glx::GetTexGendvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexGenfv(_) => Some(glx::GetTexGenfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexGeniv(_) => Some(glx::GetTexGenivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexImage(_) => Some(glx::GetTexImageRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexParameterfv(_) => Some(glx::GetTexParameterfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexParameteriv(_) => Some(glx::GetTexParameterivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexLevelParameterfv(_) => Some(glx::GetTexLevelParameterfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetTexLevelParameteriv(_) => Some(glx::GetTexLevelParameterivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxIsEnabled(_) => Some(glx::IsEnabledRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxIsList(_) => Some(glx::IsListRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxFlush(_) => None, #[cfg(feature = "glx")] Request::GlxAreTexturesResident(_) => Some(glx::AreTexturesResidentRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxDeleteTextures(_) => None, #[cfg(feature = "glx")] Request::GlxGenTextures(_) => Some(glx::GenTexturesRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxIsTexture(_) => Some(glx::IsTextureRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetColorTable(_) => Some(glx::GetColorTableRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetColorTableParameterfv(_) => Some(glx::GetColorTableParameterfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetColorTableParameteriv(_) => Some(glx::GetColorTableParameterivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetConvolutionFilter(_) => Some(glx::GetConvolutionFilterRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetConvolutionParameterfv(_) => Some(glx::GetConvolutionParameterfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetConvolutionParameteriv(_) => Some(glx::GetConvolutionParameterivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetSeparableFilter(_) => Some(glx::GetSeparableFilterRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetHistogram(_) => Some(glx::GetHistogramRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetHistogramParameterfv(_) => Some(glx::GetHistogramParameterfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetHistogramParameteriv(_) => Some(glx::GetHistogramParameterivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMinmax(_) => Some(glx::GetMinmaxRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMinmaxParameterfv(_) => Some(glx::GetMinmaxParameterfvRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetMinmaxParameteriv(_) => Some(glx::GetMinmaxParameterivRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetCompressedTexImageARB(_) => Some(glx::GetCompressedTexImageARBRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxDeleteQueriesARB(_) => None, #[cfg(feature = "glx")] Request::GlxGenQueriesARB(_) => Some(glx::GenQueriesARBRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxIsQueryARB(_) => Some(glx::IsQueryARBRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetQueryivARB(_) => Some(glx::GetQueryivARBRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetQueryObjectivARB(_) => Some(glx::GetQueryObjectivARBRequest::parse_reply), #[cfg(feature = "glx")] Request::GlxGetQueryObjectuivARB(_) => Some(glx::GetQueryObjectuivARBRequest::parse_reply), #[cfg(feature = "present")] Request::PresentQueryVersion(_) => Some(present::QueryVersionRequest::parse_reply), #[cfg(feature = "present")] Request::PresentPixmap(_) => None, #[cfg(feature = "present")] Request::PresentNotifyMSC(_) => None, #[cfg(feature = "present")] Request::PresentSelectInput(_) => None, #[cfg(feature = "present")] Request::PresentQueryCapabilities(_) => Some(present::QueryCapabilitiesRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrQueryVersion(_) => Some(randr::QueryVersionRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetScreenConfig(_) => Some(randr::SetScreenConfigRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSelectInput(_) => None, #[cfg(feature = "randr")] Request::RandrGetScreenInfo(_) => Some(randr::GetScreenInfoRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetScreenSizeRange(_) => Some(randr::GetScreenSizeRangeRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetScreenSize(_) => None, #[cfg(feature = "randr")] Request::RandrGetScreenResources(_) => Some(randr::GetScreenResourcesRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetOutputInfo(_) => Some(randr::GetOutputInfoRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrListOutputProperties(_) => Some(randr::ListOutputPropertiesRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrQueryOutputProperty(_) => Some(randr::QueryOutputPropertyRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrConfigureOutputProperty(_) => None, #[cfg(feature = "randr")] Request::RandrChangeOutputProperty(_) => None, #[cfg(feature = "randr")] Request::RandrDeleteOutputProperty(_) => None, #[cfg(feature = "randr")] Request::RandrGetOutputProperty(_) => Some(randr::GetOutputPropertyRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrCreateMode(_) => Some(randr::CreateModeRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrDestroyMode(_) => None, #[cfg(feature = "randr")] Request::RandrAddOutputMode(_) => None, #[cfg(feature = "randr")] Request::RandrDeleteOutputMode(_) => None, #[cfg(feature = "randr")] Request::RandrGetCrtcInfo(_) => Some(randr::GetCrtcInfoRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetCrtcConfig(_) => Some(randr::SetCrtcConfigRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetCrtcGammaSize(_) => Some(randr::GetCrtcGammaSizeRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetCrtcGamma(_) => Some(randr::GetCrtcGammaRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetCrtcGamma(_) => None, #[cfg(feature = "randr")] Request::RandrGetScreenResourcesCurrent(_) => Some(randr::GetScreenResourcesCurrentRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetCrtcTransform(_) => None, #[cfg(feature = "randr")] Request::RandrGetCrtcTransform(_) => Some(randr::GetCrtcTransformRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetPanning(_) => Some(randr::GetPanningRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetPanning(_) => Some(randr::SetPanningRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetOutputPrimary(_) => None, #[cfg(feature = "randr")] Request::RandrGetOutputPrimary(_) => Some(randr::GetOutputPrimaryRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetProviders(_) => Some(randr::GetProvidersRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetProviderInfo(_) => Some(randr::GetProviderInfoRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetProviderOffloadSink(_) => None, #[cfg(feature = "randr")] Request::RandrSetProviderOutputSource(_) => None, #[cfg(feature = "randr")] Request::RandrListProviderProperties(_) => Some(randr::ListProviderPropertiesRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrQueryProviderProperty(_) => Some(randr::QueryProviderPropertyRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrConfigureProviderProperty(_) => None, #[cfg(feature = "randr")] Request::RandrChangeProviderProperty(_) => None, #[cfg(feature = "randr")] Request::RandrDeleteProviderProperty(_) => None, #[cfg(feature = "randr")] Request::RandrGetProviderProperty(_) => Some(randr::GetProviderPropertyRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrGetMonitors(_) => Some(randr::GetMonitorsRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrSetMonitor(_) => None, #[cfg(feature = "randr")] Request::RandrDeleteMonitor(_) => None, #[cfg(feature = "randr")] Request::RandrCreateLease(_) => Some(randr::CreateLeaseRequest::parse_reply), #[cfg(feature = "randr")] Request::RandrFreeLease(_) => None, #[cfg(feature = "record")] Request::RecordQueryVersion(_) => Some(record::QueryVersionRequest::parse_reply), #[cfg(feature = "record")] Request::RecordCreateContext(_) => None, #[cfg(feature = "record")] Request::RecordRegisterClients(_) => None, #[cfg(feature = "record")] Request::RecordUnregisterClients(_) => None, #[cfg(feature = "record")] Request::RecordGetContext(_) => Some(record::GetContextRequest::parse_reply), #[cfg(feature = "record")] Request::RecordEnableContext(_) => Some(record::EnableContextRequest::parse_reply), #[cfg(feature = "record")] Request::RecordDisableContext(_) => None, #[cfg(feature = "record")] Request::RecordFreeContext(_) => None, #[cfg(feature = "render")] Request::RenderQueryVersion(_) => Some(render::QueryVersionRequest::parse_reply), #[cfg(feature = "render")] Request::RenderQueryPictFormats(_) => Some(render::QueryPictFormatsRequest::parse_reply), #[cfg(feature = "render")] Request::RenderQueryPictIndexValues(_) => Some(render::QueryPictIndexValuesRequest::parse_reply), #[cfg(feature = "render")] Request::RenderCreatePicture(_) => None, #[cfg(feature = "render")] Request::RenderChangePicture(_) => None, #[cfg(feature = "render")] Request::RenderSetPictureClipRectangles(_) => None, #[cfg(feature = "render")] Request::RenderFreePicture(_) => None, #[cfg(feature = "render")] Request::RenderComposite(_) => None, #[cfg(feature = "render")] Request::RenderTrapezoids(_) => None, #[cfg(feature = "render")] Request::RenderTriangles(_) => None, #[cfg(feature = "render")] Request::RenderTriStrip(_) => None, #[cfg(feature = "render")] Request::RenderTriFan(_) => None, #[cfg(feature = "render")] Request::RenderCreateGlyphSet(_) => None, #[cfg(feature = "render")] Request::RenderReferenceGlyphSet(_) => None, #[cfg(feature = "render")] Request::RenderFreeGlyphSet(_) => None, #[cfg(feature = "render")] Request::RenderAddGlyphs(_) => None, #[cfg(feature = "render")] Request::RenderFreeGlyphs(_) => None, #[cfg(feature = "render")] Request::RenderCompositeGlyphs8(_) => None, #[cfg(feature = "render")] Request::RenderCompositeGlyphs16(_) => None, #[cfg(feature = "render")] Request::RenderCompositeGlyphs32(_) => None, #[cfg(feature = "render")] Request::RenderFillRectangles(_) => None, #[cfg(feature = "render")] Request::RenderCreateCursor(_) => None, #[cfg(feature = "render")] Request::RenderSetPictureTransform(_) => None, #[cfg(feature = "render")] Request::RenderQueryFilters(_) => Some(render::QueryFiltersRequest::parse_reply), #[cfg(feature = "render")] Request::RenderSetPictureFilter(_) => None, #[cfg(feature = "render")] Request::RenderCreateAnimCursor(_) => None, #[cfg(feature = "render")] Request::RenderAddTraps(_) => None, #[cfg(feature = "render")] Request::RenderCreateSolidFill(_) => None, #[cfg(feature = "render")] Request::RenderCreateLinearGradient(_) => None, #[cfg(feature = "render")] Request::RenderCreateRadialGradient(_) => None, #[cfg(feature = "render")] Request::RenderCreateConicalGradient(_) => None, #[cfg(feature = "res")] Request::ResQueryVersion(_) => Some(res::QueryVersionRequest::parse_reply), #[cfg(feature = "res")] Request::ResQueryClients(_) => Some(res::QueryClientsRequest::parse_reply), #[cfg(feature = "res")] Request::ResQueryClientResources(_) => Some(res::QueryClientResourcesRequest::parse_reply), #[cfg(feature = "res")] Request::ResQueryClientPixmapBytes(_) => Some(res::QueryClientPixmapBytesRequest::parse_reply), #[cfg(feature = "res")] Request::ResQueryClientIds(_) => Some(res::QueryClientIdsRequest::parse_reply), #[cfg(feature = "res")] Request::ResQueryResourceBytes(_) => Some(res::QueryResourceBytesRequest::parse_reply), #[cfg(feature = "screensaver")] Request::ScreensaverQueryVersion(_) => Some(screensaver::QueryVersionRequest::parse_reply), #[cfg(feature = "screensaver")] Request::ScreensaverQueryInfo(_) => Some(screensaver::QueryInfoRequest::parse_reply), #[cfg(feature = "screensaver")] Request::ScreensaverSelectInput(_) => None, #[cfg(feature = "screensaver")] Request::ScreensaverSetAttributes(_) => None, #[cfg(feature = "screensaver")] Request::ScreensaverUnsetAttributes(_) => None, #[cfg(feature = "screensaver")] Request::ScreensaverSuspend(_) => None, #[cfg(feature = "shape")] Request::ShapeQueryVersion(_) => Some(shape::QueryVersionRequest::parse_reply), #[cfg(feature = "shape")] Request::ShapeRectangles(_) => None, #[cfg(feature = "shape")] Request::ShapeMask(_) => None, #[cfg(feature = "shape")] Request::ShapeCombine(_) => None, #[cfg(feature = "shape")] Request::ShapeOffset(_) => None, #[cfg(feature = "shape")] Request::ShapeQueryExtents(_) => Some(shape::QueryExtentsRequest::parse_reply), #[cfg(feature = "shape")] Request::ShapeSelectInput(_) => None, #[cfg(feature = "shape")] Request::ShapeInputSelected(_) => Some(shape::InputSelectedRequest::parse_reply), #[cfg(feature = "shape")] Request::ShapeGetRectangles(_) => Some(shape::GetRectanglesRequest::parse_reply), #[cfg(feature = "shm")] Request::ShmQueryVersion(_) => Some(shm::QueryVersionRequest::parse_reply), #[cfg(feature = "shm")] Request::ShmAttach(_) => None, #[cfg(feature = "shm")] Request::ShmDetach(_) => None, #[cfg(feature = "shm")] Request::ShmPutImage(_) => None, #[cfg(feature = "shm")] Request::ShmGetImage(_) => Some(shm::GetImageRequest::parse_reply), #[cfg(feature = "shm")] Request::ShmCreatePixmap(_) => None, #[cfg(feature = "shm")] Request::ShmAttachFd(_) => None, #[cfg(feature = "shm")] Request::ShmCreateSegment(_) => Some(shm::CreateSegmentRequest::parse_reply), #[cfg(feature = "sync")] Request::SyncInitialize(_) => Some(sync::InitializeRequest::parse_reply), #[cfg(feature = "sync")] Request::SyncListSystemCounters(_) => Some(sync::ListSystemCountersRequest::parse_reply), #[cfg(feature = "sync")] Request::SyncCreateCounter(_) => None, #[cfg(feature = "sync")] Request::SyncDestroyCounter(_) => None, #[cfg(feature = "sync")] Request::SyncQueryCounter(_) => Some(sync::QueryCounterRequest::parse_reply), #[cfg(feature = "sync")] Request::SyncAwait(_) => None, #[cfg(feature = "sync")] Request::SyncChangeCounter(_) => None, #[cfg(feature = "sync")] Request::SyncSetCounter(_) => None, #[cfg(feature = "sync")] Request::SyncCreateAlarm(_) => None, #[cfg(feature = "sync")] Request::SyncChangeAlarm(_) => None, #[cfg(feature = "sync")] Request::SyncDestroyAlarm(_) => None, #[cfg(feature = "sync")] Request::SyncQueryAlarm(_) => Some(sync::QueryAlarmRequest::parse_reply), #[cfg(feature = "sync")] Request::SyncSetPriority(_) => None, #[cfg(feature = "sync")] Request::SyncGetPriority(_) => Some(sync::GetPriorityRequest::parse_reply), #[cfg(feature = "sync")] Request::SyncCreateFence(_) => None, #[cfg(feature = "sync")] Request::SyncTriggerFence(_) => None, #[cfg(feature = "sync")] Request::SyncResetFence(_) => None, #[cfg(feature = "sync")] Request::SyncDestroyFence(_) => None, #[cfg(feature = "sync")] Request::SyncQueryFence(_) => Some(sync::QueryFenceRequest::parse_reply), #[cfg(feature = "sync")] Request::SyncAwaitFence(_) => None, Request::XcMiscGetVersion(_) => Some(xc_misc::GetVersionRequest::parse_reply), Request::XcMiscGetXIDRange(_) => Some(xc_misc::GetXIDRangeRequest::parse_reply), Request::XcMiscGetXIDList(_) => Some(xc_misc::GetXIDListRequest::parse_reply), #[cfg(feature = "xevie")] Request::XevieQueryVersion(_) => Some(xevie::QueryVersionRequest::parse_reply), #[cfg(feature = "xevie")] Request::XevieStart(_) => Some(xevie::StartRequest::parse_reply), #[cfg(feature = "xevie")] Request::XevieEnd(_) => Some(xevie::EndRequest::parse_reply), #[cfg(feature = "xevie")] Request::XevieSend(_) => Some(xevie::SendRequest::parse_reply), #[cfg(feature = "xevie")] Request::XevieSelectInput(_) => Some(xevie::SelectInputRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driQueryVersion(_) => Some(xf86dri::QueryVersionRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driQueryDirectRenderingCapable(_) => Some(xf86dri::QueryDirectRenderingCapableRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driOpenConnection(_) => Some(xf86dri::OpenConnectionRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driCloseConnection(_) => None, #[cfg(feature = "xf86dri")] Request::Xf86driGetClientDriverName(_) => Some(xf86dri::GetClientDriverNameRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driCreateContext(_) => Some(xf86dri::CreateContextRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driDestroyContext(_) => None, #[cfg(feature = "xf86dri")] Request::Xf86driCreateDrawable(_) => Some(xf86dri::CreateDrawableRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driDestroyDrawable(_) => None, #[cfg(feature = "xf86dri")] Request::Xf86driGetDrawableInfo(_) => Some(xf86dri::GetDrawableInfoRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driGetDeviceInfo(_) => Some(xf86dri::GetDeviceInfoRequest::parse_reply), #[cfg(feature = "xf86dri")] Request::Xf86driAuthConnection(_) => Some(xf86dri::AuthConnectionRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeQueryVersion(_) => Some(xf86vidmode::QueryVersionRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetModeLine(_) => Some(xf86vidmode::GetModeLineRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeModModeLine(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSwitchMode(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetMonitor(_) => Some(xf86vidmode::GetMonitorRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeLockModeSwitch(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetAllModeLines(_) => Some(xf86vidmode::GetAllModeLinesRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeAddModeLine(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeDeleteModeLine(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeValidateModeLine(_) => Some(xf86vidmode::ValidateModeLineRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSwitchToMode(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetViewPort(_) => Some(xf86vidmode::GetViewPortRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetViewPort(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetDotClocks(_) => Some(xf86vidmode::GetDotClocksRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetClientVersion(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetGamma(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetGamma(_) => Some(xf86vidmode::GetGammaRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetGammaRamp(_) => Some(xf86vidmode::GetGammaRampRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetGammaRamp(_) => None, #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetGammaRampSize(_) => Some(xf86vidmode::GetGammaRampSizeRequest::parse_reply), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetPermissions(_) => Some(xf86vidmode::GetPermissionsRequest::parse_reply), #[cfg(feature = "xfixes")] Request::XfixesQueryVersion(_) => Some(xfixes::QueryVersionRequest::parse_reply), #[cfg(feature = "xfixes")] Request::XfixesChangeSaveSet(_) => None, #[cfg(feature = "xfixes")] Request::XfixesSelectSelectionInput(_) => None, #[cfg(feature = "xfixes")] Request::XfixesSelectCursorInput(_) => None, #[cfg(feature = "xfixes")] Request::XfixesGetCursorImage(_) => Some(xfixes::GetCursorImageRequest::parse_reply), #[cfg(feature = "xfixes")] Request::XfixesCreateRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromBitmap(_) => None, #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromWindow(_) => None, #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromGC(_) => None, #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromPicture(_) => None, #[cfg(feature = "xfixes")] Request::XfixesDestroyRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesSetRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesCopyRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesUnionRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesIntersectRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesSubtractRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesInvertRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesTranslateRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesRegionExtents(_) => None, #[cfg(feature = "xfixes")] Request::XfixesFetchRegion(_) => Some(xfixes::FetchRegionRequest::parse_reply), #[cfg(feature = "xfixes")] Request::XfixesSetGCClipRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesSetWindowShapeRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesSetPictureClipRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesSetCursorName(_) => None, #[cfg(feature = "xfixes")] Request::XfixesGetCursorName(_) => Some(xfixes::GetCursorNameRequest::parse_reply), #[cfg(feature = "xfixes")] Request::XfixesGetCursorImageAndName(_) => Some(xfixes::GetCursorImageAndNameRequest::parse_reply), #[cfg(feature = "xfixes")] Request::XfixesChangeCursor(_) => None, #[cfg(feature = "xfixes")] Request::XfixesChangeCursorByName(_) => None, #[cfg(feature = "xfixes")] Request::XfixesExpandRegion(_) => None, #[cfg(feature = "xfixes")] Request::XfixesHideCursor(_) => None, #[cfg(feature = "xfixes")] Request::XfixesShowCursor(_) => None, #[cfg(feature = "xfixes")] Request::XfixesCreatePointerBarrier(_) => None, #[cfg(feature = "xfixes")] Request::XfixesDeletePointerBarrier(_) => None, #[cfg(feature = "xinerama")] Request::XineramaQueryVersion(_) => Some(xinerama::QueryVersionRequest::parse_reply), #[cfg(feature = "xinerama")] Request::XineramaGetState(_) => Some(xinerama::GetStateRequest::parse_reply), #[cfg(feature = "xinerama")] Request::XineramaGetScreenCount(_) => Some(xinerama::GetScreenCountRequest::parse_reply), #[cfg(feature = "xinerama")] Request::XineramaGetScreenSize(_) => Some(xinerama::GetScreenSizeRequest::parse_reply), #[cfg(feature = "xinerama")] Request::XineramaIsActive(_) => Some(xinerama::IsActiveRequest::parse_reply), #[cfg(feature = "xinerama")] Request::XineramaQueryScreens(_) => Some(xinerama::QueryScreensRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputGetExtensionVersion(_) => Some(xinput::GetExtensionVersionRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputListInputDevices(_) => Some(xinput::ListInputDevicesRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputOpenDevice(_) => Some(xinput::OpenDeviceRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputCloseDevice(_) => None, #[cfg(feature = "xinput")] Request::XinputSetDeviceMode(_) => Some(xinput::SetDeviceModeRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputSelectExtensionEvent(_) => None, #[cfg(feature = "xinput")] Request::XinputGetSelectedExtensionEvents(_) => Some(xinput::GetSelectedExtensionEventsRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputChangeDeviceDontPropagateList(_) => None, #[cfg(feature = "xinput")] Request::XinputGetDeviceDontPropagateList(_) => Some(xinput::GetDeviceDontPropagateListRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputGetDeviceMotionEvents(_) => Some(xinput::GetDeviceMotionEventsRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputChangeKeyboardDevice(_) => Some(xinput::ChangeKeyboardDeviceRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputChangePointerDevice(_) => Some(xinput::ChangePointerDeviceRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputGrabDevice(_) => Some(xinput::GrabDeviceRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputUngrabDevice(_) => None, #[cfg(feature = "xinput")] Request::XinputGrabDeviceKey(_) => None, #[cfg(feature = "xinput")] Request::XinputUngrabDeviceKey(_) => None, #[cfg(feature = "xinput")] Request::XinputGrabDeviceButton(_) => None, #[cfg(feature = "xinput")] Request::XinputUngrabDeviceButton(_) => None, #[cfg(feature = "xinput")] Request::XinputAllowDeviceEvents(_) => None, #[cfg(feature = "xinput")] Request::XinputGetDeviceFocus(_) => Some(xinput::GetDeviceFocusRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputSetDeviceFocus(_) => None, #[cfg(feature = "xinput")] Request::XinputGetFeedbackControl(_) => Some(xinput::GetFeedbackControlRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputChangeFeedbackControl(_) => None, #[cfg(feature = "xinput")] Request::XinputGetDeviceKeyMapping(_) => Some(xinput::GetDeviceKeyMappingRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputChangeDeviceKeyMapping(_) => None, #[cfg(feature = "xinput")] Request::XinputGetDeviceModifierMapping(_) => Some(xinput::GetDeviceModifierMappingRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputSetDeviceModifierMapping(_) => Some(xinput::SetDeviceModifierMappingRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputGetDeviceButtonMapping(_) => Some(xinput::GetDeviceButtonMappingRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputSetDeviceButtonMapping(_) => Some(xinput::SetDeviceButtonMappingRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputQueryDeviceState(_) => Some(xinput::QueryDeviceStateRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputDeviceBell(_) => None, #[cfg(feature = "xinput")] Request::XinputSetDeviceValuators(_) => Some(xinput::SetDeviceValuatorsRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputGetDeviceControl(_) => Some(xinput::GetDeviceControlRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputChangeDeviceControl(_) => Some(xinput::ChangeDeviceControlRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputListDeviceProperties(_) => Some(xinput::ListDevicePropertiesRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputChangeDeviceProperty(_) => None, #[cfg(feature = "xinput")] Request::XinputDeleteDeviceProperty(_) => None, #[cfg(feature = "xinput")] Request::XinputGetDeviceProperty(_) => Some(xinput::GetDevicePropertyRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIQueryPointer(_) => Some(xinput::XIQueryPointerRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIWarpPointer(_) => None, #[cfg(feature = "xinput")] Request::XinputXIChangeCursor(_) => None, #[cfg(feature = "xinput")] Request::XinputXIChangeHierarchy(_) => None, #[cfg(feature = "xinput")] Request::XinputXISetClientPointer(_) => None, #[cfg(feature = "xinput")] Request::XinputXIGetClientPointer(_) => Some(xinput::XIGetClientPointerRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXISelectEvents(_) => None, #[cfg(feature = "xinput")] Request::XinputXIQueryVersion(_) => Some(xinput::XIQueryVersionRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIQueryDevice(_) => Some(xinput::XIQueryDeviceRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXISetFocus(_) => None, #[cfg(feature = "xinput")] Request::XinputXIGetFocus(_) => Some(xinput::XIGetFocusRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIGrabDevice(_) => Some(xinput::XIGrabDeviceRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIUngrabDevice(_) => None, #[cfg(feature = "xinput")] Request::XinputXIAllowEvents(_) => None, #[cfg(feature = "xinput")] Request::XinputXIPassiveGrabDevice(_) => Some(xinput::XIPassiveGrabDeviceRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIPassiveUngrabDevice(_) => None, #[cfg(feature = "xinput")] Request::XinputXIListProperties(_) => Some(xinput::XIListPropertiesRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIChangeProperty(_) => None, #[cfg(feature = "xinput")] Request::XinputXIDeleteProperty(_) => None, #[cfg(feature = "xinput")] Request::XinputXIGetProperty(_) => Some(xinput::XIGetPropertyRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIGetSelectedEvents(_) => Some(xinput::XIGetSelectedEventsRequest::parse_reply), #[cfg(feature = "xinput")] Request::XinputXIBarrierReleasePointer(_) => None, #[cfg(feature = "xinput")] Request::XinputSendExtensionEvent(_) => None, #[cfg(feature = "xkb")] Request::XkbUseExtension(_) => Some(xkb::UseExtensionRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSelectEvents(_) => None, #[cfg(feature = "xkb")] Request::XkbBell(_) => None, #[cfg(feature = "xkb")] Request::XkbGetState(_) => Some(xkb::GetStateRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbLatchLockState(_) => None, #[cfg(feature = "xkb")] Request::XkbGetControls(_) => Some(xkb::GetControlsRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSetControls(_) => None, #[cfg(feature = "xkb")] Request::XkbGetMap(_) => Some(xkb::GetMapRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSetMap(_) => None, #[cfg(feature = "xkb")] Request::XkbGetCompatMap(_) => Some(xkb::GetCompatMapRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSetCompatMap(_) => None, #[cfg(feature = "xkb")] Request::XkbGetIndicatorState(_) => Some(xkb::GetIndicatorStateRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbGetIndicatorMap(_) => Some(xkb::GetIndicatorMapRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSetIndicatorMap(_) => None, #[cfg(feature = "xkb")] Request::XkbGetNamedIndicator(_) => Some(xkb::GetNamedIndicatorRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSetNamedIndicator(_) => None, #[cfg(feature = "xkb")] Request::XkbGetNames(_) => Some(xkb::GetNamesRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSetNames(_) => None, #[cfg(feature = "xkb")] Request::XkbPerClientFlags(_) => Some(xkb::PerClientFlagsRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbListComponents(_) => Some(xkb::ListComponentsRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbGetKbdByName(_) => Some(xkb::GetKbdByNameRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbGetDeviceInfo(_) => Some(xkb::GetDeviceInfoRequest::parse_reply), #[cfg(feature = "xkb")] Request::XkbSetDeviceInfo(_) => None, #[cfg(feature = "xkb")] Request::XkbSetDebuggingFlags(_) => Some(xkb::SetDebuggingFlagsRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintQueryVersion(_) => Some(xprint::PrintQueryVersionRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintGetPrinterList(_) => Some(xprint::PrintGetPrinterListRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintRehashPrinterList(_) => None, #[cfg(feature = "xprint")] Request::XprintCreateContext(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintSetContext(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintGetContext(_) => Some(xprint::PrintGetContextRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintDestroyContext(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintGetScreenOfContext(_) => Some(xprint::PrintGetScreenOfContextRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintStartJob(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintEndJob(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintStartDoc(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintEndDoc(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintPutDocumentData(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintGetDocumentData(_) => Some(xprint::PrintGetDocumentDataRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintStartPage(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintEndPage(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintSelectInput(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintInputSelected(_) => Some(xprint::PrintInputSelectedRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintGetAttributes(_) => Some(xprint::PrintGetAttributesRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintGetOneAttributes(_) => Some(xprint::PrintGetOneAttributesRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintSetAttributes(_) => None, #[cfg(feature = "xprint")] Request::XprintPrintGetPageDimensions(_) => Some(xprint::PrintGetPageDimensionsRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintQueryScreens(_) => Some(xprint::PrintQueryScreensRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintSetImageResolution(_) => Some(xprint::PrintSetImageResolutionRequest::parse_reply), #[cfg(feature = "xprint")] Request::XprintPrintGetImageResolution(_) => Some(xprint::PrintGetImageResolutionRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxQueryVersion(_) => Some(xselinux::QueryVersionRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxSetDeviceCreateContext(_) => None, #[cfg(feature = "xselinux")] Request::XselinuxGetDeviceCreateContext(_) => Some(xselinux::GetDeviceCreateContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxSetDeviceContext(_) => None, #[cfg(feature = "xselinux")] Request::XselinuxGetDeviceContext(_) => Some(xselinux::GetDeviceContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxSetWindowCreateContext(_) => None, #[cfg(feature = "xselinux")] Request::XselinuxGetWindowCreateContext(_) => Some(xselinux::GetWindowCreateContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxGetWindowContext(_) => Some(xselinux::GetWindowContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxSetPropertyCreateContext(_) => None, #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyCreateContext(_) => Some(xselinux::GetPropertyCreateContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxSetPropertyUseContext(_) => None, #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyUseContext(_) => Some(xselinux::GetPropertyUseContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyContext(_) => Some(xselinux::GetPropertyContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyDataContext(_) => Some(xselinux::GetPropertyDataContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxListProperties(_) => Some(xselinux::ListPropertiesRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxSetSelectionCreateContext(_) => None, #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionCreateContext(_) => Some(xselinux::GetSelectionCreateContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxSetSelectionUseContext(_) => None, #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionUseContext(_) => Some(xselinux::GetSelectionUseContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionContext(_) => Some(xselinux::GetSelectionContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionDataContext(_) => Some(xselinux::GetSelectionDataContextRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxListSelections(_) => Some(xselinux::ListSelectionsRequest::parse_reply), #[cfg(feature = "xselinux")] Request::XselinuxGetClientContext(_) => Some(xselinux::GetClientContextRequest::parse_reply), #[cfg(feature = "xtest")] Request::XtestGetVersion(_) => Some(xtest::GetVersionRequest::parse_reply), #[cfg(feature = "xtest")] Request::XtestCompareCursor(_) => Some(xtest::CompareCursorRequest::parse_reply), #[cfg(feature = "xtest")] Request::XtestFakeInput(_) => None, #[cfg(feature = "xtest")] Request::XtestGrabControl(_) => None, #[cfg(feature = "xv")] Request::XvQueryExtension(_) => Some(xv::QueryExtensionRequest::parse_reply), #[cfg(feature = "xv")] Request::XvQueryAdaptors(_) => Some(xv::QueryAdaptorsRequest::parse_reply), #[cfg(feature = "xv")] Request::XvQueryEncodings(_) => Some(xv::QueryEncodingsRequest::parse_reply), #[cfg(feature = "xv")] Request::XvGrabPort(_) => Some(xv::GrabPortRequest::parse_reply), #[cfg(feature = "xv")] Request::XvUngrabPort(_) => None, #[cfg(feature = "xv")] Request::XvPutVideo(_) => None, #[cfg(feature = "xv")] Request::XvPutStill(_) => None, #[cfg(feature = "xv")] Request::XvGetVideo(_) => None, #[cfg(feature = "xv")] Request::XvGetStill(_) => None, #[cfg(feature = "xv")] Request::XvStopVideo(_) => None, #[cfg(feature = "xv")] Request::XvSelectVideoNotify(_) => None, #[cfg(feature = "xv")] Request::XvSelectPortNotify(_) => None, #[cfg(feature = "xv")] Request::XvQueryBestSize(_) => Some(xv::QueryBestSizeRequest::parse_reply), #[cfg(feature = "xv")] Request::XvSetPortAttribute(_) => None, #[cfg(feature = "xv")] Request::XvGetPortAttribute(_) => Some(xv::GetPortAttributeRequest::parse_reply), #[cfg(feature = "xv")] Request::XvQueryPortAttributes(_) => Some(xv::QueryPortAttributesRequest::parse_reply), #[cfg(feature = "xv")] Request::XvListImageFormats(_) => Some(xv::ListImageFormatsRequest::parse_reply), #[cfg(feature = "xv")] Request::XvQueryImageAttributes(_) => Some(xv::QueryImageAttributesRequest::parse_reply), #[cfg(feature = "xv")] Request::XvPutImage(_) => None, #[cfg(feature = "xv")] Request::XvShmPutImage(_) => None, #[cfg(feature = "xvmc")] Request::XvmcQueryVersion(_) => Some(xvmc::QueryVersionRequest::parse_reply), #[cfg(feature = "xvmc")] Request::XvmcListSurfaceTypes(_) => Some(xvmc::ListSurfaceTypesRequest::parse_reply), #[cfg(feature = "xvmc")] Request::XvmcCreateContext(_) => Some(xvmc::CreateContextRequest::parse_reply), #[cfg(feature = "xvmc")] Request::XvmcDestroyContext(_) => None, #[cfg(feature = "xvmc")] Request::XvmcCreateSurface(_) => Some(xvmc::CreateSurfaceRequest::parse_reply), #[cfg(feature = "xvmc")] Request::XvmcDestroySurface(_) => None, #[cfg(feature = "xvmc")] Request::XvmcCreateSubpicture(_) => Some(xvmc::CreateSubpictureRequest::parse_reply), #[cfg(feature = "xvmc")] Request::XvmcDestroySubpicture(_) => None, #[cfg(feature = "xvmc")] Request::XvmcListSubpictureTypes(_) => Some(xvmc::ListSubpictureTypesRequest::parse_reply), } } /// Convert this Request into an owned version with no borrows. pub fn into_owned(self) -> Request<'static> { match self { Request::Unknown(header, body) => Request::Unknown(header, Cow::Owned(body.into_owned())), Request::CreateWindow(req) => Request::CreateWindow(req.into_owned()), Request::ChangeWindowAttributes(req) => Request::ChangeWindowAttributes(req.into_owned()), Request::GetWindowAttributes(req) => Request::GetWindowAttributes(req), Request::DestroyWindow(req) => Request::DestroyWindow(req), Request::DestroySubwindows(req) => Request::DestroySubwindows(req), Request::ChangeSaveSet(req) => Request::ChangeSaveSet(req), Request::ReparentWindow(req) => Request::ReparentWindow(req), Request::MapWindow(req) => Request::MapWindow(req), Request::MapSubwindows(req) => Request::MapSubwindows(req), Request::UnmapWindow(req) => Request::UnmapWindow(req), Request::UnmapSubwindows(req) => Request::UnmapSubwindows(req), Request::ConfigureWindow(req) => Request::ConfigureWindow(req.into_owned()), Request::CirculateWindow(req) => Request::CirculateWindow(req), Request::GetGeometry(req) => Request::GetGeometry(req), Request::QueryTree(req) => Request::QueryTree(req), Request::InternAtom(req) => Request::InternAtom(req.into_owned()), Request::GetAtomName(req) => Request::GetAtomName(req), Request::ChangeProperty(req) => Request::ChangeProperty(req.into_owned()), Request::DeleteProperty(req) => Request::DeleteProperty(req), Request::GetProperty(req) => Request::GetProperty(req), Request::ListProperties(req) => Request::ListProperties(req), Request::SetSelectionOwner(req) => Request::SetSelectionOwner(req), Request::GetSelectionOwner(req) => Request::GetSelectionOwner(req), Request::ConvertSelection(req) => Request::ConvertSelection(req), Request::SendEvent(req) => Request::SendEvent(req.into_owned()), Request::GrabPointer(req) => Request::GrabPointer(req), Request::UngrabPointer(req) => Request::UngrabPointer(req), Request::GrabButton(req) => Request::GrabButton(req), Request::UngrabButton(req) => Request::UngrabButton(req), Request::ChangeActivePointerGrab(req) => Request::ChangeActivePointerGrab(req), Request::GrabKeyboard(req) => Request::GrabKeyboard(req), Request::UngrabKeyboard(req) => Request::UngrabKeyboard(req), Request::GrabKey(req) => Request::GrabKey(req), Request::UngrabKey(req) => Request::UngrabKey(req), Request::AllowEvents(req) => Request::AllowEvents(req), Request::GrabServer(req) => Request::GrabServer(req), Request::UngrabServer(req) => Request::UngrabServer(req), Request::QueryPointer(req) => Request::QueryPointer(req), Request::GetMotionEvents(req) => Request::GetMotionEvents(req), Request::TranslateCoordinates(req) => Request::TranslateCoordinates(req), Request::WarpPointer(req) => Request::WarpPointer(req), Request::SetInputFocus(req) => Request::SetInputFocus(req), Request::GetInputFocus(req) => Request::GetInputFocus(req), Request::QueryKeymap(req) => Request::QueryKeymap(req), Request::OpenFont(req) => Request::OpenFont(req.into_owned()), Request::CloseFont(req) => Request::CloseFont(req), Request::QueryFont(req) => Request::QueryFont(req), Request::QueryTextExtents(req) => Request::QueryTextExtents(req.into_owned()), Request::ListFonts(req) => Request::ListFonts(req.into_owned()), Request::ListFontsWithInfo(req) => Request::ListFontsWithInfo(req.into_owned()), Request::SetFontPath(req) => Request::SetFontPath(req.into_owned()), Request::GetFontPath(req) => Request::GetFontPath(req), Request::CreatePixmap(req) => Request::CreatePixmap(req), Request::FreePixmap(req) => Request::FreePixmap(req), Request::CreateGC(req) => Request::CreateGC(req.into_owned()), Request::ChangeGC(req) => Request::ChangeGC(req.into_owned()), Request::CopyGC(req) => Request::CopyGC(req), Request::SetDashes(req) => Request::SetDashes(req.into_owned()), Request::SetClipRectangles(req) => Request::SetClipRectangles(req.into_owned()), Request::FreeGC(req) => Request::FreeGC(req), Request::ClearArea(req) => Request::ClearArea(req), Request::CopyArea(req) => Request::CopyArea(req), Request::CopyPlane(req) => Request::CopyPlane(req), Request::PolyPoint(req) => Request::PolyPoint(req.into_owned()), Request::PolyLine(req) => Request::PolyLine(req.into_owned()), Request::PolySegment(req) => Request::PolySegment(req.into_owned()), Request::PolyRectangle(req) => Request::PolyRectangle(req.into_owned()), Request::PolyArc(req) => Request::PolyArc(req.into_owned()), Request::FillPoly(req) => Request::FillPoly(req.into_owned()), Request::PolyFillRectangle(req) => Request::PolyFillRectangle(req.into_owned()), Request::PolyFillArc(req) => Request::PolyFillArc(req.into_owned()), Request::PutImage(req) => Request::PutImage(req.into_owned()), Request::GetImage(req) => Request::GetImage(req), Request::PolyText8(req) => Request::PolyText8(req.into_owned()), Request::PolyText16(req) => Request::PolyText16(req.into_owned()), Request::ImageText8(req) => Request::ImageText8(req.into_owned()), Request::ImageText16(req) => Request::ImageText16(req.into_owned()), Request::CreateColormap(req) => Request::CreateColormap(req), Request::FreeColormap(req) => Request::FreeColormap(req), Request::CopyColormapAndFree(req) => Request::CopyColormapAndFree(req), Request::InstallColormap(req) => Request::InstallColormap(req), Request::UninstallColormap(req) => Request::UninstallColormap(req), Request::ListInstalledColormaps(req) => Request::ListInstalledColormaps(req), Request::AllocColor(req) => Request::AllocColor(req), Request::AllocNamedColor(req) => Request::AllocNamedColor(req.into_owned()), Request::AllocColorCells(req) => Request::AllocColorCells(req), Request::AllocColorPlanes(req) => Request::AllocColorPlanes(req), Request::FreeColors(req) => Request::FreeColors(req.into_owned()), Request::StoreColors(req) => Request::StoreColors(req.into_owned()), Request::StoreNamedColor(req) => Request::StoreNamedColor(req.into_owned()), Request::QueryColors(req) => Request::QueryColors(req.into_owned()), Request::LookupColor(req) => Request::LookupColor(req.into_owned()), Request::CreateCursor(req) => Request::CreateCursor(req), Request::CreateGlyphCursor(req) => Request::CreateGlyphCursor(req), Request::FreeCursor(req) => Request::FreeCursor(req), Request::RecolorCursor(req) => Request::RecolorCursor(req), Request::QueryBestSize(req) => Request::QueryBestSize(req), Request::QueryExtension(req) => Request::QueryExtension(req.into_owned()), Request::ListExtensions(req) => Request::ListExtensions(req), Request::ChangeKeyboardMapping(req) => Request::ChangeKeyboardMapping(req.into_owned()), Request::GetKeyboardMapping(req) => Request::GetKeyboardMapping(req), Request::ChangeKeyboardControl(req) => Request::ChangeKeyboardControl(req.into_owned()), Request::GetKeyboardControl(req) => Request::GetKeyboardControl(req), Request::Bell(req) => Request::Bell(req), Request::ChangePointerControl(req) => Request::ChangePointerControl(req), Request::GetPointerControl(req) => Request::GetPointerControl(req), Request::SetScreenSaver(req) => Request::SetScreenSaver(req), Request::GetScreenSaver(req) => Request::GetScreenSaver(req), Request::ChangeHosts(req) => Request::ChangeHosts(req.into_owned()), Request::ListHosts(req) => Request::ListHosts(req), Request::SetAccessControl(req) => Request::SetAccessControl(req), Request::SetCloseDownMode(req) => Request::SetCloseDownMode(req), Request::KillClient(req) => Request::KillClient(req), Request::RotateProperties(req) => Request::RotateProperties(req.into_owned()), Request::ForceScreenSaver(req) => Request::ForceScreenSaver(req), Request::SetPointerMapping(req) => Request::SetPointerMapping(req.into_owned()), Request::GetPointerMapping(req) => Request::GetPointerMapping(req), Request::SetModifierMapping(req) => Request::SetModifierMapping(req.into_owned()), Request::GetModifierMapping(req) => Request::GetModifierMapping(req), Request::NoOperation(req) => Request::NoOperation(req), Request::BigreqEnable(req) => Request::BigreqEnable(req), #[cfg(feature = "composite")] Request::CompositeQueryVersion(req) => Request::CompositeQueryVersion(req), #[cfg(feature = "composite")] Request::CompositeRedirectWindow(req) => Request::CompositeRedirectWindow(req), #[cfg(feature = "composite")] Request::CompositeRedirectSubwindows(req) => Request::CompositeRedirectSubwindows(req), #[cfg(feature = "composite")] Request::CompositeUnredirectWindow(req) => Request::CompositeUnredirectWindow(req), #[cfg(feature = "composite")] Request::CompositeUnredirectSubwindows(req) => Request::CompositeUnredirectSubwindows(req), #[cfg(feature = "composite")] Request::CompositeCreateRegionFromBorderClip(req) => Request::CompositeCreateRegionFromBorderClip(req), #[cfg(feature = "composite")] Request::CompositeNameWindowPixmap(req) => Request::CompositeNameWindowPixmap(req), #[cfg(feature = "composite")] Request::CompositeGetOverlayWindow(req) => Request::CompositeGetOverlayWindow(req), #[cfg(feature = "composite")] Request::CompositeReleaseOverlayWindow(req) => Request::CompositeReleaseOverlayWindow(req), #[cfg(feature = "damage")] Request::DamageQueryVersion(req) => Request::DamageQueryVersion(req), #[cfg(feature = "damage")] Request::DamageCreate(req) => Request::DamageCreate(req), #[cfg(feature = "damage")] Request::DamageDestroy(req) => Request::DamageDestroy(req), #[cfg(feature = "damage")] Request::DamageSubtract(req) => Request::DamageSubtract(req), #[cfg(feature = "damage")] Request::DamageAdd(req) => Request::DamageAdd(req), #[cfg(feature = "dpms")] Request::DpmsGetVersion(req) => Request::DpmsGetVersion(req), #[cfg(feature = "dpms")] Request::DpmsCapable(req) => Request::DpmsCapable(req), #[cfg(feature = "dpms")] Request::DpmsGetTimeouts(req) => Request::DpmsGetTimeouts(req), #[cfg(feature = "dpms")] Request::DpmsSetTimeouts(req) => Request::DpmsSetTimeouts(req), #[cfg(feature = "dpms")] Request::DpmsEnable(req) => Request::DpmsEnable(req), #[cfg(feature = "dpms")] Request::DpmsDisable(req) => Request::DpmsDisable(req), #[cfg(feature = "dpms")] Request::DpmsForceLevel(req) => Request::DpmsForceLevel(req), #[cfg(feature = "dpms")] Request::DpmsInfo(req) => Request::DpmsInfo(req), #[cfg(feature = "dri2")] Request::Dri2QueryVersion(req) => Request::Dri2QueryVersion(req), #[cfg(feature = "dri2")] Request::Dri2Connect(req) => Request::Dri2Connect(req), #[cfg(feature = "dri2")] Request::Dri2Authenticate(req) => Request::Dri2Authenticate(req), #[cfg(feature = "dri2")] Request::Dri2CreateDrawable(req) => Request::Dri2CreateDrawable(req), #[cfg(feature = "dri2")] Request::Dri2DestroyDrawable(req) => Request::Dri2DestroyDrawable(req), #[cfg(feature = "dri2")] Request::Dri2GetBuffers(req) => Request::Dri2GetBuffers(req.into_owned()), #[cfg(feature = "dri2")] Request::Dri2CopyRegion(req) => Request::Dri2CopyRegion(req), #[cfg(feature = "dri2")] Request::Dri2GetBuffersWithFormat(req) => Request::Dri2GetBuffersWithFormat(req.into_owned()), #[cfg(feature = "dri2")] Request::Dri2SwapBuffers(req) => Request::Dri2SwapBuffers(req), #[cfg(feature = "dri2")] Request::Dri2GetMSC(req) => Request::Dri2GetMSC(req), #[cfg(feature = "dri2")] Request::Dri2WaitMSC(req) => Request::Dri2WaitMSC(req), #[cfg(feature = "dri2")] Request::Dri2WaitSBC(req) => Request::Dri2WaitSBC(req), #[cfg(feature = "dri2")] Request::Dri2SwapInterval(req) => Request::Dri2SwapInterval(req), #[cfg(feature = "dri2")] Request::Dri2GetParam(req) => Request::Dri2GetParam(req), #[cfg(feature = "dri3")] Request::Dri3QueryVersion(req) => Request::Dri3QueryVersion(req), #[cfg(feature = "dri3")] Request::Dri3Open(req) => Request::Dri3Open(req), #[cfg(feature = "dri3")] Request::Dri3PixmapFromBuffer(req) => Request::Dri3PixmapFromBuffer(req), #[cfg(feature = "dri3")] Request::Dri3BufferFromPixmap(req) => Request::Dri3BufferFromPixmap(req), #[cfg(feature = "dri3")] Request::Dri3FenceFromFD(req) => Request::Dri3FenceFromFD(req), #[cfg(feature = "dri3")] Request::Dri3FDFromFence(req) => Request::Dri3FDFromFence(req), #[cfg(feature = "dri3")] Request::Dri3GetSupportedModifiers(req) => Request::Dri3GetSupportedModifiers(req), #[cfg(feature = "dri3")] Request::Dri3PixmapFromBuffers(req) => Request::Dri3PixmapFromBuffers(req), #[cfg(feature = "dri3")] Request::Dri3BuffersFromPixmap(req) => Request::Dri3BuffersFromPixmap(req), Request::GeQueryVersion(req) => Request::GeQueryVersion(req), #[cfg(feature = "glx")] Request::GlxRender(req) => Request::GlxRender(req.into_owned()), #[cfg(feature = "glx")] Request::GlxRenderLarge(req) => Request::GlxRenderLarge(req.into_owned()), #[cfg(feature = "glx")] Request::GlxCreateContext(req) => Request::GlxCreateContext(req), #[cfg(feature = "glx")] Request::GlxDestroyContext(req) => Request::GlxDestroyContext(req), #[cfg(feature = "glx")] Request::GlxMakeCurrent(req) => Request::GlxMakeCurrent(req), #[cfg(feature = "glx")] Request::GlxIsDirect(req) => Request::GlxIsDirect(req), #[cfg(feature = "glx")] Request::GlxQueryVersion(req) => Request::GlxQueryVersion(req), #[cfg(feature = "glx")] Request::GlxWaitGL(req) => Request::GlxWaitGL(req), #[cfg(feature = "glx")] Request::GlxWaitX(req) => Request::GlxWaitX(req), #[cfg(feature = "glx")] Request::GlxCopyContext(req) => Request::GlxCopyContext(req), #[cfg(feature = "glx")] Request::GlxSwapBuffers(req) => Request::GlxSwapBuffers(req), #[cfg(feature = "glx")] Request::GlxUseXFont(req) => Request::GlxUseXFont(req), #[cfg(feature = "glx")] Request::GlxCreateGLXPixmap(req) => Request::GlxCreateGLXPixmap(req), #[cfg(feature = "glx")] Request::GlxGetVisualConfigs(req) => Request::GlxGetVisualConfigs(req), #[cfg(feature = "glx")] Request::GlxDestroyGLXPixmap(req) => Request::GlxDestroyGLXPixmap(req), #[cfg(feature = "glx")] Request::GlxVendorPrivate(req) => Request::GlxVendorPrivate(req.into_owned()), #[cfg(feature = "glx")] Request::GlxVendorPrivateWithReply(req) => Request::GlxVendorPrivateWithReply(req.into_owned()), #[cfg(feature = "glx")] Request::GlxQueryExtensionsString(req) => Request::GlxQueryExtensionsString(req), #[cfg(feature = "glx")] Request::GlxQueryServerString(req) => Request::GlxQueryServerString(req), #[cfg(feature = "glx")] Request::GlxClientInfo(req) => Request::GlxClientInfo(req.into_owned()), #[cfg(feature = "glx")] Request::GlxGetFBConfigs(req) => Request::GlxGetFBConfigs(req), #[cfg(feature = "glx")] Request::GlxCreatePixmap(req) => Request::GlxCreatePixmap(req.into_owned()), #[cfg(feature = "glx")] Request::GlxDestroyPixmap(req) => Request::GlxDestroyPixmap(req), #[cfg(feature = "glx")] Request::GlxCreateNewContext(req) => Request::GlxCreateNewContext(req), #[cfg(feature = "glx")] Request::GlxQueryContext(req) => Request::GlxQueryContext(req), #[cfg(feature = "glx")] Request::GlxMakeContextCurrent(req) => Request::GlxMakeContextCurrent(req), #[cfg(feature = "glx")] Request::GlxCreatePbuffer(req) => Request::GlxCreatePbuffer(req.into_owned()), #[cfg(feature = "glx")] Request::GlxDestroyPbuffer(req) => Request::GlxDestroyPbuffer(req), #[cfg(feature = "glx")] Request::GlxGetDrawableAttributes(req) => Request::GlxGetDrawableAttributes(req), #[cfg(feature = "glx")] Request::GlxChangeDrawableAttributes(req) => Request::GlxChangeDrawableAttributes(req.into_owned()), #[cfg(feature = "glx")] Request::GlxCreateWindow(req) => Request::GlxCreateWindow(req.into_owned()), #[cfg(feature = "glx")] Request::GlxDeleteWindow(req) => Request::GlxDeleteWindow(req), #[cfg(feature = "glx")] Request::GlxSetClientInfoARB(req) => Request::GlxSetClientInfoARB(req.into_owned()), #[cfg(feature = "glx")] Request::GlxCreateContextAttribsARB(req) => Request::GlxCreateContextAttribsARB(req.into_owned()), #[cfg(feature = "glx")] Request::GlxSetClientInfo2ARB(req) => Request::GlxSetClientInfo2ARB(req.into_owned()), #[cfg(feature = "glx")] Request::GlxNewList(req) => Request::GlxNewList(req), #[cfg(feature = "glx")] Request::GlxEndList(req) => Request::GlxEndList(req), #[cfg(feature = "glx")] Request::GlxDeleteLists(req) => Request::GlxDeleteLists(req), #[cfg(feature = "glx")] Request::GlxGenLists(req) => Request::GlxGenLists(req), #[cfg(feature = "glx")] Request::GlxFeedbackBuffer(req) => Request::GlxFeedbackBuffer(req), #[cfg(feature = "glx")] Request::GlxSelectBuffer(req) => Request::GlxSelectBuffer(req), #[cfg(feature = "glx")] Request::GlxRenderMode(req) => Request::GlxRenderMode(req), #[cfg(feature = "glx")] Request::GlxFinish(req) => Request::GlxFinish(req), #[cfg(feature = "glx")] Request::GlxPixelStoref(req) => Request::GlxPixelStoref(req), #[cfg(feature = "glx")] Request::GlxPixelStorei(req) => Request::GlxPixelStorei(req), #[cfg(feature = "glx")] Request::GlxReadPixels(req) => Request::GlxReadPixels(req), #[cfg(feature = "glx")] Request::GlxGetBooleanv(req) => Request::GlxGetBooleanv(req), #[cfg(feature = "glx")] Request::GlxGetClipPlane(req) => Request::GlxGetClipPlane(req), #[cfg(feature = "glx")] Request::GlxGetDoublev(req) => Request::GlxGetDoublev(req), #[cfg(feature = "glx")] Request::GlxGetError(req) => Request::GlxGetError(req), #[cfg(feature = "glx")] Request::GlxGetFloatv(req) => Request::GlxGetFloatv(req), #[cfg(feature = "glx")] Request::GlxGetIntegerv(req) => Request::GlxGetIntegerv(req), #[cfg(feature = "glx")] Request::GlxGetLightfv(req) => Request::GlxGetLightfv(req), #[cfg(feature = "glx")] Request::GlxGetLightiv(req) => Request::GlxGetLightiv(req), #[cfg(feature = "glx")] Request::GlxGetMapdv(req) => Request::GlxGetMapdv(req), #[cfg(feature = "glx")] Request::GlxGetMapfv(req) => Request::GlxGetMapfv(req), #[cfg(feature = "glx")] Request::GlxGetMapiv(req) => Request::GlxGetMapiv(req), #[cfg(feature = "glx")] Request::GlxGetMaterialfv(req) => Request::GlxGetMaterialfv(req), #[cfg(feature = "glx")] Request::GlxGetMaterialiv(req) => Request::GlxGetMaterialiv(req), #[cfg(feature = "glx")] Request::GlxGetPixelMapfv(req) => Request::GlxGetPixelMapfv(req), #[cfg(feature = "glx")] Request::GlxGetPixelMapuiv(req) => Request::GlxGetPixelMapuiv(req), #[cfg(feature = "glx")] Request::GlxGetPixelMapusv(req) => Request::GlxGetPixelMapusv(req), #[cfg(feature = "glx")] Request::GlxGetPolygonStipple(req) => Request::GlxGetPolygonStipple(req), #[cfg(feature = "glx")] Request::GlxGetString(req) => Request::GlxGetString(req), #[cfg(feature = "glx")] Request::GlxGetTexEnvfv(req) => Request::GlxGetTexEnvfv(req), #[cfg(feature = "glx")] Request::GlxGetTexEnviv(req) => Request::GlxGetTexEnviv(req), #[cfg(feature = "glx")] Request::GlxGetTexGendv(req) => Request::GlxGetTexGendv(req), #[cfg(feature = "glx")] Request::GlxGetTexGenfv(req) => Request::GlxGetTexGenfv(req), #[cfg(feature = "glx")] Request::GlxGetTexGeniv(req) => Request::GlxGetTexGeniv(req), #[cfg(feature = "glx")] Request::GlxGetTexImage(req) => Request::GlxGetTexImage(req), #[cfg(feature = "glx")] Request::GlxGetTexParameterfv(req) => Request::GlxGetTexParameterfv(req), #[cfg(feature = "glx")] Request::GlxGetTexParameteriv(req) => Request::GlxGetTexParameteriv(req), #[cfg(feature = "glx")] Request::GlxGetTexLevelParameterfv(req) => Request::GlxGetTexLevelParameterfv(req), #[cfg(feature = "glx")] Request::GlxGetTexLevelParameteriv(req) => Request::GlxGetTexLevelParameteriv(req), #[cfg(feature = "glx")] Request::GlxIsEnabled(req) => Request::GlxIsEnabled(req), #[cfg(feature = "glx")] Request::GlxIsList(req) => Request::GlxIsList(req), #[cfg(feature = "glx")] Request::GlxFlush(req) => Request::GlxFlush(req), #[cfg(feature = "glx")] Request::GlxAreTexturesResident(req) => Request::GlxAreTexturesResident(req.into_owned()), #[cfg(feature = "glx")] Request::GlxDeleteTextures(req) => Request::GlxDeleteTextures(req.into_owned()), #[cfg(feature = "glx")] Request::GlxGenTextures(req) => Request::GlxGenTextures(req), #[cfg(feature = "glx")] Request::GlxIsTexture(req) => Request::GlxIsTexture(req), #[cfg(feature = "glx")] Request::GlxGetColorTable(req) => Request::GlxGetColorTable(req), #[cfg(feature = "glx")] Request::GlxGetColorTableParameterfv(req) => Request::GlxGetColorTableParameterfv(req), #[cfg(feature = "glx")] Request::GlxGetColorTableParameteriv(req) => Request::GlxGetColorTableParameteriv(req), #[cfg(feature = "glx")] Request::GlxGetConvolutionFilter(req) => Request::GlxGetConvolutionFilter(req), #[cfg(feature = "glx")] Request::GlxGetConvolutionParameterfv(req) => Request::GlxGetConvolutionParameterfv(req), #[cfg(feature = "glx")] Request::GlxGetConvolutionParameteriv(req) => Request::GlxGetConvolutionParameteriv(req), #[cfg(feature = "glx")] Request::GlxGetSeparableFilter(req) => Request::GlxGetSeparableFilter(req), #[cfg(feature = "glx")] Request::GlxGetHistogram(req) => Request::GlxGetHistogram(req), #[cfg(feature = "glx")] Request::GlxGetHistogramParameterfv(req) => Request::GlxGetHistogramParameterfv(req), #[cfg(feature = "glx")] Request::GlxGetHistogramParameteriv(req) => Request::GlxGetHistogramParameteriv(req), #[cfg(feature = "glx")] Request::GlxGetMinmax(req) => Request::GlxGetMinmax(req), #[cfg(feature = "glx")] Request::GlxGetMinmaxParameterfv(req) => Request::GlxGetMinmaxParameterfv(req), #[cfg(feature = "glx")] Request::GlxGetMinmaxParameteriv(req) => Request::GlxGetMinmaxParameteriv(req), #[cfg(feature = "glx")] Request::GlxGetCompressedTexImageARB(req) => Request::GlxGetCompressedTexImageARB(req), #[cfg(feature = "glx")] Request::GlxDeleteQueriesARB(req) => Request::GlxDeleteQueriesARB(req.into_owned()), #[cfg(feature = "glx")] Request::GlxGenQueriesARB(req) => Request::GlxGenQueriesARB(req), #[cfg(feature = "glx")] Request::GlxIsQueryARB(req) => Request::GlxIsQueryARB(req), #[cfg(feature = "glx")] Request::GlxGetQueryivARB(req) => Request::GlxGetQueryivARB(req), #[cfg(feature = "glx")] Request::GlxGetQueryObjectivARB(req) => Request::GlxGetQueryObjectivARB(req), #[cfg(feature = "glx")] Request::GlxGetQueryObjectuivARB(req) => Request::GlxGetQueryObjectuivARB(req), #[cfg(feature = "present")] Request::PresentQueryVersion(req) => Request::PresentQueryVersion(req), #[cfg(feature = "present")] Request::PresentPixmap(req) => Request::PresentPixmap(req.into_owned()), #[cfg(feature = "present")] Request::PresentNotifyMSC(req) => Request::PresentNotifyMSC(req), #[cfg(feature = "present")] Request::PresentSelectInput(req) => Request::PresentSelectInput(req), #[cfg(feature = "present")] Request::PresentQueryCapabilities(req) => Request::PresentQueryCapabilities(req), #[cfg(feature = "randr")] Request::RandrQueryVersion(req) => Request::RandrQueryVersion(req), #[cfg(feature = "randr")] Request::RandrSetScreenConfig(req) => Request::RandrSetScreenConfig(req), #[cfg(feature = "randr")] Request::RandrSelectInput(req) => Request::RandrSelectInput(req), #[cfg(feature = "randr")] Request::RandrGetScreenInfo(req) => Request::RandrGetScreenInfo(req), #[cfg(feature = "randr")] Request::RandrGetScreenSizeRange(req) => Request::RandrGetScreenSizeRange(req), #[cfg(feature = "randr")] Request::RandrSetScreenSize(req) => Request::RandrSetScreenSize(req), #[cfg(feature = "randr")] Request::RandrGetScreenResources(req) => Request::RandrGetScreenResources(req), #[cfg(feature = "randr")] Request::RandrGetOutputInfo(req) => Request::RandrGetOutputInfo(req), #[cfg(feature = "randr")] Request::RandrListOutputProperties(req) => Request::RandrListOutputProperties(req), #[cfg(feature = "randr")] Request::RandrQueryOutputProperty(req) => Request::RandrQueryOutputProperty(req), #[cfg(feature = "randr")] Request::RandrConfigureOutputProperty(req) => Request::RandrConfigureOutputProperty(req.into_owned()), #[cfg(feature = "randr")] Request::RandrChangeOutputProperty(req) => Request::RandrChangeOutputProperty(req.into_owned()), #[cfg(feature = "randr")] Request::RandrDeleteOutputProperty(req) => Request::RandrDeleteOutputProperty(req), #[cfg(feature = "randr")] Request::RandrGetOutputProperty(req) => Request::RandrGetOutputProperty(req), #[cfg(feature = "randr")] Request::RandrCreateMode(req) => Request::RandrCreateMode(req.into_owned()), #[cfg(feature = "randr")] Request::RandrDestroyMode(req) => Request::RandrDestroyMode(req), #[cfg(feature = "randr")] Request::RandrAddOutputMode(req) => Request::RandrAddOutputMode(req), #[cfg(feature = "randr")] Request::RandrDeleteOutputMode(req) => Request::RandrDeleteOutputMode(req), #[cfg(feature = "randr")] Request::RandrGetCrtcInfo(req) => Request::RandrGetCrtcInfo(req), #[cfg(feature = "randr")] Request::RandrSetCrtcConfig(req) => Request::RandrSetCrtcConfig(req.into_owned()), #[cfg(feature = "randr")] Request::RandrGetCrtcGammaSize(req) => Request::RandrGetCrtcGammaSize(req), #[cfg(feature = "randr")] Request::RandrGetCrtcGamma(req) => Request::RandrGetCrtcGamma(req), #[cfg(feature = "randr")] Request::RandrSetCrtcGamma(req) => Request::RandrSetCrtcGamma(req.into_owned()), #[cfg(feature = "randr")] Request::RandrGetScreenResourcesCurrent(req) => Request::RandrGetScreenResourcesCurrent(req), #[cfg(feature = "randr")] Request::RandrSetCrtcTransform(req) => Request::RandrSetCrtcTransform(req.into_owned()), #[cfg(feature = "randr")] Request::RandrGetCrtcTransform(req) => Request::RandrGetCrtcTransform(req), #[cfg(feature = "randr")] Request::RandrGetPanning(req) => Request::RandrGetPanning(req), #[cfg(feature = "randr")] Request::RandrSetPanning(req) => Request::RandrSetPanning(req), #[cfg(feature = "randr")] Request::RandrSetOutputPrimary(req) => Request::RandrSetOutputPrimary(req), #[cfg(feature = "randr")] Request::RandrGetOutputPrimary(req) => Request::RandrGetOutputPrimary(req), #[cfg(feature = "randr")] Request::RandrGetProviders(req) => Request::RandrGetProviders(req), #[cfg(feature = "randr")] Request::RandrGetProviderInfo(req) => Request::RandrGetProviderInfo(req), #[cfg(feature = "randr")] Request::RandrSetProviderOffloadSink(req) => Request::RandrSetProviderOffloadSink(req), #[cfg(feature = "randr")] Request::RandrSetProviderOutputSource(req) => Request::RandrSetProviderOutputSource(req), #[cfg(feature = "randr")] Request::RandrListProviderProperties(req) => Request::RandrListProviderProperties(req), #[cfg(feature = "randr")] Request::RandrQueryProviderProperty(req) => Request::RandrQueryProviderProperty(req), #[cfg(feature = "randr")] Request::RandrConfigureProviderProperty(req) => Request::RandrConfigureProviderProperty(req.into_owned()), #[cfg(feature = "randr")] Request::RandrChangeProviderProperty(req) => Request::RandrChangeProviderProperty(req.into_owned()), #[cfg(feature = "randr")] Request::RandrDeleteProviderProperty(req) => Request::RandrDeleteProviderProperty(req), #[cfg(feature = "randr")] Request::RandrGetProviderProperty(req) => Request::RandrGetProviderProperty(req), #[cfg(feature = "randr")] Request::RandrGetMonitors(req) => Request::RandrGetMonitors(req), #[cfg(feature = "randr")] Request::RandrSetMonitor(req) => Request::RandrSetMonitor(req), #[cfg(feature = "randr")] Request::RandrDeleteMonitor(req) => Request::RandrDeleteMonitor(req), #[cfg(feature = "randr")] Request::RandrCreateLease(req) => Request::RandrCreateLease(req.into_owned()), #[cfg(feature = "randr")] Request::RandrFreeLease(req) => Request::RandrFreeLease(req), #[cfg(feature = "record")] Request::RecordQueryVersion(req) => Request::RecordQueryVersion(req), #[cfg(feature = "record")] Request::RecordCreateContext(req) => Request::RecordCreateContext(req.into_owned()), #[cfg(feature = "record")] Request::RecordRegisterClients(req) => Request::RecordRegisterClients(req.into_owned()), #[cfg(feature = "record")] Request::RecordUnregisterClients(req) => Request::RecordUnregisterClients(req.into_owned()), #[cfg(feature = "record")] Request::RecordGetContext(req) => Request::RecordGetContext(req), #[cfg(feature = "record")] Request::RecordEnableContext(req) => Request::RecordEnableContext(req), #[cfg(feature = "record")] Request::RecordDisableContext(req) => Request::RecordDisableContext(req), #[cfg(feature = "record")] Request::RecordFreeContext(req) => Request::RecordFreeContext(req), #[cfg(feature = "render")] Request::RenderQueryVersion(req) => Request::RenderQueryVersion(req), #[cfg(feature = "render")] Request::RenderQueryPictFormats(req) => Request::RenderQueryPictFormats(req), #[cfg(feature = "render")] Request::RenderQueryPictIndexValues(req) => Request::RenderQueryPictIndexValues(req), #[cfg(feature = "render")] Request::RenderCreatePicture(req) => Request::RenderCreatePicture(req.into_owned()), #[cfg(feature = "render")] Request::RenderChangePicture(req) => Request::RenderChangePicture(req.into_owned()), #[cfg(feature = "render")] Request::RenderSetPictureClipRectangles(req) => Request::RenderSetPictureClipRectangles(req.into_owned()), #[cfg(feature = "render")] Request::RenderFreePicture(req) => Request::RenderFreePicture(req), #[cfg(feature = "render")] Request::RenderComposite(req) => Request::RenderComposite(req), #[cfg(feature = "render")] Request::RenderTrapezoids(req) => Request::RenderTrapezoids(req.into_owned()), #[cfg(feature = "render")] Request::RenderTriangles(req) => Request::RenderTriangles(req.into_owned()), #[cfg(feature = "render")] Request::RenderTriStrip(req) => Request::RenderTriStrip(req.into_owned()), #[cfg(feature = "render")] Request::RenderTriFan(req) => Request::RenderTriFan(req.into_owned()), #[cfg(feature = "render")] Request::RenderCreateGlyphSet(req) => Request::RenderCreateGlyphSet(req), #[cfg(feature = "render")] Request::RenderReferenceGlyphSet(req) => Request::RenderReferenceGlyphSet(req), #[cfg(feature = "render")] Request::RenderFreeGlyphSet(req) => Request::RenderFreeGlyphSet(req), #[cfg(feature = "render")] Request::RenderAddGlyphs(req) => Request::RenderAddGlyphs(req.into_owned()), #[cfg(feature = "render")] Request::RenderFreeGlyphs(req) => Request::RenderFreeGlyphs(req.into_owned()), #[cfg(feature = "render")] Request::RenderCompositeGlyphs8(req) => Request::RenderCompositeGlyphs8(req.into_owned()), #[cfg(feature = "render")] Request::RenderCompositeGlyphs16(req) => Request::RenderCompositeGlyphs16(req.into_owned()), #[cfg(feature = "render")] Request::RenderCompositeGlyphs32(req) => Request::RenderCompositeGlyphs32(req.into_owned()), #[cfg(feature = "render")] Request::RenderFillRectangles(req) => Request::RenderFillRectangles(req.into_owned()), #[cfg(feature = "render")] Request::RenderCreateCursor(req) => Request::RenderCreateCursor(req), #[cfg(feature = "render")] Request::RenderSetPictureTransform(req) => Request::RenderSetPictureTransform(req), #[cfg(feature = "render")] Request::RenderQueryFilters(req) => Request::RenderQueryFilters(req), #[cfg(feature = "render")] Request::RenderSetPictureFilter(req) => Request::RenderSetPictureFilter(req.into_owned()), #[cfg(feature = "render")] Request::RenderCreateAnimCursor(req) => Request::RenderCreateAnimCursor(req.into_owned()), #[cfg(feature = "render")] Request::RenderAddTraps(req) => Request::RenderAddTraps(req.into_owned()), #[cfg(feature = "render")] Request::RenderCreateSolidFill(req) => Request::RenderCreateSolidFill(req), #[cfg(feature = "render")] Request::RenderCreateLinearGradient(req) => Request::RenderCreateLinearGradient(req.into_owned()), #[cfg(feature = "render")] Request::RenderCreateRadialGradient(req) => Request::RenderCreateRadialGradient(req.into_owned()), #[cfg(feature = "render")] Request::RenderCreateConicalGradient(req) => Request::RenderCreateConicalGradient(req.into_owned()), #[cfg(feature = "res")] Request::ResQueryVersion(req) => Request::ResQueryVersion(req), #[cfg(feature = "res")] Request::ResQueryClients(req) => Request::ResQueryClients(req), #[cfg(feature = "res")] Request::ResQueryClientResources(req) => Request::ResQueryClientResources(req), #[cfg(feature = "res")] Request::ResQueryClientPixmapBytes(req) => Request::ResQueryClientPixmapBytes(req), #[cfg(feature = "res")] Request::ResQueryClientIds(req) => Request::ResQueryClientIds(req.into_owned()), #[cfg(feature = "res")] Request::ResQueryResourceBytes(req) => Request::ResQueryResourceBytes(req.into_owned()), #[cfg(feature = "screensaver")] Request::ScreensaverQueryVersion(req) => Request::ScreensaverQueryVersion(req), #[cfg(feature = "screensaver")] Request::ScreensaverQueryInfo(req) => Request::ScreensaverQueryInfo(req), #[cfg(feature = "screensaver")] Request::ScreensaverSelectInput(req) => Request::ScreensaverSelectInput(req), #[cfg(feature = "screensaver")] Request::ScreensaverSetAttributes(req) => Request::ScreensaverSetAttributes(req.into_owned()), #[cfg(feature = "screensaver")] Request::ScreensaverUnsetAttributes(req) => Request::ScreensaverUnsetAttributes(req), #[cfg(feature = "screensaver")] Request::ScreensaverSuspend(req) => Request::ScreensaverSuspend(req), #[cfg(feature = "shape")] Request::ShapeQueryVersion(req) => Request::ShapeQueryVersion(req), #[cfg(feature = "shape")] Request::ShapeRectangles(req) => Request::ShapeRectangles(req.into_owned()), #[cfg(feature = "shape")] Request::ShapeMask(req) => Request::ShapeMask(req), #[cfg(feature = "shape")] Request::ShapeCombine(req) => Request::ShapeCombine(req), #[cfg(feature = "shape")] Request::ShapeOffset(req) => Request::ShapeOffset(req), #[cfg(feature = "shape")] Request::ShapeQueryExtents(req) => Request::ShapeQueryExtents(req), #[cfg(feature = "shape")] Request::ShapeSelectInput(req) => Request::ShapeSelectInput(req), #[cfg(feature = "shape")] Request::ShapeInputSelected(req) => Request::ShapeInputSelected(req), #[cfg(feature = "shape")] Request::ShapeGetRectangles(req) => Request::ShapeGetRectangles(req), #[cfg(feature = "shm")] Request::ShmQueryVersion(req) => Request::ShmQueryVersion(req), #[cfg(feature = "shm")] Request::ShmAttach(req) => Request::ShmAttach(req), #[cfg(feature = "shm")] Request::ShmDetach(req) => Request::ShmDetach(req), #[cfg(feature = "shm")] Request::ShmPutImage(req) => Request::ShmPutImage(req), #[cfg(feature = "shm")] Request::ShmGetImage(req) => Request::ShmGetImage(req), #[cfg(feature = "shm")] Request::ShmCreatePixmap(req) => Request::ShmCreatePixmap(req), #[cfg(feature = "shm")] Request::ShmAttachFd(req) => Request::ShmAttachFd(req), #[cfg(feature = "shm")] Request::ShmCreateSegment(req) => Request::ShmCreateSegment(req), #[cfg(feature = "sync")] Request::SyncInitialize(req) => Request::SyncInitialize(req), #[cfg(feature = "sync")] Request::SyncListSystemCounters(req) => Request::SyncListSystemCounters(req), #[cfg(feature = "sync")] Request::SyncCreateCounter(req) => Request::SyncCreateCounter(req), #[cfg(feature = "sync")] Request::SyncDestroyCounter(req) => Request::SyncDestroyCounter(req), #[cfg(feature = "sync")] Request::SyncQueryCounter(req) => Request::SyncQueryCounter(req), #[cfg(feature = "sync")] Request::SyncAwait(req) => Request::SyncAwait(req.into_owned()), #[cfg(feature = "sync")] Request::SyncChangeCounter(req) => Request::SyncChangeCounter(req), #[cfg(feature = "sync")] Request::SyncSetCounter(req) => Request::SyncSetCounter(req), #[cfg(feature = "sync")] Request::SyncCreateAlarm(req) => Request::SyncCreateAlarm(req.into_owned()), #[cfg(feature = "sync")] Request::SyncChangeAlarm(req) => Request::SyncChangeAlarm(req.into_owned()), #[cfg(feature = "sync")] Request::SyncDestroyAlarm(req) => Request::SyncDestroyAlarm(req), #[cfg(feature = "sync")] Request::SyncQueryAlarm(req) => Request::SyncQueryAlarm(req), #[cfg(feature = "sync")] Request::SyncSetPriority(req) => Request::SyncSetPriority(req), #[cfg(feature = "sync")] Request::SyncGetPriority(req) => Request::SyncGetPriority(req), #[cfg(feature = "sync")] Request::SyncCreateFence(req) => Request::SyncCreateFence(req), #[cfg(feature = "sync")] Request::SyncTriggerFence(req) => Request::SyncTriggerFence(req), #[cfg(feature = "sync")] Request::SyncResetFence(req) => Request::SyncResetFence(req), #[cfg(feature = "sync")] Request::SyncDestroyFence(req) => Request::SyncDestroyFence(req), #[cfg(feature = "sync")] Request::SyncQueryFence(req) => Request::SyncQueryFence(req), #[cfg(feature = "sync")] Request::SyncAwaitFence(req) => Request::SyncAwaitFence(req.into_owned()), Request::XcMiscGetVersion(req) => Request::XcMiscGetVersion(req), Request::XcMiscGetXIDRange(req) => Request::XcMiscGetXIDRange(req), Request::XcMiscGetXIDList(req) => Request::XcMiscGetXIDList(req), #[cfg(feature = "xevie")] Request::XevieQueryVersion(req) => Request::XevieQueryVersion(req), #[cfg(feature = "xevie")] Request::XevieStart(req) => Request::XevieStart(req), #[cfg(feature = "xevie")] Request::XevieEnd(req) => Request::XevieEnd(req), #[cfg(feature = "xevie")] Request::XevieSend(req) => Request::XevieSend(req), #[cfg(feature = "xevie")] Request::XevieSelectInput(req) => Request::XevieSelectInput(req), #[cfg(feature = "xf86dri")] Request::Xf86driQueryVersion(req) => Request::Xf86driQueryVersion(req), #[cfg(feature = "xf86dri")] Request::Xf86driQueryDirectRenderingCapable(req) => Request::Xf86driQueryDirectRenderingCapable(req), #[cfg(feature = "xf86dri")] Request::Xf86driOpenConnection(req) => Request::Xf86driOpenConnection(req), #[cfg(feature = "xf86dri")] Request::Xf86driCloseConnection(req) => Request::Xf86driCloseConnection(req), #[cfg(feature = "xf86dri")] Request::Xf86driGetClientDriverName(req) => Request::Xf86driGetClientDriverName(req), #[cfg(feature = "xf86dri")] Request::Xf86driCreateContext(req) => Request::Xf86driCreateContext(req), #[cfg(feature = "xf86dri")] Request::Xf86driDestroyContext(req) => Request::Xf86driDestroyContext(req), #[cfg(feature = "xf86dri")] Request::Xf86driCreateDrawable(req) => Request::Xf86driCreateDrawable(req), #[cfg(feature = "xf86dri")] Request::Xf86driDestroyDrawable(req) => Request::Xf86driDestroyDrawable(req), #[cfg(feature = "xf86dri")] Request::Xf86driGetDrawableInfo(req) => Request::Xf86driGetDrawableInfo(req), #[cfg(feature = "xf86dri")] Request::Xf86driGetDeviceInfo(req) => Request::Xf86driGetDeviceInfo(req), #[cfg(feature = "xf86dri")] Request::Xf86driAuthConnection(req) => Request::Xf86driAuthConnection(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeQueryVersion(req) => Request::Xf86vidmodeQueryVersion(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetModeLine(req) => Request::Xf86vidmodeGetModeLine(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeModModeLine(req) => Request::Xf86vidmodeModModeLine(req.into_owned()), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSwitchMode(req) => Request::Xf86vidmodeSwitchMode(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetMonitor(req) => Request::Xf86vidmodeGetMonitor(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeLockModeSwitch(req) => Request::Xf86vidmodeLockModeSwitch(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetAllModeLines(req) => Request::Xf86vidmodeGetAllModeLines(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeAddModeLine(req) => Request::Xf86vidmodeAddModeLine(req.into_owned()), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeDeleteModeLine(req) => Request::Xf86vidmodeDeleteModeLine(req.into_owned()), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeValidateModeLine(req) => Request::Xf86vidmodeValidateModeLine(req.into_owned()), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSwitchToMode(req) => Request::Xf86vidmodeSwitchToMode(req.into_owned()), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetViewPort(req) => Request::Xf86vidmodeGetViewPort(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetViewPort(req) => Request::Xf86vidmodeSetViewPort(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetDotClocks(req) => Request::Xf86vidmodeGetDotClocks(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetClientVersion(req) => Request::Xf86vidmodeSetClientVersion(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetGamma(req) => Request::Xf86vidmodeSetGamma(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetGamma(req) => Request::Xf86vidmodeGetGamma(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetGammaRamp(req) => Request::Xf86vidmodeGetGammaRamp(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeSetGammaRamp(req) => Request::Xf86vidmodeSetGammaRamp(req.into_owned()), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetGammaRampSize(req) => Request::Xf86vidmodeGetGammaRampSize(req), #[cfg(feature = "xf86vidmode")] Request::Xf86vidmodeGetPermissions(req) => Request::Xf86vidmodeGetPermissions(req), #[cfg(feature = "xfixes")] Request::XfixesQueryVersion(req) => Request::XfixesQueryVersion(req), #[cfg(feature = "xfixes")] Request::XfixesChangeSaveSet(req) => Request::XfixesChangeSaveSet(req), #[cfg(feature = "xfixes")] Request::XfixesSelectSelectionInput(req) => Request::XfixesSelectSelectionInput(req), #[cfg(feature = "xfixes")] Request::XfixesSelectCursorInput(req) => Request::XfixesSelectCursorInput(req), #[cfg(feature = "xfixes")] Request::XfixesGetCursorImage(req) => Request::XfixesGetCursorImage(req), #[cfg(feature = "xfixes")] Request::XfixesCreateRegion(req) => Request::XfixesCreateRegion(req.into_owned()), #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromBitmap(req) => Request::XfixesCreateRegionFromBitmap(req), #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromWindow(req) => Request::XfixesCreateRegionFromWindow(req), #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromGC(req) => Request::XfixesCreateRegionFromGC(req), #[cfg(feature = "xfixes")] Request::XfixesCreateRegionFromPicture(req) => Request::XfixesCreateRegionFromPicture(req), #[cfg(feature = "xfixes")] Request::XfixesDestroyRegion(req) => Request::XfixesDestroyRegion(req), #[cfg(feature = "xfixes")] Request::XfixesSetRegion(req) => Request::XfixesSetRegion(req.into_owned()), #[cfg(feature = "xfixes")] Request::XfixesCopyRegion(req) => Request::XfixesCopyRegion(req), #[cfg(feature = "xfixes")] Request::XfixesUnionRegion(req) => Request::XfixesUnionRegion(req), #[cfg(feature = "xfixes")] Request::XfixesIntersectRegion(req) => Request::XfixesIntersectRegion(req), #[cfg(feature = "xfixes")] Request::XfixesSubtractRegion(req) => Request::XfixesSubtractRegion(req), #[cfg(feature = "xfixes")] Request::XfixesInvertRegion(req) => Request::XfixesInvertRegion(req), #[cfg(feature = "xfixes")] Request::XfixesTranslateRegion(req) => Request::XfixesTranslateRegion(req), #[cfg(feature = "xfixes")] Request::XfixesRegionExtents(req) => Request::XfixesRegionExtents(req), #[cfg(feature = "xfixes")] Request::XfixesFetchRegion(req) => Request::XfixesFetchRegion(req), #[cfg(feature = "xfixes")] Request::XfixesSetGCClipRegion(req) => Request::XfixesSetGCClipRegion(req), #[cfg(feature = "xfixes")] Request::XfixesSetWindowShapeRegion(req) => Request::XfixesSetWindowShapeRegion(req), #[cfg(feature = "xfixes")] Request::XfixesSetPictureClipRegion(req) => Request::XfixesSetPictureClipRegion(req), #[cfg(feature = "xfixes")] Request::XfixesSetCursorName(req) => Request::XfixesSetCursorName(req.into_owned()), #[cfg(feature = "xfixes")] Request::XfixesGetCursorName(req) => Request::XfixesGetCursorName(req), #[cfg(feature = "xfixes")] Request::XfixesGetCursorImageAndName(req) => Request::XfixesGetCursorImageAndName(req), #[cfg(feature = "xfixes")] Request::XfixesChangeCursor(req) => Request::XfixesChangeCursor(req), #[cfg(feature = "xfixes")] Request::XfixesChangeCursorByName(req) => Request::XfixesChangeCursorByName(req.into_owned()), #[cfg(feature = "xfixes")] Request::XfixesExpandRegion(req) => Request::XfixesExpandRegion(req), #[cfg(feature = "xfixes")] Request::XfixesHideCursor(req) => Request::XfixesHideCursor(req), #[cfg(feature = "xfixes")] Request::XfixesShowCursor(req) => Request::XfixesShowCursor(req), #[cfg(feature = "xfixes")] Request::XfixesCreatePointerBarrier(req) => Request::XfixesCreatePointerBarrier(req.into_owned()), #[cfg(feature = "xfixes")] Request::XfixesDeletePointerBarrier(req) => Request::XfixesDeletePointerBarrier(req), #[cfg(feature = "xinerama")] Request::XineramaQueryVersion(req) => Request::XineramaQueryVersion(req), #[cfg(feature = "xinerama")] Request::XineramaGetState(req) => Request::XineramaGetState(req), #[cfg(feature = "xinerama")] Request::XineramaGetScreenCount(req) => Request::XineramaGetScreenCount(req), #[cfg(feature = "xinerama")] Request::XineramaGetScreenSize(req) => Request::XineramaGetScreenSize(req), #[cfg(feature = "xinerama")] Request::XineramaIsActive(req) => Request::XineramaIsActive(req), #[cfg(feature = "xinerama")] Request::XineramaQueryScreens(req) => Request::XineramaQueryScreens(req), #[cfg(feature = "xinput")] Request::XinputGetExtensionVersion(req) => Request::XinputGetExtensionVersion(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputListInputDevices(req) => Request::XinputListInputDevices(req), #[cfg(feature = "xinput")] Request::XinputOpenDevice(req) => Request::XinputOpenDevice(req), #[cfg(feature = "xinput")] Request::XinputCloseDevice(req) => Request::XinputCloseDevice(req), #[cfg(feature = "xinput")] Request::XinputSetDeviceMode(req) => Request::XinputSetDeviceMode(req), #[cfg(feature = "xinput")] Request::XinputSelectExtensionEvent(req) => Request::XinputSelectExtensionEvent(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputGetSelectedExtensionEvents(req) => Request::XinputGetSelectedExtensionEvents(req), #[cfg(feature = "xinput")] Request::XinputChangeDeviceDontPropagateList(req) => Request::XinputChangeDeviceDontPropagateList(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputGetDeviceDontPropagateList(req) => Request::XinputGetDeviceDontPropagateList(req), #[cfg(feature = "xinput")] Request::XinputGetDeviceMotionEvents(req) => Request::XinputGetDeviceMotionEvents(req), #[cfg(feature = "xinput")] Request::XinputChangeKeyboardDevice(req) => Request::XinputChangeKeyboardDevice(req), #[cfg(feature = "xinput")] Request::XinputChangePointerDevice(req) => Request::XinputChangePointerDevice(req), #[cfg(feature = "xinput")] Request::XinputGrabDevice(req) => Request::XinputGrabDevice(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputUngrabDevice(req) => Request::XinputUngrabDevice(req), #[cfg(feature = "xinput")] Request::XinputGrabDeviceKey(req) => Request::XinputGrabDeviceKey(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputUngrabDeviceKey(req) => Request::XinputUngrabDeviceKey(req), #[cfg(feature = "xinput")] Request::XinputGrabDeviceButton(req) => Request::XinputGrabDeviceButton(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputUngrabDeviceButton(req) => Request::XinputUngrabDeviceButton(req), #[cfg(feature = "xinput")] Request::XinputAllowDeviceEvents(req) => Request::XinputAllowDeviceEvents(req), #[cfg(feature = "xinput")] Request::XinputGetDeviceFocus(req) => Request::XinputGetDeviceFocus(req), #[cfg(feature = "xinput")] Request::XinputSetDeviceFocus(req) => Request::XinputSetDeviceFocus(req), #[cfg(feature = "xinput")] Request::XinputGetFeedbackControl(req) => Request::XinputGetFeedbackControl(req), #[cfg(feature = "xinput")] Request::XinputChangeFeedbackControl(req) => Request::XinputChangeFeedbackControl(req), #[cfg(feature = "xinput")] Request::XinputGetDeviceKeyMapping(req) => Request::XinputGetDeviceKeyMapping(req), #[cfg(feature = "xinput")] Request::XinputChangeDeviceKeyMapping(req) => Request::XinputChangeDeviceKeyMapping(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputGetDeviceModifierMapping(req) => Request::XinputGetDeviceModifierMapping(req), #[cfg(feature = "xinput")] Request::XinputSetDeviceModifierMapping(req) => Request::XinputSetDeviceModifierMapping(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputGetDeviceButtonMapping(req) => Request::XinputGetDeviceButtonMapping(req), #[cfg(feature = "xinput")] Request::XinputSetDeviceButtonMapping(req) => Request::XinputSetDeviceButtonMapping(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputQueryDeviceState(req) => Request::XinputQueryDeviceState(req), #[cfg(feature = "xinput")] Request::XinputDeviceBell(req) => Request::XinputDeviceBell(req), #[cfg(feature = "xinput")] Request::XinputSetDeviceValuators(req) => Request::XinputSetDeviceValuators(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputGetDeviceControl(req) => Request::XinputGetDeviceControl(req), #[cfg(feature = "xinput")] Request::XinputChangeDeviceControl(req) => Request::XinputChangeDeviceControl(req), #[cfg(feature = "xinput")] Request::XinputListDeviceProperties(req) => Request::XinputListDeviceProperties(req), #[cfg(feature = "xinput")] Request::XinputChangeDeviceProperty(req) => Request::XinputChangeDeviceProperty(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputDeleteDeviceProperty(req) => Request::XinputDeleteDeviceProperty(req), #[cfg(feature = "xinput")] Request::XinputGetDeviceProperty(req) => Request::XinputGetDeviceProperty(req), #[cfg(feature = "xinput")] Request::XinputXIQueryPointer(req) => Request::XinputXIQueryPointer(req), #[cfg(feature = "xinput")] Request::XinputXIWarpPointer(req) => Request::XinputXIWarpPointer(req), #[cfg(feature = "xinput")] Request::XinputXIChangeCursor(req) => Request::XinputXIChangeCursor(req), #[cfg(feature = "xinput")] Request::XinputXIChangeHierarchy(req) => Request::XinputXIChangeHierarchy(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputXISetClientPointer(req) => Request::XinputXISetClientPointer(req), #[cfg(feature = "xinput")] Request::XinputXIGetClientPointer(req) => Request::XinputXIGetClientPointer(req), #[cfg(feature = "xinput")] Request::XinputXISelectEvents(req) => Request::XinputXISelectEvents(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputXIQueryVersion(req) => Request::XinputXIQueryVersion(req), #[cfg(feature = "xinput")] Request::XinputXIQueryDevice(req) => Request::XinputXIQueryDevice(req), #[cfg(feature = "xinput")] Request::XinputXISetFocus(req) => Request::XinputXISetFocus(req), #[cfg(feature = "xinput")] Request::XinputXIGetFocus(req) => Request::XinputXIGetFocus(req), #[cfg(feature = "xinput")] Request::XinputXIGrabDevice(req) => Request::XinputXIGrabDevice(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputXIUngrabDevice(req) => Request::XinputXIUngrabDevice(req), #[cfg(feature = "xinput")] Request::XinputXIAllowEvents(req) => Request::XinputXIAllowEvents(req), #[cfg(feature = "xinput")] Request::XinputXIPassiveGrabDevice(req) => Request::XinputXIPassiveGrabDevice(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputXIPassiveUngrabDevice(req) => Request::XinputXIPassiveUngrabDevice(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputXIListProperties(req) => Request::XinputXIListProperties(req), #[cfg(feature = "xinput")] Request::XinputXIChangeProperty(req) => Request::XinputXIChangeProperty(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputXIDeleteProperty(req) => Request::XinputXIDeleteProperty(req), #[cfg(feature = "xinput")] Request::XinputXIGetProperty(req) => Request::XinputXIGetProperty(req), #[cfg(feature = "xinput")] Request::XinputXIGetSelectedEvents(req) => Request::XinputXIGetSelectedEvents(req), #[cfg(feature = "xinput")] Request::XinputXIBarrierReleasePointer(req) => Request::XinputXIBarrierReleasePointer(req.into_owned()), #[cfg(feature = "xinput")] Request::XinputSendExtensionEvent(req) => Request::XinputSendExtensionEvent(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbUseExtension(req) => Request::XkbUseExtension(req), #[cfg(feature = "xkb")] Request::XkbSelectEvents(req) => Request::XkbSelectEvents(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbBell(req) => Request::XkbBell(req), #[cfg(feature = "xkb")] Request::XkbGetState(req) => Request::XkbGetState(req), #[cfg(feature = "xkb")] Request::XkbLatchLockState(req) => Request::XkbLatchLockState(req), #[cfg(feature = "xkb")] Request::XkbGetControls(req) => Request::XkbGetControls(req), #[cfg(feature = "xkb")] Request::XkbSetControls(req) => Request::XkbSetControls(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbGetMap(req) => Request::XkbGetMap(req), #[cfg(feature = "xkb")] Request::XkbSetMap(req) => Request::XkbSetMap(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbGetCompatMap(req) => Request::XkbGetCompatMap(req), #[cfg(feature = "xkb")] Request::XkbSetCompatMap(req) => Request::XkbSetCompatMap(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbGetIndicatorState(req) => Request::XkbGetIndicatorState(req), #[cfg(feature = "xkb")] Request::XkbGetIndicatorMap(req) => Request::XkbGetIndicatorMap(req), #[cfg(feature = "xkb")] Request::XkbSetIndicatorMap(req) => Request::XkbSetIndicatorMap(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbGetNamedIndicator(req) => Request::XkbGetNamedIndicator(req), #[cfg(feature = "xkb")] Request::XkbSetNamedIndicator(req) => Request::XkbSetNamedIndicator(req), #[cfg(feature = "xkb")] Request::XkbGetNames(req) => Request::XkbGetNames(req), #[cfg(feature = "xkb")] Request::XkbSetNames(req) => Request::XkbSetNames(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbPerClientFlags(req) => Request::XkbPerClientFlags(req), #[cfg(feature = "xkb")] Request::XkbListComponents(req) => Request::XkbListComponents(req), #[cfg(feature = "xkb")] Request::XkbGetKbdByName(req) => Request::XkbGetKbdByName(req), #[cfg(feature = "xkb")] Request::XkbGetDeviceInfo(req) => Request::XkbGetDeviceInfo(req), #[cfg(feature = "xkb")] Request::XkbSetDeviceInfo(req) => Request::XkbSetDeviceInfo(req.into_owned()), #[cfg(feature = "xkb")] Request::XkbSetDebuggingFlags(req) => Request::XkbSetDebuggingFlags(req.into_owned()), #[cfg(feature = "xprint")] Request::XprintPrintQueryVersion(req) => Request::XprintPrintQueryVersion(req), #[cfg(feature = "xprint")] Request::XprintPrintGetPrinterList(req) => Request::XprintPrintGetPrinterList(req.into_owned()), #[cfg(feature = "xprint")] Request::XprintPrintRehashPrinterList(req) => Request::XprintPrintRehashPrinterList(req), #[cfg(feature = "xprint")] Request::XprintCreateContext(req) => Request::XprintCreateContext(req.into_owned()), #[cfg(feature = "xprint")] Request::XprintPrintSetContext(req) => Request::XprintPrintSetContext(req), #[cfg(feature = "xprint")] Request::XprintPrintGetContext(req) => Request::XprintPrintGetContext(req), #[cfg(feature = "xprint")] Request::XprintPrintDestroyContext(req) => Request::XprintPrintDestroyContext(req), #[cfg(feature = "xprint")] Request::XprintPrintGetScreenOfContext(req) => Request::XprintPrintGetScreenOfContext(req), #[cfg(feature = "xprint")] Request::XprintPrintStartJob(req) => Request::XprintPrintStartJob(req), #[cfg(feature = "xprint")] Request::XprintPrintEndJob(req) => Request::XprintPrintEndJob(req), #[cfg(feature = "xprint")] Request::XprintPrintStartDoc(req) => Request::XprintPrintStartDoc(req), #[cfg(feature = "xprint")] Request::XprintPrintEndDoc(req) => Request::XprintPrintEndDoc(req), #[cfg(feature = "xprint")] Request::XprintPrintPutDocumentData(req) => Request::XprintPrintPutDocumentData(req.into_owned()), #[cfg(feature = "xprint")] Request::XprintPrintGetDocumentData(req) => Request::XprintPrintGetDocumentData(req), #[cfg(feature = "xprint")] Request::XprintPrintStartPage(req) => Request::XprintPrintStartPage(req), #[cfg(feature = "xprint")] Request::XprintPrintEndPage(req) => Request::XprintPrintEndPage(req), #[cfg(feature = "xprint")] Request::XprintPrintSelectInput(req) => Request::XprintPrintSelectInput(req), #[cfg(feature = "xprint")] Request::XprintPrintInputSelected(req) => Request::XprintPrintInputSelected(req), #[cfg(feature = "xprint")] Request::XprintPrintGetAttributes(req) => Request::XprintPrintGetAttributes(req), #[cfg(feature = "xprint")] Request::XprintPrintGetOneAttributes(req) => Request::XprintPrintGetOneAttributes(req.into_owned()), #[cfg(feature = "xprint")] Request::XprintPrintSetAttributes(req) => Request::XprintPrintSetAttributes(req.into_owned()), #[cfg(feature = "xprint")] Request::XprintPrintGetPageDimensions(req) => Request::XprintPrintGetPageDimensions(req), #[cfg(feature = "xprint")] Request::XprintPrintQueryScreens(req) => Request::XprintPrintQueryScreens(req), #[cfg(feature = "xprint")] Request::XprintPrintSetImageResolution(req) => Request::XprintPrintSetImageResolution(req), #[cfg(feature = "xprint")] Request::XprintPrintGetImageResolution(req) => Request::XprintPrintGetImageResolution(req), #[cfg(feature = "xselinux")] Request::XselinuxQueryVersion(req) => Request::XselinuxQueryVersion(req), #[cfg(feature = "xselinux")] Request::XselinuxSetDeviceCreateContext(req) => Request::XselinuxSetDeviceCreateContext(req.into_owned()), #[cfg(feature = "xselinux")] Request::XselinuxGetDeviceCreateContext(req) => Request::XselinuxGetDeviceCreateContext(req), #[cfg(feature = "xselinux")] Request::XselinuxSetDeviceContext(req) => Request::XselinuxSetDeviceContext(req.into_owned()), #[cfg(feature = "xselinux")] Request::XselinuxGetDeviceContext(req) => Request::XselinuxGetDeviceContext(req), #[cfg(feature = "xselinux")] Request::XselinuxSetWindowCreateContext(req) => Request::XselinuxSetWindowCreateContext(req.into_owned()), #[cfg(feature = "xselinux")] Request::XselinuxGetWindowCreateContext(req) => Request::XselinuxGetWindowCreateContext(req), #[cfg(feature = "xselinux")] Request::XselinuxGetWindowContext(req) => Request::XselinuxGetWindowContext(req), #[cfg(feature = "xselinux")] Request::XselinuxSetPropertyCreateContext(req) => Request::XselinuxSetPropertyCreateContext(req.into_owned()), #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyCreateContext(req) => Request::XselinuxGetPropertyCreateContext(req), #[cfg(feature = "xselinux")] Request::XselinuxSetPropertyUseContext(req) => Request::XselinuxSetPropertyUseContext(req.into_owned()), #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyUseContext(req) => Request::XselinuxGetPropertyUseContext(req), #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyContext(req) => Request::XselinuxGetPropertyContext(req), #[cfg(feature = "xselinux")] Request::XselinuxGetPropertyDataContext(req) => Request::XselinuxGetPropertyDataContext(req), #[cfg(feature = "xselinux")] Request::XselinuxListProperties(req) => Request::XselinuxListProperties(req), #[cfg(feature = "xselinux")] Request::XselinuxSetSelectionCreateContext(req) => Request::XselinuxSetSelectionCreateContext(req.into_owned()), #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionCreateContext(req) => Request::XselinuxGetSelectionCreateContext(req), #[cfg(feature = "xselinux")] Request::XselinuxSetSelectionUseContext(req) => Request::XselinuxSetSelectionUseContext(req.into_owned()), #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionUseContext(req) => Request::XselinuxGetSelectionUseContext(req), #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionContext(req) => Request::XselinuxGetSelectionContext(req), #[cfg(feature = "xselinux")] Request::XselinuxGetSelectionDataContext(req) => Request::XselinuxGetSelectionDataContext(req), #[cfg(feature = "xselinux")] Request::XselinuxListSelections(req) => Request::XselinuxListSelections(req), #[cfg(feature = "xselinux")] Request::XselinuxGetClientContext(req) => Request::XselinuxGetClientContext(req), #[cfg(feature = "xtest")] Request::XtestGetVersion(req) => Request::XtestGetVersion(req), #[cfg(feature = "xtest")] Request::XtestCompareCursor(req) => Request::XtestCompareCursor(req), #[cfg(feature = "xtest")] Request::XtestFakeInput(req) => Request::XtestFakeInput(req), #[cfg(feature = "xtest")] Request::XtestGrabControl(req) => Request::XtestGrabControl(req), #[cfg(feature = "xv")] Request::XvQueryExtension(req) => Request::XvQueryExtension(req), #[cfg(feature = "xv")] Request::XvQueryAdaptors(req) => Request::XvQueryAdaptors(req), #[cfg(feature = "xv")] Request::XvQueryEncodings(req) => Request::XvQueryEncodings(req), #[cfg(feature = "xv")] Request::XvGrabPort(req) => Request::XvGrabPort(req), #[cfg(feature = "xv")] Request::XvUngrabPort(req) => Request::XvUngrabPort(req), #[cfg(feature = "xv")] Request::XvPutVideo(req) => Request::XvPutVideo(req), #[cfg(feature = "xv")] Request::XvPutStill(req) => Request::XvPutStill(req), #[cfg(feature = "xv")] Request::XvGetVideo(req) => Request::XvGetVideo(req), #[cfg(feature = "xv")] Request::XvGetStill(req) => Request::XvGetStill(req), #[cfg(feature = "xv")] Request::XvStopVideo(req) => Request::XvStopVideo(req), #[cfg(feature = "xv")] Request::XvSelectVideoNotify(req) => Request::XvSelectVideoNotify(req), #[cfg(feature = "xv")] Request::XvSelectPortNotify(req) => Request::XvSelectPortNotify(req), #[cfg(feature = "xv")] Request::XvQueryBestSize(req) => Request::XvQueryBestSize(req), #[cfg(feature = "xv")] Request::XvSetPortAttribute(req) => Request::XvSetPortAttribute(req), #[cfg(feature = "xv")] Request::XvGetPortAttribute(req) => Request::XvGetPortAttribute(req), #[cfg(feature = "xv")] Request::XvQueryPortAttributes(req) => Request::XvQueryPortAttributes(req), #[cfg(feature = "xv")] Request::XvListImageFormats(req) => Request::XvListImageFormats(req), #[cfg(feature = "xv")] Request::XvQueryImageAttributes(req) => Request::XvQueryImageAttributes(req), #[cfg(feature = "xv")] Request::XvPutImage(req) => Request::XvPutImage(req.into_owned()), #[cfg(feature = "xv")] Request::XvShmPutImage(req) => Request::XvShmPutImage(req), #[cfg(feature = "xvmc")] Request::XvmcQueryVersion(req) => Request::XvmcQueryVersion(req), #[cfg(feature = "xvmc")] Request::XvmcListSurfaceTypes(req) => Request::XvmcListSurfaceTypes(req), #[cfg(feature = "xvmc")] Request::XvmcCreateContext(req) => Request::XvmcCreateContext(req), #[cfg(feature = "xvmc")] Request::XvmcDestroyContext(req) => Request::XvmcDestroyContext(req), #[cfg(feature = "xvmc")] Request::XvmcCreateSurface(req) => Request::XvmcCreateSurface(req), #[cfg(feature = "xvmc")] Request::XvmcDestroySurface(req) => Request::XvmcDestroySurface(req), #[cfg(feature = "xvmc")] Request::XvmcCreateSubpicture(req) => Request::XvmcCreateSubpicture(req), #[cfg(feature = "xvmc")] Request::XvmcDestroySubpicture(req) => Request::XvmcDestroySubpicture(req), #[cfg(feature = "xvmc")] Request::XvmcListSubpictureTypes(req) => Request::XvmcListSubpictureTypes(req), } } } /// Enumeration of all possible X11 replies. #[derive(Debug)] #[allow(clippy::large_enum_variant)] #[non_exhaustive] pub enum Reply { Void, GetWindowAttributes(xproto::GetWindowAttributesReply), GetGeometry(xproto::GetGeometryReply), QueryTree(xproto::QueryTreeReply), InternAtom(xproto::InternAtomReply), GetAtomName(xproto::GetAtomNameReply), GetProperty(xproto::GetPropertyReply), ListProperties(xproto::ListPropertiesReply), GetSelectionOwner(xproto::GetSelectionOwnerReply), GrabPointer(xproto::GrabPointerReply), GrabKeyboard(xproto::GrabKeyboardReply), QueryPointer(xproto::QueryPointerReply), GetMotionEvents(xproto::GetMotionEventsReply), TranslateCoordinates(xproto::TranslateCoordinatesReply), GetInputFocus(xproto::GetInputFocusReply), QueryKeymap(xproto::QueryKeymapReply), QueryFont(xproto::QueryFontReply), QueryTextExtents(xproto::QueryTextExtentsReply), ListFonts(xproto::ListFontsReply), ListFontsWithInfo(xproto::ListFontsWithInfoReply), GetFontPath(xproto::GetFontPathReply), GetImage(xproto::GetImageReply), ListInstalledColormaps(xproto::ListInstalledColormapsReply), AllocColor(xproto::AllocColorReply), AllocNamedColor(xproto::AllocNamedColorReply), AllocColorCells(xproto::AllocColorCellsReply), AllocColorPlanes(xproto::AllocColorPlanesReply), QueryColors(xproto::QueryColorsReply), LookupColor(xproto::LookupColorReply), QueryBestSize(xproto::QueryBestSizeReply), QueryExtension(xproto::QueryExtensionReply), ListExtensions(xproto::ListExtensionsReply), GetKeyboardMapping(xproto::GetKeyboardMappingReply), GetKeyboardControl(xproto::GetKeyboardControlReply), GetPointerControl(xproto::GetPointerControlReply), GetScreenSaver(xproto::GetScreenSaverReply), ListHosts(xproto::ListHostsReply), SetPointerMapping(xproto::SetPointerMappingReply), GetPointerMapping(xproto::GetPointerMappingReply), SetModifierMapping(xproto::SetModifierMappingReply), GetModifierMapping(xproto::GetModifierMappingReply), BigreqEnable(bigreq::EnableReply), #[cfg(feature = "composite")] CompositeQueryVersion(composite::QueryVersionReply), #[cfg(feature = "composite")] CompositeGetOverlayWindow(composite::GetOverlayWindowReply), #[cfg(feature = "damage")] DamageQueryVersion(damage::QueryVersionReply), #[cfg(feature = "dpms")] DpmsGetVersion(dpms::GetVersionReply), #[cfg(feature = "dpms")] DpmsCapable(dpms::CapableReply), #[cfg(feature = "dpms")] DpmsGetTimeouts(dpms::GetTimeoutsReply), #[cfg(feature = "dpms")] DpmsInfo(dpms::InfoReply), #[cfg(feature = "dri2")] Dri2QueryVersion(dri2::QueryVersionReply), #[cfg(feature = "dri2")] Dri2Connect(dri2::ConnectReply), #[cfg(feature = "dri2")] Dri2Authenticate(dri2::AuthenticateReply), #[cfg(feature = "dri2")] Dri2GetBuffers(dri2::GetBuffersReply), #[cfg(feature = "dri2")] Dri2CopyRegion(dri2::CopyRegionReply), #[cfg(feature = "dri2")] Dri2GetBuffersWithFormat(dri2::GetBuffersWithFormatReply), #[cfg(feature = "dri2")] Dri2SwapBuffers(dri2::SwapBuffersReply), #[cfg(feature = "dri2")] Dri2GetMSC(dri2::GetMSCReply), #[cfg(feature = "dri2")] Dri2WaitMSC(dri2::WaitMSCReply), #[cfg(feature = "dri2")] Dri2WaitSBC(dri2::WaitSBCReply), #[cfg(feature = "dri2")] Dri2GetParam(dri2::GetParamReply), #[cfg(feature = "dri3")] Dri3QueryVersion(dri3::QueryVersionReply), #[cfg(feature = "dri3")] Dri3Open(dri3::OpenReply), #[cfg(feature = "dri3")] Dri3BufferFromPixmap(dri3::BufferFromPixmapReply), #[cfg(feature = "dri3")] Dri3FDFromFence(dri3::FDFromFenceReply), #[cfg(feature = "dri3")] Dri3GetSupportedModifiers(dri3::GetSupportedModifiersReply), #[cfg(feature = "dri3")] Dri3BuffersFromPixmap(dri3::BuffersFromPixmapReply), GeQueryVersion(ge::QueryVersionReply), #[cfg(feature = "glx")] GlxMakeCurrent(glx::MakeCurrentReply), #[cfg(feature = "glx")] GlxIsDirect(glx::IsDirectReply), #[cfg(feature = "glx")] GlxQueryVersion(glx::QueryVersionReply), #[cfg(feature = "glx")] GlxGetVisualConfigs(glx::GetVisualConfigsReply), #[cfg(feature = "glx")] GlxVendorPrivateWithReply(glx::VendorPrivateWithReplyReply), #[cfg(feature = "glx")] GlxQueryExtensionsString(glx::QueryExtensionsStringReply), #[cfg(feature = "glx")] GlxQueryServerString(glx::QueryServerStringReply), #[cfg(feature = "glx")] GlxGetFBConfigs(glx::GetFBConfigsReply), #[cfg(feature = "glx")] GlxQueryContext(glx::QueryContextReply), #[cfg(feature = "glx")] GlxMakeContextCurrent(glx::MakeContextCurrentReply), #[cfg(feature = "glx")] GlxGetDrawableAttributes(glx::GetDrawableAttributesReply), #[cfg(feature = "glx")] GlxGenLists(glx::GenListsReply), #[cfg(feature = "glx")] GlxRenderMode(glx::RenderModeReply), #[cfg(feature = "glx")] GlxFinish(glx::FinishReply), #[cfg(feature = "glx")] GlxReadPixels(glx::ReadPixelsReply), #[cfg(feature = "glx")] GlxGetBooleanv(glx::GetBooleanvReply), #[cfg(feature = "glx")] GlxGetClipPlane(glx::GetClipPlaneReply), #[cfg(feature = "glx")] GlxGetDoublev(glx::GetDoublevReply), #[cfg(feature = "glx")] GlxGetError(glx::GetErrorReply), #[cfg(feature = "glx")] GlxGetFloatv(glx::GetFloatvReply), #[cfg(feature = "glx")] GlxGetIntegerv(glx::GetIntegervReply), #[cfg(feature = "glx")] GlxGetLightfv(glx::GetLightfvReply), #[cfg(feature = "glx")] GlxGetLightiv(glx::GetLightivReply), #[cfg(feature = "glx")] GlxGetMapdv(glx::GetMapdvReply), #[cfg(feature = "glx")] GlxGetMapfv(glx::GetMapfvReply), #[cfg(feature = "glx")] GlxGetMapiv(glx::GetMapivReply), #[cfg(feature = "glx")] GlxGetMaterialfv(glx::GetMaterialfvReply), #[cfg(feature = "glx")] GlxGetMaterialiv(glx::GetMaterialivReply), #[cfg(feature = "glx")] GlxGetPixelMapfv(glx::GetPixelMapfvReply), #[cfg(feature = "glx")] GlxGetPixelMapuiv(glx::GetPixelMapuivReply), #[cfg(feature = "glx")] GlxGetPixelMapusv(glx::GetPixelMapusvReply), #[cfg(feature = "glx")] GlxGetPolygonStipple(glx::GetPolygonStippleReply), #[cfg(feature = "glx")] GlxGetString(glx::GetStringReply), #[cfg(feature = "glx")] GlxGetTexEnvfv(glx::GetTexEnvfvReply), #[cfg(feature = "glx")] GlxGetTexEnviv(glx::GetTexEnvivReply), #[cfg(feature = "glx")] GlxGetTexGendv(glx::GetTexGendvReply), #[cfg(feature = "glx")] GlxGetTexGenfv(glx::GetTexGenfvReply), #[cfg(feature = "glx")] GlxGetTexGeniv(glx::GetTexGenivReply), #[cfg(feature = "glx")] GlxGetTexImage(glx::GetTexImageReply), #[cfg(feature = "glx")] GlxGetTexParameterfv(glx::GetTexParameterfvReply), #[cfg(feature = "glx")] GlxGetTexParameteriv(glx::GetTexParameterivReply), #[cfg(feature = "glx")] GlxGetTexLevelParameterfv(glx::GetTexLevelParameterfvReply), #[cfg(feature = "glx")] GlxGetTexLevelParameteriv(glx::GetTexLevelParameterivReply), #[cfg(feature = "glx")] GlxIsEnabled(glx::IsEnabledReply), #[cfg(feature = "glx")] GlxIsList(glx::IsListReply), #[cfg(feature = "glx")] GlxAreTexturesResident(glx::AreTexturesResidentReply), #[cfg(feature = "glx")] GlxGenTextures(glx::GenTexturesReply), #[cfg(feature = "glx")] GlxIsTexture(glx::IsTextureReply), #[cfg(feature = "glx")] GlxGetColorTable(glx::GetColorTableReply), #[cfg(feature = "glx")] GlxGetColorTableParameterfv(glx::GetColorTableParameterfvReply), #[cfg(feature = "glx")] GlxGetColorTableParameteriv(glx::GetColorTableParameterivReply), #[cfg(feature = "glx")] GlxGetConvolutionFilter(glx::GetConvolutionFilterReply), #[cfg(feature = "glx")] GlxGetConvolutionParameterfv(glx::GetConvolutionParameterfvReply), #[cfg(feature = "glx")] GlxGetConvolutionParameteriv(glx::GetConvolutionParameterivReply), #[cfg(feature = "glx")] GlxGetSeparableFilter(glx::GetSeparableFilterReply), #[cfg(feature = "glx")] GlxGetHistogram(glx::GetHistogramReply), #[cfg(feature = "glx")] GlxGetHistogramParameterfv(glx::GetHistogramParameterfvReply), #[cfg(feature = "glx")] GlxGetHistogramParameteriv(glx::GetHistogramParameterivReply), #[cfg(feature = "glx")] GlxGetMinmax(glx::GetMinmaxReply), #[cfg(feature = "glx")] GlxGetMinmaxParameterfv(glx::GetMinmaxParameterfvReply), #[cfg(feature = "glx")] GlxGetMinmaxParameteriv(glx::GetMinmaxParameterivReply), #[cfg(feature = "glx")] GlxGetCompressedTexImageARB(glx::GetCompressedTexImageARBReply), #[cfg(feature = "glx")] GlxGenQueriesARB(glx::GenQueriesARBReply), #[cfg(feature = "glx")] GlxIsQueryARB(glx::IsQueryARBReply), #[cfg(feature = "glx")] GlxGetQueryivARB(glx::GetQueryivARBReply), #[cfg(feature = "glx")] GlxGetQueryObjectivARB(glx::GetQueryObjectivARBReply), #[cfg(feature = "glx")] GlxGetQueryObjectuivARB(glx::GetQueryObjectuivARBReply), #[cfg(feature = "present")] PresentQueryVersion(present::QueryVersionReply), #[cfg(feature = "present")] PresentQueryCapabilities(present::QueryCapabilitiesReply), #[cfg(feature = "randr")] RandrQueryVersion(randr::QueryVersionReply), #[cfg(feature = "randr")] RandrSetScreenConfig(randr::SetScreenConfigReply), #[cfg(feature = "randr")] RandrGetScreenInfo(randr::GetScreenInfoReply), #[cfg(feature = "randr")] RandrGetScreenSizeRange(randr::GetScreenSizeRangeReply), #[cfg(feature = "randr")] RandrGetScreenResources(randr::GetScreenResourcesReply), #[cfg(feature = "randr")] RandrGetOutputInfo(randr::GetOutputInfoReply), #[cfg(feature = "randr")] RandrListOutputProperties(randr::ListOutputPropertiesReply), #[cfg(feature = "randr")] RandrQueryOutputProperty(randr::QueryOutputPropertyReply), #[cfg(feature = "randr")] RandrGetOutputProperty(randr::GetOutputPropertyReply), #[cfg(feature = "randr")] RandrCreateMode(randr::CreateModeReply), #[cfg(feature = "randr")] RandrGetCrtcInfo(randr::GetCrtcInfoReply), #[cfg(feature = "randr")] RandrSetCrtcConfig(randr::SetCrtcConfigReply), #[cfg(feature = "randr")] RandrGetCrtcGammaSize(randr::GetCrtcGammaSizeReply), #[cfg(feature = "randr")] RandrGetCrtcGamma(randr::GetCrtcGammaReply), #[cfg(feature = "randr")] RandrGetScreenResourcesCurrent(randr::GetScreenResourcesCurrentReply), #[cfg(feature = "randr")] RandrGetCrtcTransform(randr::GetCrtcTransformReply), #[cfg(feature = "randr")] RandrGetPanning(randr::GetPanningReply), #[cfg(feature = "randr")] RandrSetPanning(randr::SetPanningReply), #[cfg(feature = "randr")] RandrGetOutputPrimary(randr::GetOutputPrimaryReply), #[cfg(feature = "randr")] RandrGetProviders(randr::GetProvidersReply), #[cfg(feature = "randr")] RandrGetProviderInfo(randr::GetProviderInfoReply), #[cfg(feature = "randr")] RandrListProviderProperties(randr::ListProviderPropertiesReply), #[cfg(feature = "randr")] RandrQueryProviderProperty(randr::QueryProviderPropertyReply), #[cfg(feature = "randr")] RandrGetProviderProperty(randr::GetProviderPropertyReply), #[cfg(feature = "randr")] RandrGetMonitors(randr::GetMonitorsReply), #[cfg(feature = "randr")] RandrCreateLease(randr::CreateLeaseReply), #[cfg(feature = "record")] RecordQueryVersion(record::QueryVersionReply), #[cfg(feature = "record")] RecordGetContext(record::GetContextReply), #[cfg(feature = "record")] RecordEnableContext(record::EnableContextReply), #[cfg(feature = "render")] RenderQueryVersion(render::QueryVersionReply), #[cfg(feature = "render")] RenderQueryPictFormats(render::QueryPictFormatsReply), #[cfg(feature = "render")] RenderQueryPictIndexValues(render::QueryPictIndexValuesReply), #[cfg(feature = "render")] RenderQueryFilters(render::QueryFiltersReply), #[cfg(feature = "res")] ResQueryVersion(res::QueryVersionReply), #[cfg(feature = "res")] ResQueryClients(res::QueryClientsReply), #[cfg(feature = "res")] ResQueryClientResources(res::QueryClientResourcesReply), #[cfg(feature = "res")] ResQueryClientPixmapBytes(res::QueryClientPixmapBytesReply), #[cfg(feature = "res")] ResQueryClientIds(res::QueryClientIdsReply), #[cfg(feature = "res")] ResQueryResourceBytes(res::QueryResourceBytesReply), #[cfg(feature = "screensaver")] ScreensaverQueryVersion(screensaver::QueryVersionReply), #[cfg(feature = "screensaver")] ScreensaverQueryInfo(screensaver::QueryInfoReply), #[cfg(feature = "shape")] ShapeQueryVersion(shape::QueryVersionReply), #[cfg(feature = "shape")] ShapeQueryExtents(shape::QueryExtentsReply), #[cfg(feature = "shape")] ShapeInputSelected(shape::InputSelectedReply), #[cfg(feature = "shape")] ShapeGetRectangles(shape::GetRectanglesReply), #[cfg(feature = "shm")] ShmQueryVersion(shm::QueryVersionReply), #[cfg(feature = "shm")] ShmGetImage(shm::GetImageReply), #[cfg(feature = "shm")] ShmCreateSegment(shm::CreateSegmentReply), #[cfg(feature = "sync")] SyncInitialize(sync::InitializeReply), #[cfg(feature = "sync")] SyncListSystemCounters(sync::ListSystemCountersReply), #[cfg(feature = "sync")] SyncQueryCounter(sync::QueryCounterReply), #[cfg(feature = "sync")] SyncQueryAlarm(sync::QueryAlarmReply), #[cfg(feature = "sync")] SyncGetPriority(sync::GetPriorityReply), #[cfg(feature = "sync")] SyncQueryFence(sync::QueryFenceReply), XcMiscGetVersion(xc_misc::GetVersionReply), XcMiscGetXIDRange(xc_misc::GetXIDRangeReply), XcMiscGetXIDList(xc_misc::GetXIDListReply), #[cfg(feature = "xevie")] XevieQueryVersion(xevie::QueryVersionReply), #[cfg(feature = "xevie")] XevieStart(xevie::StartReply), #[cfg(feature = "xevie")] XevieEnd(xevie::EndReply), #[cfg(feature = "xevie")] XevieSend(xevie::SendReply), #[cfg(feature = "xevie")] XevieSelectInput(xevie::SelectInputReply), #[cfg(feature = "xf86dri")] Xf86driQueryVersion(xf86dri::QueryVersionReply), #[cfg(feature = "xf86dri")] Xf86driQueryDirectRenderingCapable(xf86dri::QueryDirectRenderingCapableReply), #[cfg(feature = "xf86dri")] Xf86driOpenConnection(xf86dri::OpenConnectionReply), #[cfg(feature = "xf86dri")] Xf86driGetClientDriverName(xf86dri::GetClientDriverNameReply), #[cfg(feature = "xf86dri")] Xf86driCreateContext(xf86dri::CreateContextReply), #[cfg(feature = "xf86dri")] Xf86driCreateDrawable(xf86dri::CreateDrawableReply), #[cfg(feature = "xf86dri")] Xf86driGetDrawableInfo(xf86dri::GetDrawableInfoReply), #[cfg(feature = "xf86dri")] Xf86driGetDeviceInfo(xf86dri::GetDeviceInfoReply), #[cfg(feature = "xf86dri")] Xf86driAuthConnection(xf86dri::AuthConnectionReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeQueryVersion(xf86vidmode::QueryVersionReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetModeLine(xf86vidmode::GetModeLineReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetMonitor(xf86vidmode::GetMonitorReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetAllModeLines(xf86vidmode::GetAllModeLinesReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeValidateModeLine(xf86vidmode::ValidateModeLineReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetViewPort(xf86vidmode::GetViewPortReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetDotClocks(xf86vidmode::GetDotClocksReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetGamma(xf86vidmode::GetGammaReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetGammaRamp(xf86vidmode::GetGammaRampReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetGammaRampSize(xf86vidmode::GetGammaRampSizeReply), #[cfg(feature = "xf86vidmode")] Xf86vidmodeGetPermissions(xf86vidmode::GetPermissionsReply), #[cfg(feature = "xfixes")] XfixesQueryVersion(xfixes::QueryVersionReply), #[cfg(feature = "xfixes")] XfixesGetCursorImage(xfixes::GetCursorImageReply), #[cfg(feature = "xfixes")] XfixesFetchRegion(xfixes::FetchRegionReply), #[cfg(feature = "xfixes")] XfixesGetCursorName(xfixes::GetCursorNameReply), #[cfg(feature = "xfixes")] XfixesGetCursorImageAndName(xfixes::GetCursorImageAndNameReply), #[cfg(feature = "xinerama")] XineramaQueryVersion(xinerama::QueryVersionReply), #[cfg(feature = "xinerama")] XineramaGetState(xinerama::GetStateReply), #[cfg(feature = "xinerama")] XineramaGetScreenCount(xinerama::GetScreenCountReply), #[cfg(feature = "xinerama")] XineramaGetScreenSize(xinerama::GetScreenSizeReply), #[cfg(feature = "xinerama")] XineramaIsActive(xinerama::IsActiveReply), #[cfg(feature = "xinerama")] XineramaQueryScreens(xinerama::QueryScreensReply), #[cfg(feature = "xinput")] XinputGetExtensionVersion(xinput::GetExtensionVersionReply), #[cfg(feature = "xinput")] XinputListInputDevices(xinput::ListInputDevicesReply), #[cfg(feature = "xinput")] XinputOpenDevice(xinput::OpenDeviceReply), #[cfg(feature = "xinput")] XinputSetDeviceMode(xinput::SetDeviceModeReply), #[cfg(feature = "xinput")] XinputGetSelectedExtensionEvents(xinput::GetSelectedExtensionEventsReply), #[cfg(feature = "xinput")] XinputGetDeviceDontPropagateList(xinput::GetDeviceDontPropagateListReply), #[cfg(feature = "xinput")] XinputGetDeviceMotionEvents(xinput::GetDeviceMotionEventsReply), #[cfg(feature = "xinput")] XinputChangeKeyboardDevice(xinput::ChangeKeyboardDeviceReply), #[cfg(feature = "xinput")] XinputChangePointerDevice(xinput::ChangePointerDeviceReply), #[cfg(feature = "xinput")] XinputGrabDevice(xinput::GrabDeviceReply), #[cfg(feature = "xinput")] XinputGetDeviceFocus(xinput::GetDeviceFocusReply), #[cfg(feature = "xinput")] XinputGetFeedbackControl(xinput::GetFeedbackControlReply), #[cfg(feature = "xinput")] XinputGetDeviceKeyMapping(xinput::GetDeviceKeyMappingReply), #[cfg(feature = "xinput")] XinputGetDeviceModifierMapping(xinput::GetDeviceModifierMappingReply), #[cfg(feature = "xinput")] XinputSetDeviceModifierMapping(xinput::SetDeviceModifierMappingReply), #[cfg(feature = "xinput")] XinputGetDeviceButtonMapping(xinput::GetDeviceButtonMappingReply), #[cfg(feature = "xinput")] XinputSetDeviceButtonMapping(xinput::SetDeviceButtonMappingReply), #[cfg(feature = "xinput")] XinputQueryDeviceState(xinput::QueryDeviceStateReply), #[cfg(feature = "xinput")] XinputSetDeviceValuators(xinput::SetDeviceValuatorsReply), #[cfg(feature = "xinput")] XinputGetDeviceControl(xinput::GetDeviceControlReply), #[cfg(feature = "xinput")] XinputChangeDeviceControl(xinput::ChangeDeviceControlReply), #[cfg(feature = "xinput")] XinputListDeviceProperties(xinput::ListDevicePropertiesReply), #[cfg(feature = "xinput")] XinputGetDeviceProperty(xinput::GetDevicePropertyReply), #[cfg(feature = "xinput")] XinputXIQueryPointer(xinput::XIQueryPointerReply), #[cfg(feature = "xinput")] XinputXIGetClientPointer(xinput::XIGetClientPointerReply), #[cfg(feature = "xinput")] XinputXIQueryVersion(xinput::XIQueryVersionReply), #[cfg(feature = "xinput")] XinputXIQueryDevice(xinput::XIQueryDeviceReply), #[cfg(feature = "xinput")] XinputXIGetFocus(xinput::XIGetFocusReply), #[cfg(feature = "xinput")] XinputXIGrabDevice(xinput::XIGrabDeviceReply), #[cfg(feature = "xinput")] XinputXIPassiveGrabDevice(xinput::XIPassiveGrabDeviceReply), #[cfg(feature = "xinput")] XinputXIListProperties(xinput::XIListPropertiesReply), #[cfg(feature = "xinput")] XinputXIGetProperty(xinput::XIGetPropertyReply), #[cfg(feature = "xinput")] XinputXIGetSelectedEvents(xinput::XIGetSelectedEventsReply), #[cfg(feature = "xkb")] XkbUseExtension(xkb::UseExtensionReply), #[cfg(feature = "xkb")] XkbGetState(xkb::GetStateReply), #[cfg(feature = "xkb")] XkbGetControls(xkb::GetControlsReply), #[cfg(feature = "xkb")] XkbGetMap(xkb::GetMapReply), #[cfg(feature = "xkb")] XkbGetCompatMap(xkb::GetCompatMapReply), #[cfg(feature = "xkb")] XkbGetIndicatorState(xkb::GetIndicatorStateReply), #[cfg(feature = "xkb")] XkbGetIndicatorMap(xkb::GetIndicatorMapReply), #[cfg(feature = "xkb")] XkbGetNamedIndicator(xkb::GetNamedIndicatorReply), #[cfg(feature = "xkb")] XkbGetNames(xkb::GetNamesReply), #[cfg(feature = "xkb")] XkbPerClientFlags(xkb::PerClientFlagsReply), #[cfg(feature = "xkb")] XkbListComponents(xkb::ListComponentsReply), #[cfg(feature = "xkb")] XkbGetKbdByName(xkb::GetKbdByNameReply), #[cfg(feature = "xkb")] XkbGetDeviceInfo(xkb::GetDeviceInfoReply), #[cfg(feature = "xkb")] XkbSetDebuggingFlags(xkb::SetDebuggingFlagsReply), #[cfg(feature = "xprint")] XprintPrintQueryVersion(xprint::PrintQueryVersionReply), #[cfg(feature = "xprint")] XprintPrintGetPrinterList(xprint::PrintGetPrinterListReply), #[cfg(feature = "xprint")] XprintPrintGetContext(xprint::PrintGetContextReply), #[cfg(feature = "xprint")] XprintPrintGetScreenOfContext(xprint::PrintGetScreenOfContextReply), #[cfg(feature = "xprint")] XprintPrintGetDocumentData(xprint::PrintGetDocumentDataReply), #[cfg(feature = "xprint")] XprintPrintInputSelected(xprint::PrintInputSelectedReply), #[cfg(feature = "xprint")] XprintPrintGetAttributes(xprint::PrintGetAttributesReply), #[cfg(feature = "xprint")] XprintPrintGetOneAttributes(xprint::PrintGetOneAttributesReply), #[cfg(feature = "xprint")] XprintPrintGetPageDimensions(xprint::PrintGetPageDimensionsReply), #[cfg(feature = "xprint")] XprintPrintQueryScreens(xprint::PrintQueryScreensReply), #[cfg(feature = "xprint")] XprintPrintSetImageResolution(xprint::PrintSetImageResolutionReply), #[cfg(feature = "xprint")] XprintPrintGetImageResolution(xprint::PrintGetImageResolutionReply), #[cfg(feature = "xselinux")] XselinuxQueryVersion(xselinux::QueryVersionReply), #[cfg(feature = "xselinux")] XselinuxGetDeviceCreateContext(xselinux::GetDeviceCreateContextReply), #[cfg(feature = "xselinux")] XselinuxGetDeviceContext(xselinux::GetDeviceContextReply), #[cfg(feature = "xselinux")] XselinuxGetWindowCreateContext(xselinux::GetWindowCreateContextReply), #[cfg(feature = "xselinux")] XselinuxGetWindowContext(xselinux::GetWindowContextReply), #[cfg(feature = "xselinux")] XselinuxGetPropertyCreateContext(xselinux::GetPropertyCreateContextReply), #[cfg(feature = "xselinux")] XselinuxGetPropertyUseContext(xselinux::GetPropertyUseContextReply), #[cfg(feature = "xselinux")] XselinuxGetPropertyContext(xselinux::GetPropertyContextReply), #[cfg(feature = "xselinux")] XselinuxGetPropertyDataContext(xselinux::GetPropertyDataContextReply), #[cfg(feature = "xselinux")] XselinuxListProperties(xselinux::ListPropertiesReply), #[cfg(feature = "xselinux")] XselinuxGetSelectionCreateContext(xselinux::GetSelectionCreateContextReply), #[cfg(feature = "xselinux")] XselinuxGetSelectionUseContext(xselinux::GetSelectionUseContextReply), #[cfg(feature = "xselinux")] XselinuxGetSelectionContext(xselinux::GetSelectionContextReply), #[cfg(feature = "xselinux")] XselinuxGetSelectionDataContext(xselinux::GetSelectionDataContextReply), #[cfg(feature = "xselinux")] XselinuxListSelections(xselinux::ListSelectionsReply), #[cfg(feature = "xselinux")] XselinuxGetClientContext(xselinux::GetClientContextReply), #[cfg(feature = "xtest")] XtestGetVersion(xtest::GetVersionReply), #[cfg(feature = "xtest")] XtestCompareCursor(xtest::CompareCursorReply), #[cfg(feature = "xv")] XvQueryExtension(xv::QueryExtensionReply), #[cfg(feature = "xv")] XvQueryAdaptors(xv::QueryAdaptorsReply), #[cfg(feature = "xv")] XvQueryEncodings(xv::QueryEncodingsReply), #[cfg(feature = "xv")] XvGrabPort(xv::GrabPortReply), #[cfg(feature = "xv")] XvQueryBestSize(xv::QueryBestSizeReply), #[cfg(feature = "xv")] XvGetPortAttribute(xv::GetPortAttributeReply), #[cfg(feature = "xv")] XvQueryPortAttributes(xv::QueryPortAttributesReply), #[cfg(feature = "xv")] XvListImageFormats(xv::ListImageFormatsReply), #[cfg(feature = "xv")] XvQueryImageAttributes(xv::QueryImageAttributesReply), #[cfg(feature = "xvmc")] XvmcQueryVersion(xvmc::QueryVersionReply), #[cfg(feature = "xvmc")] XvmcListSurfaceTypes(xvmc::ListSurfaceTypesReply), #[cfg(feature = "xvmc")] XvmcCreateContext(xvmc::CreateContextReply), #[cfg(feature = "xvmc")] XvmcCreateSurface(xvmc::CreateSurfaceReply), #[cfg(feature = "xvmc")] XvmcCreateSubpicture(xvmc::CreateSubpictureReply), #[cfg(feature = "xvmc")] XvmcListSubpictureTypes(xvmc::ListSubpictureTypesReply), } impl From<()> for Reply { fn from(_: ()) -> Reply { Reply::Void } } impl From for Reply { fn from(reply: xproto::GetWindowAttributesReply) -> Reply { Reply::GetWindowAttributes(reply) } } impl From for Reply { fn from(reply: xproto::GetGeometryReply) -> Reply { Reply::GetGeometry(reply) } } impl From for Reply { fn from(reply: xproto::QueryTreeReply) -> Reply { Reply::QueryTree(reply) } } impl From for Reply { fn from(reply: xproto::InternAtomReply) -> Reply { Reply::InternAtom(reply) } } impl From for Reply { fn from(reply: xproto::GetAtomNameReply) -> Reply { Reply::GetAtomName(reply) } } impl From for Reply { fn from(reply: xproto::GetPropertyReply) -> Reply { Reply::GetProperty(reply) } } impl From for Reply { fn from(reply: xproto::ListPropertiesReply) -> Reply { Reply::ListProperties(reply) } } impl From for Reply { fn from(reply: xproto::GetSelectionOwnerReply) -> Reply { Reply::GetSelectionOwner(reply) } } impl From for Reply { fn from(reply: xproto::GrabPointerReply) -> Reply { Reply::GrabPointer(reply) } } impl From for Reply { fn from(reply: xproto::GrabKeyboardReply) -> Reply { Reply::GrabKeyboard(reply) } } impl From for Reply { fn from(reply: xproto::QueryPointerReply) -> Reply { Reply::QueryPointer(reply) } } impl From for Reply { fn from(reply: xproto::GetMotionEventsReply) -> Reply { Reply::GetMotionEvents(reply) } } impl From for Reply { fn from(reply: xproto::TranslateCoordinatesReply) -> Reply { Reply::TranslateCoordinates(reply) } } impl From for Reply { fn from(reply: xproto::GetInputFocusReply) -> Reply { Reply::GetInputFocus(reply) } } impl From for Reply { fn from(reply: xproto::QueryKeymapReply) -> Reply { Reply::QueryKeymap(reply) } } impl From for Reply { fn from(reply: xproto::QueryFontReply) -> Reply { Reply::QueryFont(reply) } } impl From for Reply { fn from(reply: xproto::QueryTextExtentsReply) -> Reply { Reply::QueryTextExtents(reply) } } impl From for Reply { fn from(reply: xproto::ListFontsReply) -> Reply { Reply::ListFonts(reply) } } impl From for Reply { fn from(reply: xproto::ListFontsWithInfoReply) -> Reply { Reply::ListFontsWithInfo(reply) } } impl From for Reply { fn from(reply: xproto::GetFontPathReply) -> Reply { Reply::GetFontPath(reply) } } impl From for Reply { fn from(reply: xproto::GetImageReply) -> Reply { Reply::GetImage(reply) } } impl From for Reply { fn from(reply: xproto::ListInstalledColormapsReply) -> Reply { Reply::ListInstalledColormaps(reply) } } impl From for Reply { fn from(reply: xproto::AllocColorReply) -> Reply { Reply::AllocColor(reply) } } impl From for Reply { fn from(reply: xproto::AllocNamedColorReply) -> Reply { Reply::AllocNamedColor(reply) } } impl From for Reply { fn from(reply: xproto::AllocColorCellsReply) -> Reply { Reply::AllocColorCells(reply) } } impl From for Reply { fn from(reply: xproto::AllocColorPlanesReply) -> Reply { Reply::AllocColorPlanes(reply) } } impl From for Reply { fn from(reply: xproto::QueryColorsReply) -> Reply { Reply::QueryColors(reply) } } impl From for Reply { fn from(reply: xproto::LookupColorReply) -> Reply { Reply::LookupColor(reply) } } impl From for Reply { fn from(reply: xproto::QueryBestSizeReply) -> Reply { Reply::QueryBestSize(reply) } } impl From for Reply { fn from(reply: xproto::QueryExtensionReply) -> Reply { Reply::QueryExtension(reply) } } impl From for Reply { fn from(reply: xproto::ListExtensionsReply) -> Reply { Reply::ListExtensions(reply) } } impl From for Reply { fn from(reply: xproto::GetKeyboardMappingReply) -> Reply { Reply::GetKeyboardMapping(reply) } } impl From for Reply { fn from(reply: xproto::GetKeyboardControlReply) -> Reply { Reply::GetKeyboardControl(reply) } } impl From for Reply { fn from(reply: xproto::GetPointerControlReply) -> Reply { Reply::GetPointerControl(reply) } } impl From for Reply { fn from(reply: xproto::GetScreenSaverReply) -> Reply { Reply::GetScreenSaver(reply) } } impl From for Reply { fn from(reply: xproto::ListHostsReply) -> Reply { Reply::ListHosts(reply) } } impl From for Reply { fn from(reply: xproto::SetPointerMappingReply) -> Reply { Reply::SetPointerMapping(reply) } } impl From for Reply { fn from(reply: xproto::GetPointerMappingReply) -> Reply { Reply::GetPointerMapping(reply) } } impl From for Reply { fn from(reply: xproto::SetModifierMappingReply) -> Reply { Reply::SetModifierMapping(reply) } } impl From for Reply { fn from(reply: xproto::GetModifierMappingReply) -> Reply { Reply::GetModifierMapping(reply) } } impl From for Reply { fn from(reply: bigreq::EnableReply) -> Reply { Reply::BigreqEnable(reply) } } #[cfg(feature = "composite")] impl From for Reply { fn from(reply: composite::QueryVersionReply) -> Reply { Reply::CompositeQueryVersion(reply) } } #[cfg(feature = "composite")] impl From for Reply { fn from(reply: composite::GetOverlayWindowReply) -> Reply { Reply::CompositeGetOverlayWindow(reply) } } #[cfg(feature = "damage")] impl From for Reply { fn from(reply: damage::QueryVersionReply) -> Reply { Reply::DamageQueryVersion(reply) } } #[cfg(feature = "dpms")] impl From for Reply { fn from(reply: dpms::GetVersionReply) -> Reply { Reply::DpmsGetVersion(reply) } } #[cfg(feature = "dpms")] impl From for Reply { fn from(reply: dpms::CapableReply) -> Reply { Reply::DpmsCapable(reply) } } #[cfg(feature = "dpms")] impl From for Reply { fn from(reply: dpms::GetTimeoutsReply) -> Reply { Reply::DpmsGetTimeouts(reply) } } #[cfg(feature = "dpms")] impl From for Reply { fn from(reply: dpms::InfoReply) -> Reply { Reply::DpmsInfo(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::QueryVersionReply) -> Reply { Reply::Dri2QueryVersion(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::ConnectReply) -> Reply { Reply::Dri2Connect(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::AuthenticateReply) -> Reply { Reply::Dri2Authenticate(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::GetBuffersReply) -> Reply { Reply::Dri2GetBuffers(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::CopyRegionReply) -> Reply { Reply::Dri2CopyRegion(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::GetBuffersWithFormatReply) -> Reply { Reply::Dri2GetBuffersWithFormat(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::SwapBuffersReply) -> Reply { Reply::Dri2SwapBuffers(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::GetMSCReply) -> Reply { Reply::Dri2GetMSC(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::WaitMSCReply) -> Reply { Reply::Dri2WaitMSC(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::WaitSBCReply) -> Reply { Reply::Dri2WaitSBC(reply) } } #[cfg(feature = "dri2")] impl From for Reply { fn from(reply: dri2::GetParamReply) -> Reply { Reply::Dri2GetParam(reply) } } #[cfg(feature = "dri3")] impl From for Reply { fn from(reply: dri3::QueryVersionReply) -> Reply { Reply::Dri3QueryVersion(reply) } } #[cfg(feature = "dri3")] impl From for Reply { fn from(reply: dri3::OpenReply) -> Reply { Reply::Dri3Open(reply) } } #[cfg(feature = "dri3")] impl From for Reply { fn from(reply: dri3::BufferFromPixmapReply) -> Reply { Reply::Dri3BufferFromPixmap(reply) } } #[cfg(feature = "dri3")] impl From for Reply { fn from(reply: dri3::FDFromFenceReply) -> Reply { Reply::Dri3FDFromFence(reply) } } #[cfg(feature = "dri3")] impl From for Reply { fn from(reply: dri3::GetSupportedModifiersReply) -> Reply { Reply::Dri3GetSupportedModifiers(reply) } } #[cfg(feature = "dri3")] impl From for Reply { fn from(reply: dri3::BuffersFromPixmapReply) -> Reply { Reply::Dri3BuffersFromPixmap(reply) } } impl From for Reply { fn from(reply: ge::QueryVersionReply) -> Reply { Reply::GeQueryVersion(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::MakeCurrentReply) -> Reply { Reply::GlxMakeCurrent(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::IsDirectReply) -> Reply { Reply::GlxIsDirect(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::QueryVersionReply) -> Reply { Reply::GlxQueryVersion(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetVisualConfigsReply) -> Reply { Reply::GlxGetVisualConfigs(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::VendorPrivateWithReplyReply) -> Reply { Reply::GlxVendorPrivateWithReply(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::QueryExtensionsStringReply) -> Reply { Reply::GlxQueryExtensionsString(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::QueryServerStringReply) -> Reply { Reply::GlxQueryServerString(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetFBConfigsReply) -> Reply { Reply::GlxGetFBConfigs(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::QueryContextReply) -> Reply { Reply::GlxQueryContext(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::MakeContextCurrentReply) -> Reply { Reply::GlxMakeContextCurrent(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetDrawableAttributesReply) -> Reply { Reply::GlxGetDrawableAttributes(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GenListsReply) -> Reply { Reply::GlxGenLists(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::RenderModeReply) -> Reply { Reply::GlxRenderMode(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::FinishReply) -> Reply { Reply::GlxFinish(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::ReadPixelsReply) -> Reply { Reply::GlxReadPixels(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetBooleanvReply) -> Reply { Reply::GlxGetBooleanv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetClipPlaneReply) -> Reply { Reply::GlxGetClipPlane(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetDoublevReply) -> Reply { Reply::GlxGetDoublev(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetErrorReply) -> Reply { Reply::GlxGetError(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetFloatvReply) -> Reply { Reply::GlxGetFloatv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetIntegervReply) -> Reply { Reply::GlxGetIntegerv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetLightfvReply) -> Reply { Reply::GlxGetLightfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetLightivReply) -> Reply { Reply::GlxGetLightiv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMapdvReply) -> Reply { Reply::GlxGetMapdv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMapfvReply) -> Reply { Reply::GlxGetMapfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMapivReply) -> Reply { Reply::GlxGetMapiv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMaterialfvReply) -> Reply { Reply::GlxGetMaterialfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMaterialivReply) -> Reply { Reply::GlxGetMaterialiv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetPixelMapfvReply) -> Reply { Reply::GlxGetPixelMapfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetPixelMapuivReply) -> Reply { Reply::GlxGetPixelMapuiv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetPixelMapusvReply) -> Reply { Reply::GlxGetPixelMapusv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetPolygonStippleReply) -> Reply { Reply::GlxGetPolygonStipple(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetStringReply) -> Reply { Reply::GlxGetString(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexEnvfvReply) -> Reply { Reply::GlxGetTexEnvfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexEnvivReply) -> Reply { Reply::GlxGetTexEnviv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexGendvReply) -> Reply { Reply::GlxGetTexGendv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexGenfvReply) -> Reply { Reply::GlxGetTexGenfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexGenivReply) -> Reply { Reply::GlxGetTexGeniv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexImageReply) -> Reply { Reply::GlxGetTexImage(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexParameterfvReply) -> Reply { Reply::GlxGetTexParameterfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexParameterivReply) -> Reply { Reply::GlxGetTexParameteriv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexLevelParameterfvReply) -> Reply { Reply::GlxGetTexLevelParameterfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetTexLevelParameterivReply) -> Reply { Reply::GlxGetTexLevelParameteriv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::IsEnabledReply) -> Reply { Reply::GlxIsEnabled(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::IsListReply) -> Reply { Reply::GlxIsList(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::AreTexturesResidentReply) -> Reply { Reply::GlxAreTexturesResident(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GenTexturesReply) -> Reply { Reply::GlxGenTextures(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::IsTextureReply) -> Reply { Reply::GlxIsTexture(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetColorTableReply) -> Reply { Reply::GlxGetColorTable(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetColorTableParameterfvReply) -> Reply { Reply::GlxGetColorTableParameterfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetColorTableParameterivReply) -> Reply { Reply::GlxGetColorTableParameteriv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetConvolutionFilterReply) -> Reply { Reply::GlxGetConvolutionFilter(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetConvolutionParameterfvReply) -> Reply { Reply::GlxGetConvolutionParameterfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetConvolutionParameterivReply) -> Reply { Reply::GlxGetConvolutionParameteriv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetSeparableFilterReply) -> Reply { Reply::GlxGetSeparableFilter(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetHistogramReply) -> Reply { Reply::GlxGetHistogram(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetHistogramParameterfvReply) -> Reply { Reply::GlxGetHistogramParameterfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetHistogramParameterivReply) -> Reply { Reply::GlxGetHistogramParameteriv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMinmaxReply) -> Reply { Reply::GlxGetMinmax(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMinmaxParameterfvReply) -> Reply { Reply::GlxGetMinmaxParameterfv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetMinmaxParameterivReply) -> Reply { Reply::GlxGetMinmaxParameteriv(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetCompressedTexImageARBReply) -> Reply { Reply::GlxGetCompressedTexImageARB(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GenQueriesARBReply) -> Reply { Reply::GlxGenQueriesARB(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::IsQueryARBReply) -> Reply { Reply::GlxIsQueryARB(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetQueryivARBReply) -> Reply { Reply::GlxGetQueryivARB(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetQueryObjectivARBReply) -> Reply { Reply::GlxGetQueryObjectivARB(reply) } } #[cfg(feature = "glx")] impl From for Reply { fn from(reply: glx::GetQueryObjectuivARBReply) -> Reply { Reply::GlxGetQueryObjectuivARB(reply) } } #[cfg(feature = "present")] impl From for Reply { fn from(reply: present::QueryVersionReply) -> Reply { Reply::PresentQueryVersion(reply) } } #[cfg(feature = "present")] impl From for Reply { fn from(reply: present::QueryCapabilitiesReply) -> Reply { Reply::PresentQueryCapabilities(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::QueryVersionReply) -> Reply { Reply::RandrQueryVersion(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::SetScreenConfigReply) -> Reply { Reply::RandrSetScreenConfig(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetScreenInfoReply) -> Reply { Reply::RandrGetScreenInfo(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetScreenSizeRangeReply) -> Reply { Reply::RandrGetScreenSizeRange(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetScreenResourcesReply) -> Reply { Reply::RandrGetScreenResources(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetOutputInfoReply) -> Reply { Reply::RandrGetOutputInfo(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::ListOutputPropertiesReply) -> Reply { Reply::RandrListOutputProperties(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::QueryOutputPropertyReply) -> Reply { Reply::RandrQueryOutputProperty(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetOutputPropertyReply) -> Reply { Reply::RandrGetOutputProperty(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::CreateModeReply) -> Reply { Reply::RandrCreateMode(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetCrtcInfoReply) -> Reply { Reply::RandrGetCrtcInfo(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::SetCrtcConfigReply) -> Reply { Reply::RandrSetCrtcConfig(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetCrtcGammaSizeReply) -> Reply { Reply::RandrGetCrtcGammaSize(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetCrtcGammaReply) -> Reply { Reply::RandrGetCrtcGamma(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetScreenResourcesCurrentReply) -> Reply { Reply::RandrGetScreenResourcesCurrent(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetCrtcTransformReply) -> Reply { Reply::RandrGetCrtcTransform(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetPanningReply) -> Reply { Reply::RandrGetPanning(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::SetPanningReply) -> Reply { Reply::RandrSetPanning(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetOutputPrimaryReply) -> Reply { Reply::RandrGetOutputPrimary(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetProvidersReply) -> Reply { Reply::RandrGetProviders(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetProviderInfoReply) -> Reply { Reply::RandrGetProviderInfo(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::ListProviderPropertiesReply) -> Reply { Reply::RandrListProviderProperties(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::QueryProviderPropertyReply) -> Reply { Reply::RandrQueryProviderProperty(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetProviderPropertyReply) -> Reply { Reply::RandrGetProviderProperty(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::GetMonitorsReply) -> Reply { Reply::RandrGetMonitors(reply) } } #[cfg(feature = "randr")] impl From for Reply { fn from(reply: randr::CreateLeaseReply) -> Reply { Reply::RandrCreateLease(reply) } } #[cfg(feature = "record")] impl From for Reply { fn from(reply: record::QueryVersionReply) -> Reply { Reply::RecordQueryVersion(reply) } } #[cfg(feature = "record")] impl From for Reply { fn from(reply: record::GetContextReply) -> Reply { Reply::RecordGetContext(reply) } } #[cfg(feature = "record")] impl From for Reply { fn from(reply: record::EnableContextReply) -> Reply { Reply::RecordEnableContext(reply) } } #[cfg(feature = "render")] impl From for Reply { fn from(reply: render::QueryVersionReply) -> Reply { Reply::RenderQueryVersion(reply) } } #[cfg(feature = "render")] impl From for Reply { fn from(reply: render::QueryPictFormatsReply) -> Reply { Reply::RenderQueryPictFormats(reply) } } #[cfg(feature = "render")] impl From for Reply { fn from(reply: render::QueryPictIndexValuesReply) -> Reply { Reply::RenderQueryPictIndexValues(reply) } } #[cfg(feature = "render")] impl From for Reply { fn from(reply: render::QueryFiltersReply) -> Reply { Reply::RenderQueryFilters(reply) } } #[cfg(feature = "res")] impl From for Reply { fn from(reply: res::QueryVersionReply) -> Reply { Reply::ResQueryVersion(reply) } } #[cfg(feature = "res")] impl From for Reply { fn from(reply: res::QueryClientsReply) -> Reply { Reply::ResQueryClients(reply) } } #[cfg(feature = "res")] impl From for Reply { fn from(reply: res::QueryClientResourcesReply) -> Reply { Reply::ResQueryClientResources(reply) } } #[cfg(feature = "res")] impl From for Reply { fn from(reply: res::QueryClientPixmapBytesReply) -> Reply { Reply::ResQueryClientPixmapBytes(reply) } } #[cfg(feature = "res")] impl From for Reply { fn from(reply: res::QueryClientIdsReply) -> Reply { Reply::ResQueryClientIds(reply) } } #[cfg(feature = "res")] impl From for Reply { fn from(reply: res::QueryResourceBytesReply) -> Reply { Reply::ResQueryResourceBytes(reply) } } #[cfg(feature = "screensaver")] impl From for Reply { fn from(reply: screensaver::QueryVersionReply) -> Reply { Reply::ScreensaverQueryVersion(reply) } } #[cfg(feature = "screensaver")] impl From for Reply { fn from(reply: screensaver::QueryInfoReply) -> Reply { Reply::ScreensaverQueryInfo(reply) } } #[cfg(feature = "shape")] impl From for Reply { fn from(reply: shape::QueryVersionReply) -> Reply { Reply::ShapeQueryVersion(reply) } } #[cfg(feature = "shape")] impl From for Reply { fn from(reply: shape::QueryExtentsReply) -> Reply { Reply::ShapeQueryExtents(reply) } } #[cfg(feature = "shape")] impl From for Reply { fn from(reply: shape::InputSelectedReply) -> Reply { Reply::ShapeInputSelected(reply) } } #[cfg(feature = "shape")] impl From for Reply { fn from(reply: shape::GetRectanglesReply) -> Reply { Reply::ShapeGetRectangles(reply) } } #[cfg(feature = "shm")] impl From for Reply { fn from(reply: shm::QueryVersionReply) -> Reply { Reply::ShmQueryVersion(reply) } } #[cfg(feature = "shm")] impl From for Reply { fn from(reply: shm::GetImageReply) -> Reply { Reply::ShmGetImage(reply) } } #[cfg(feature = "shm")] impl From for Reply { fn from(reply: shm::CreateSegmentReply) -> Reply { Reply::ShmCreateSegment(reply) } } #[cfg(feature = "sync")] impl From for Reply { fn from(reply: sync::InitializeReply) -> Reply { Reply::SyncInitialize(reply) } } #[cfg(feature = "sync")] impl From for Reply { fn from(reply: sync::ListSystemCountersReply) -> Reply { Reply::SyncListSystemCounters(reply) } } #[cfg(feature = "sync")] impl From for Reply { fn from(reply: sync::QueryCounterReply) -> Reply { Reply::SyncQueryCounter(reply) } } #[cfg(feature = "sync")] impl From for Reply { fn from(reply: sync::QueryAlarmReply) -> Reply { Reply::SyncQueryAlarm(reply) } } #[cfg(feature = "sync")] impl From for Reply { fn from(reply: sync::GetPriorityReply) -> Reply { Reply::SyncGetPriority(reply) } } #[cfg(feature = "sync")] impl From for Reply { fn from(reply: sync::QueryFenceReply) -> Reply { Reply::SyncQueryFence(reply) } } impl From for Reply { fn from(reply: xc_misc::GetVersionReply) -> Reply { Reply::XcMiscGetVersion(reply) } } impl From for Reply { fn from(reply: xc_misc::GetXIDRangeReply) -> Reply { Reply::XcMiscGetXIDRange(reply) } } impl From for Reply { fn from(reply: xc_misc::GetXIDListReply) -> Reply { Reply::XcMiscGetXIDList(reply) } } #[cfg(feature = "xevie")] impl From for Reply { fn from(reply: xevie::QueryVersionReply) -> Reply { Reply::XevieQueryVersion(reply) } } #[cfg(feature = "xevie")] impl From for Reply { fn from(reply: xevie::StartReply) -> Reply { Reply::XevieStart(reply) } } #[cfg(feature = "xevie")] impl From for Reply { fn from(reply: xevie::EndReply) -> Reply { Reply::XevieEnd(reply) } } #[cfg(feature = "xevie")] impl From for Reply { fn from(reply: xevie::SendReply) -> Reply { Reply::XevieSend(reply) } } #[cfg(feature = "xevie")] impl From for Reply { fn from(reply: xevie::SelectInputReply) -> Reply { Reply::XevieSelectInput(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::QueryVersionReply) -> Reply { Reply::Xf86driQueryVersion(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::QueryDirectRenderingCapableReply) -> Reply { Reply::Xf86driQueryDirectRenderingCapable(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::OpenConnectionReply) -> Reply { Reply::Xf86driOpenConnection(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::GetClientDriverNameReply) -> Reply { Reply::Xf86driGetClientDriverName(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::CreateContextReply) -> Reply { Reply::Xf86driCreateContext(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::CreateDrawableReply) -> Reply { Reply::Xf86driCreateDrawable(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::GetDrawableInfoReply) -> Reply { Reply::Xf86driGetDrawableInfo(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::GetDeviceInfoReply) -> Reply { Reply::Xf86driGetDeviceInfo(reply) } } #[cfg(feature = "xf86dri")] impl From for Reply { fn from(reply: xf86dri::AuthConnectionReply) -> Reply { Reply::Xf86driAuthConnection(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::QueryVersionReply) -> Reply { Reply::Xf86vidmodeQueryVersion(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetModeLineReply) -> Reply { Reply::Xf86vidmodeGetModeLine(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetMonitorReply) -> Reply { Reply::Xf86vidmodeGetMonitor(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetAllModeLinesReply) -> Reply { Reply::Xf86vidmodeGetAllModeLines(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::ValidateModeLineReply) -> Reply { Reply::Xf86vidmodeValidateModeLine(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetViewPortReply) -> Reply { Reply::Xf86vidmodeGetViewPort(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetDotClocksReply) -> Reply { Reply::Xf86vidmodeGetDotClocks(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetGammaReply) -> Reply { Reply::Xf86vidmodeGetGamma(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetGammaRampReply) -> Reply { Reply::Xf86vidmodeGetGammaRamp(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetGammaRampSizeReply) -> Reply { Reply::Xf86vidmodeGetGammaRampSize(reply) } } #[cfg(feature = "xf86vidmode")] impl From for Reply { fn from(reply: xf86vidmode::GetPermissionsReply) -> Reply { Reply::Xf86vidmodeGetPermissions(reply) } } #[cfg(feature = "xfixes")] impl From for Reply { fn from(reply: xfixes::QueryVersionReply) -> Reply { Reply::XfixesQueryVersion(reply) } } #[cfg(feature = "xfixes")] impl From for Reply { fn from(reply: xfixes::GetCursorImageReply) -> Reply { Reply::XfixesGetCursorImage(reply) } } #[cfg(feature = "xfixes")] impl From for Reply { fn from(reply: xfixes::FetchRegionReply) -> Reply { Reply::XfixesFetchRegion(reply) } } #[cfg(feature = "xfixes")] impl From for Reply { fn from(reply: xfixes::GetCursorNameReply) -> Reply { Reply::XfixesGetCursorName(reply) } } #[cfg(feature = "xfixes")] impl From for Reply { fn from(reply: xfixes::GetCursorImageAndNameReply) -> Reply { Reply::XfixesGetCursorImageAndName(reply) } } #[cfg(feature = "xinerama")] impl From for Reply { fn from(reply: xinerama::QueryVersionReply) -> Reply { Reply::XineramaQueryVersion(reply) } } #[cfg(feature = "xinerama")] impl From for Reply { fn from(reply: xinerama::GetStateReply) -> Reply { Reply::XineramaGetState(reply) } } #[cfg(feature = "xinerama")] impl From for Reply { fn from(reply: xinerama::GetScreenCountReply) -> Reply { Reply::XineramaGetScreenCount(reply) } } #[cfg(feature = "xinerama")] impl From for Reply { fn from(reply: xinerama::GetScreenSizeReply) -> Reply { Reply::XineramaGetScreenSize(reply) } } #[cfg(feature = "xinerama")] impl From for Reply { fn from(reply: xinerama::IsActiveReply) -> Reply { Reply::XineramaIsActive(reply) } } #[cfg(feature = "xinerama")] impl From for Reply { fn from(reply: xinerama::QueryScreensReply) -> Reply { Reply::XineramaQueryScreens(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetExtensionVersionReply) -> Reply { Reply::XinputGetExtensionVersion(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::ListInputDevicesReply) -> Reply { Reply::XinputListInputDevices(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::OpenDeviceReply) -> Reply { Reply::XinputOpenDevice(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::SetDeviceModeReply) -> Reply { Reply::XinputSetDeviceMode(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetSelectedExtensionEventsReply) -> Reply { Reply::XinputGetSelectedExtensionEvents(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDeviceDontPropagateListReply) -> Reply { Reply::XinputGetDeviceDontPropagateList(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDeviceMotionEventsReply) -> Reply { Reply::XinputGetDeviceMotionEvents(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::ChangeKeyboardDeviceReply) -> Reply { Reply::XinputChangeKeyboardDevice(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::ChangePointerDeviceReply) -> Reply { Reply::XinputChangePointerDevice(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GrabDeviceReply) -> Reply { Reply::XinputGrabDevice(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDeviceFocusReply) -> Reply { Reply::XinputGetDeviceFocus(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetFeedbackControlReply) -> Reply { Reply::XinputGetFeedbackControl(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDeviceKeyMappingReply) -> Reply { Reply::XinputGetDeviceKeyMapping(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDeviceModifierMappingReply) -> Reply { Reply::XinputGetDeviceModifierMapping(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::SetDeviceModifierMappingReply) -> Reply { Reply::XinputSetDeviceModifierMapping(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDeviceButtonMappingReply) -> Reply { Reply::XinputGetDeviceButtonMapping(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::SetDeviceButtonMappingReply) -> Reply { Reply::XinputSetDeviceButtonMapping(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::QueryDeviceStateReply) -> Reply { Reply::XinputQueryDeviceState(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::SetDeviceValuatorsReply) -> Reply { Reply::XinputSetDeviceValuators(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDeviceControlReply) -> Reply { Reply::XinputGetDeviceControl(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::ChangeDeviceControlReply) -> Reply { Reply::XinputChangeDeviceControl(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::ListDevicePropertiesReply) -> Reply { Reply::XinputListDeviceProperties(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::GetDevicePropertyReply) -> Reply { Reply::XinputGetDeviceProperty(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIQueryPointerReply) -> Reply { Reply::XinputXIQueryPointer(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIGetClientPointerReply) -> Reply { Reply::XinputXIGetClientPointer(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIQueryVersionReply) -> Reply { Reply::XinputXIQueryVersion(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIQueryDeviceReply) -> Reply { Reply::XinputXIQueryDevice(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIGetFocusReply) -> Reply { Reply::XinputXIGetFocus(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIGrabDeviceReply) -> Reply { Reply::XinputXIGrabDevice(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIPassiveGrabDeviceReply) -> Reply { Reply::XinputXIPassiveGrabDevice(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIListPropertiesReply) -> Reply { Reply::XinputXIListProperties(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIGetPropertyReply) -> Reply { Reply::XinputXIGetProperty(reply) } } #[cfg(feature = "xinput")] impl From for Reply { fn from(reply: xinput::XIGetSelectedEventsReply) -> Reply { Reply::XinputXIGetSelectedEvents(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::UseExtensionReply) -> Reply { Reply::XkbUseExtension(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetStateReply) -> Reply { Reply::XkbGetState(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetControlsReply) -> Reply { Reply::XkbGetControls(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetMapReply) -> Reply { Reply::XkbGetMap(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetCompatMapReply) -> Reply { Reply::XkbGetCompatMap(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetIndicatorStateReply) -> Reply { Reply::XkbGetIndicatorState(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetIndicatorMapReply) -> Reply { Reply::XkbGetIndicatorMap(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetNamedIndicatorReply) -> Reply { Reply::XkbGetNamedIndicator(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetNamesReply) -> Reply { Reply::XkbGetNames(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::PerClientFlagsReply) -> Reply { Reply::XkbPerClientFlags(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::ListComponentsReply) -> Reply { Reply::XkbListComponents(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetKbdByNameReply) -> Reply { Reply::XkbGetKbdByName(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::GetDeviceInfoReply) -> Reply { Reply::XkbGetDeviceInfo(reply) } } #[cfg(feature = "xkb")] impl From for Reply { fn from(reply: xkb::SetDebuggingFlagsReply) -> Reply { Reply::XkbSetDebuggingFlags(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintQueryVersionReply) -> Reply { Reply::XprintPrintQueryVersion(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetPrinterListReply) -> Reply { Reply::XprintPrintGetPrinterList(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetContextReply) -> Reply { Reply::XprintPrintGetContext(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetScreenOfContextReply) -> Reply { Reply::XprintPrintGetScreenOfContext(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetDocumentDataReply) -> Reply { Reply::XprintPrintGetDocumentData(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintInputSelectedReply) -> Reply { Reply::XprintPrintInputSelected(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetAttributesReply) -> Reply { Reply::XprintPrintGetAttributes(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetOneAttributesReply) -> Reply { Reply::XprintPrintGetOneAttributes(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetPageDimensionsReply) -> Reply { Reply::XprintPrintGetPageDimensions(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintQueryScreensReply) -> Reply { Reply::XprintPrintQueryScreens(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintSetImageResolutionReply) -> Reply { Reply::XprintPrintSetImageResolution(reply) } } #[cfg(feature = "xprint")] impl From for Reply { fn from(reply: xprint::PrintGetImageResolutionReply) -> Reply { Reply::XprintPrintGetImageResolution(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::QueryVersionReply) -> Reply { Reply::XselinuxQueryVersion(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetDeviceCreateContextReply) -> Reply { Reply::XselinuxGetDeviceCreateContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetDeviceContextReply) -> Reply { Reply::XselinuxGetDeviceContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetWindowCreateContextReply) -> Reply { Reply::XselinuxGetWindowCreateContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetWindowContextReply) -> Reply { Reply::XselinuxGetWindowContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetPropertyCreateContextReply) -> Reply { Reply::XselinuxGetPropertyCreateContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetPropertyUseContextReply) -> Reply { Reply::XselinuxGetPropertyUseContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetPropertyContextReply) -> Reply { Reply::XselinuxGetPropertyContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetPropertyDataContextReply) -> Reply { Reply::XselinuxGetPropertyDataContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::ListPropertiesReply) -> Reply { Reply::XselinuxListProperties(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetSelectionCreateContextReply) -> Reply { Reply::XselinuxGetSelectionCreateContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetSelectionUseContextReply) -> Reply { Reply::XselinuxGetSelectionUseContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetSelectionContextReply) -> Reply { Reply::XselinuxGetSelectionContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetSelectionDataContextReply) -> Reply { Reply::XselinuxGetSelectionDataContext(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::ListSelectionsReply) -> Reply { Reply::XselinuxListSelections(reply) } } #[cfg(feature = "xselinux")] impl From for Reply { fn from(reply: xselinux::GetClientContextReply) -> Reply { Reply::XselinuxGetClientContext(reply) } } #[cfg(feature = "xtest")] impl From for Reply { fn from(reply: xtest::GetVersionReply) -> Reply { Reply::XtestGetVersion(reply) } } #[cfg(feature = "xtest")] impl From for Reply { fn from(reply: xtest::CompareCursorReply) -> Reply { Reply::XtestCompareCursor(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::QueryExtensionReply) -> Reply { Reply::XvQueryExtension(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::QueryAdaptorsReply) -> Reply { Reply::XvQueryAdaptors(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::QueryEncodingsReply) -> Reply { Reply::XvQueryEncodings(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::GrabPortReply) -> Reply { Reply::XvGrabPort(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::QueryBestSizeReply) -> Reply { Reply::XvQueryBestSize(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::GetPortAttributeReply) -> Reply { Reply::XvGetPortAttribute(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::QueryPortAttributesReply) -> Reply { Reply::XvQueryPortAttributes(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::ListImageFormatsReply) -> Reply { Reply::XvListImageFormats(reply) } } #[cfg(feature = "xv")] impl From for Reply { fn from(reply: xv::QueryImageAttributesReply) -> Reply { Reply::XvQueryImageAttributes(reply) } } #[cfg(feature = "xvmc")] impl From for Reply { fn from(reply: xvmc::QueryVersionReply) -> Reply { Reply::XvmcQueryVersion(reply) } } #[cfg(feature = "xvmc")] impl From for Reply { fn from(reply: xvmc::ListSurfaceTypesReply) -> Reply { Reply::XvmcListSurfaceTypes(reply) } } #[cfg(feature = "xvmc")] impl From for Reply { fn from(reply: xvmc::CreateContextReply) -> Reply { Reply::XvmcCreateContext(reply) } } #[cfg(feature = "xvmc")] impl From for Reply { fn from(reply: xvmc::CreateSurfaceReply) -> Reply { Reply::XvmcCreateSurface(reply) } } #[cfg(feature = "xvmc")] impl From for Reply { fn from(reply: xvmc::CreateSubpictureReply) -> Reply { Reply::XvmcCreateSubpicture(reply) } } #[cfg(feature = "xvmc")] impl From for Reply { fn from(reply: xvmc::ListSubpictureTypesReply) -> Reply { Reply::XvmcListSubpictureTypes(reply) } } /// Enumeration of all possible X11 error kinds. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub enum ErrorKind { Unknown(u8), Access, Alloc, Atom, Colormap, Cursor, Drawable, Font, GContext, IDChoice, Implementation, Length, Match, Name, Pixmap, Request, Value, Window, #[cfg(feature = "damage")] DamageBadDamage, #[cfg(feature = "glx")] GlxBadContext, #[cfg(feature = "glx")] GlxBadContextState, #[cfg(feature = "glx")] GlxBadContextTag, #[cfg(feature = "glx")] GlxBadCurrentDrawable, #[cfg(feature = "glx")] GlxBadCurrentWindow, #[cfg(feature = "glx")] GlxBadDrawable, #[cfg(feature = "glx")] GlxBadFBConfig, #[cfg(feature = "glx")] GlxBadLargeRequest, #[cfg(feature = "glx")] GlxBadPbuffer, #[cfg(feature = "glx")] GlxBadPixmap, #[cfg(feature = "glx")] GlxBadRenderRequest, #[cfg(feature = "glx")] GlxBadWindow, #[cfg(feature = "glx")] GlxGLXBadProfileARB, #[cfg(feature = "glx")] GlxUnsupportedPrivateRequest, #[cfg(feature = "randr")] RandrBadCrtc, #[cfg(feature = "randr")] RandrBadMode, #[cfg(feature = "randr")] RandrBadOutput, #[cfg(feature = "randr")] RandrBadProvider, #[cfg(feature = "record")] RecordBadContext, #[cfg(feature = "render")] RenderGlyph, #[cfg(feature = "render")] RenderGlyphSet, #[cfg(feature = "render")] RenderPictFormat, #[cfg(feature = "render")] RenderPictOp, #[cfg(feature = "render")] RenderPicture, #[cfg(feature = "shm")] ShmBadSeg, #[cfg(feature = "sync")] SyncAlarm, #[cfg(feature = "sync")] SyncCounter, #[cfg(feature = "xf86vidmode")] Xf86vidmodeBadClock, #[cfg(feature = "xf86vidmode")] Xf86vidmodeBadHTimings, #[cfg(feature = "xf86vidmode")] Xf86vidmodeBadVTimings, #[cfg(feature = "xf86vidmode")] Xf86vidmodeClientNotLocal, #[cfg(feature = "xf86vidmode")] Xf86vidmodeExtensionDisabled, #[cfg(feature = "xf86vidmode")] Xf86vidmodeModeUnsuitable, #[cfg(feature = "xf86vidmode")] Xf86vidmodeZoomLocked, #[cfg(feature = "xfixes")] XfixesBadRegion, #[cfg(feature = "xinput")] XinputClass, #[cfg(feature = "xinput")] XinputDevice, #[cfg(feature = "xinput")] XinputDeviceBusy, #[cfg(feature = "xinput")] XinputEvent, #[cfg(feature = "xinput")] XinputMode, #[cfg(feature = "xkb")] XkbKeyboard, #[cfg(feature = "xprint")] XprintBadContext, #[cfg(feature = "xprint")] XprintBadSequence, #[cfg(feature = "xv")] XvBadControl, #[cfg(feature = "xv")] XvBadEncoding, #[cfg(feature = "xv")] XvBadPort, } impl ErrorKind { #[allow(clippy::match_single_binding)] pub fn from_wire_error_code( error_code: u8, ext_info_provider: &dyn ExtInfoProvider, ) -> Self { // Check if this is a core protocol error match error_code { xproto::ACCESS_ERROR => return Self::Access, xproto::ALLOC_ERROR => return Self::Alloc, xproto::ATOM_ERROR => return Self::Atom, xproto::COLORMAP_ERROR => return Self::Colormap, xproto::CURSOR_ERROR => return Self::Cursor, xproto::DRAWABLE_ERROR => return Self::Drawable, xproto::FONT_ERROR => return Self::Font, xproto::G_CONTEXT_ERROR => return Self::GContext, xproto::ID_CHOICE_ERROR => return Self::IDChoice, xproto::IMPLEMENTATION_ERROR => return Self::Implementation, xproto::LENGTH_ERROR => return Self::Length, xproto::MATCH_ERROR => return Self::Match, xproto::NAME_ERROR => return Self::Name, xproto::PIXMAP_ERROR => return Self::Pixmap, xproto::REQUEST_ERROR => return Self::Request, xproto::VALUE_ERROR => return Self::Value, xproto::WINDOW_ERROR => return Self::Window, _ => {} } // Find the extension that this error could belong to let ext_info = ext_info_provider.get_from_error_code(error_code); match ext_info { #[cfg(feature = "damage")] Some((damage::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { damage::BAD_DAMAGE_ERROR => Self::DamageBadDamage, _ => Self::Unknown(error_code), } } #[cfg(feature = "glx")] Some((glx::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { glx::BAD_CONTEXT_ERROR => Self::GlxBadContext, glx::BAD_CONTEXT_STATE_ERROR => Self::GlxBadContextState, glx::BAD_CONTEXT_TAG_ERROR => Self::GlxBadContextTag, glx::BAD_CURRENT_DRAWABLE_ERROR => Self::GlxBadCurrentDrawable, glx::BAD_CURRENT_WINDOW_ERROR => Self::GlxBadCurrentWindow, glx::BAD_DRAWABLE_ERROR => Self::GlxBadDrawable, glx::BAD_FB_CONFIG_ERROR => Self::GlxBadFBConfig, glx::BAD_LARGE_REQUEST_ERROR => Self::GlxBadLargeRequest, glx::BAD_PBUFFER_ERROR => Self::GlxBadPbuffer, glx::BAD_PIXMAP_ERROR => Self::GlxBadPixmap, glx::BAD_RENDER_REQUEST_ERROR => Self::GlxBadRenderRequest, glx::BAD_WINDOW_ERROR => Self::GlxBadWindow, glx::GLX_BAD_PROFILE_ARB_ERROR => Self::GlxGLXBadProfileARB, glx::UNSUPPORTED_PRIVATE_REQUEST_ERROR => Self::GlxUnsupportedPrivateRequest, _ => Self::Unknown(error_code), } } #[cfg(feature = "randr")] Some((randr::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { randr::BAD_CRTC_ERROR => Self::RandrBadCrtc, randr::BAD_MODE_ERROR => Self::RandrBadMode, randr::BAD_OUTPUT_ERROR => Self::RandrBadOutput, randr::BAD_PROVIDER_ERROR => Self::RandrBadProvider, _ => Self::Unknown(error_code), } } #[cfg(feature = "record")] Some((record::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { record::BAD_CONTEXT_ERROR => Self::RecordBadContext, _ => Self::Unknown(error_code), } } #[cfg(feature = "render")] Some((render::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { render::GLYPH_ERROR => Self::RenderGlyph, render::GLYPH_SET_ERROR => Self::RenderGlyphSet, render::PICT_FORMAT_ERROR => Self::RenderPictFormat, render::PICT_OP_ERROR => Self::RenderPictOp, render::PICTURE_ERROR => Self::RenderPicture, _ => Self::Unknown(error_code), } } #[cfg(feature = "shm")] Some((shm::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { shm::BAD_SEG_ERROR => Self::ShmBadSeg, _ => Self::Unknown(error_code), } } #[cfg(feature = "sync")] Some((sync::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { sync::ALARM_ERROR => Self::SyncAlarm, sync::COUNTER_ERROR => Self::SyncCounter, _ => Self::Unknown(error_code), } } #[cfg(feature = "xf86vidmode")] Some((xf86vidmode::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { xf86vidmode::BAD_CLOCK_ERROR => Self::Xf86vidmodeBadClock, xf86vidmode::BAD_H_TIMINGS_ERROR => Self::Xf86vidmodeBadHTimings, xf86vidmode::BAD_V_TIMINGS_ERROR => Self::Xf86vidmodeBadVTimings, xf86vidmode::CLIENT_NOT_LOCAL_ERROR => Self::Xf86vidmodeClientNotLocal, xf86vidmode::EXTENSION_DISABLED_ERROR => Self::Xf86vidmodeExtensionDisabled, xf86vidmode::MODE_UNSUITABLE_ERROR => Self::Xf86vidmodeModeUnsuitable, xf86vidmode::ZOOM_LOCKED_ERROR => Self::Xf86vidmodeZoomLocked, _ => Self::Unknown(error_code), } } #[cfg(feature = "xfixes")] Some((xfixes::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { xfixes::BAD_REGION_ERROR => Self::XfixesBadRegion, _ => Self::Unknown(error_code), } } #[cfg(feature = "xinput")] Some((xinput::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { xinput::CLASS_ERROR => Self::XinputClass, xinput::DEVICE_ERROR => Self::XinputDevice, xinput::DEVICE_BUSY_ERROR => Self::XinputDeviceBusy, xinput::EVENT_ERROR => Self::XinputEvent, xinput::MODE_ERROR => Self::XinputMode, _ => Self::Unknown(error_code), } } #[cfg(feature = "xkb")] Some((xkb::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { xkb::KEYBOARD_ERROR => Self::XkbKeyboard, _ => Self::Unknown(error_code), } } #[cfg(feature = "xprint")] Some((xprint::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { xprint::BAD_CONTEXT_ERROR => Self::XprintBadContext, xprint::BAD_SEQUENCE_ERROR => Self::XprintBadSequence, _ => Self::Unknown(error_code), } } #[cfg(feature = "xv")] Some((xv::X11_EXTENSION_NAME, ext_info)) => { match error_code - ext_info.first_error { xv::BAD_CONTROL_ERROR => Self::XvBadControl, xv::BAD_ENCODING_ERROR => Self::XvBadEncoding, xv::BAD_PORT_ERROR => Self::XvBadPort, _ => Self::Unknown(error_code), } } _ => Self::Unknown(error_code), } } } /// Enumeration of all possible X11 events. #[derive(Debug, Clone)] #[non_exhaustive] pub enum Event { Unknown(Vec), Error(X11Error), ButtonPress(xproto::ButtonPressEvent), ButtonRelease(xproto::ButtonReleaseEvent), CirculateNotify(xproto::CirculateNotifyEvent), CirculateRequest(xproto::CirculateRequestEvent), ClientMessage(xproto::ClientMessageEvent), ColormapNotify(xproto::ColormapNotifyEvent), ConfigureNotify(xproto::ConfigureNotifyEvent), ConfigureRequest(xproto::ConfigureRequestEvent), CreateNotify(xproto::CreateNotifyEvent), DestroyNotify(xproto::DestroyNotifyEvent), EnterNotify(xproto::EnterNotifyEvent), Expose(xproto::ExposeEvent), FocusIn(xproto::FocusInEvent), FocusOut(xproto::FocusOutEvent), GeGeneric(xproto::GeGenericEvent), GraphicsExposure(xproto::GraphicsExposureEvent), GravityNotify(xproto::GravityNotifyEvent), KeyPress(xproto::KeyPressEvent), KeyRelease(xproto::KeyReleaseEvent), KeymapNotify(xproto::KeymapNotifyEvent), LeaveNotify(xproto::LeaveNotifyEvent), MapNotify(xproto::MapNotifyEvent), MapRequest(xproto::MapRequestEvent), MappingNotify(xproto::MappingNotifyEvent), MotionNotify(xproto::MotionNotifyEvent), NoExposure(xproto::NoExposureEvent), PropertyNotify(xproto::PropertyNotifyEvent), ReparentNotify(xproto::ReparentNotifyEvent), ResizeRequest(xproto::ResizeRequestEvent), SelectionClear(xproto::SelectionClearEvent), SelectionNotify(xproto::SelectionNotifyEvent), SelectionRequest(xproto::SelectionRequestEvent), UnmapNotify(xproto::UnmapNotifyEvent), VisibilityNotify(xproto::VisibilityNotifyEvent), #[cfg(feature = "damage")] DamageNotify(damage::NotifyEvent), #[cfg(feature = "dri2")] Dri2BufferSwapComplete(dri2::BufferSwapCompleteEvent), #[cfg(feature = "dri2")] Dri2InvalidateBuffers(dri2::InvalidateBuffersEvent), #[cfg(feature = "glx")] GlxBufferSwapComplete(glx::BufferSwapCompleteEvent), #[cfg(feature = "glx")] GlxPbufferClobber(glx::PbufferClobberEvent), #[cfg(feature = "present")] PresentCompleteNotify(present::CompleteNotifyEvent), #[cfg(feature = "present")] PresentConfigureNotify(present::ConfigureNotifyEvent), #[cfg(feature = "present")] PresentGeneric(present::GenericEvent), #[cfg(feature = "present")] PresentIdleNotify(present::IdleNotifyEvent), #[cfg(feature = "present")] PresentRedirectNotify(present::RedirectNotifyEvent), #[cfg(feature = "randr")] RandrNotify(randr::NotifyEvent), #[cfg(feature = "randr")] RandrScreenChangeNotify(randr::ScreenChangeNotifyEvent), #[cfg(feature = "screensaver")] ScreensaverNotify(screensaver::NotifyEvent), #[cfg(feature = "shape")] ShapeNotify(shape::NotifyEvent), #[cfg(feature = "shm")] ShmCompletion(shm::CompletionEvent), #[cfg(feature = "sync")] SyncAlarmNotify(sync::AlarmNotifyEvent), #[cfg(feature = "sync")] SyncCounterNotify(sync::CounterNotifyEvent), #[cfg(feature = "xfixes")] XfixesCursorNotify(xfixes::CursorNotifyEvent), #[cfg(feature = "xfixes")] XfixesSelectionNotify(xfixes::SelectionNotifyEvent), #[cfg(feature = "xinput")] XinputBarrierHit(xinput::BarrierHitEvent), #[cfg(feature = "xinput")] XinputBarrierLeave(xinput::BarrierLeaveEvent), #[cfg(feature = "xinput")] XinputButtonPress(xinput::ButtonPressEvent), #[cfg(feature = "xinput")] XinputButtonRelease(xinput::ButtonReleaseEvent), #[cfg(feature = "xinput")] XinputChangeDeviceNotify(xinput::ChangeDeviceNotifyEvent), #[cfg(feature = "xinput")] XinputDeviceButtonPress(xinput::DeviceButtonPressEvent), #[cfg(feature = "xinput")] XinputDeviceButtonRelease(xinput::DeviceButtonReleaseEvent), #[cfg(feature = "xinput")] XinputDeviceButtonStateNotify(xinput::DeviceButtonStateNotifyEvent), #[cfg(feature = "xinput")] XinputDeviceChanged(xinput::DeviceChangedEvent), #[cfg(feature = "xinput")] XinputDeviceFocusIn(xinput::DeviceFocusInEvent), #[cfg(feature = "xinput")] XinputDeviceFocusOut(xinput::DeviceFocusOutEvent), #[cfg(feature = "xinput")] XinputDeviceKeyPress(xinput::DeviceKeyPressEvent), #[cfg(feature = "xinput")] XinputDeviceKeyRelease(xinput::DeviceKeyReleaseEvent), #[cfg(feature = "xinput")] XinputDeviceKeyStateNotify(xinput::DeviceKeyStateNotifyEvent), #[cfg(feature = "xinput")] XinputDeviceMappingNotify(xinput::DeviceMappingNotifyEvent), #[cfg(feature = "xinput")] XinputDeviceMotionNotify(xinput::DeviceMotionNotifyEvent), #[cfg(feature = "xinput")] XinputDevicePresenceNotify(xinput::DevicePresenceNotifyEvent), #[cfg(feature = "xinput")] XinputDevicePropertyNotify(xinput::DevicePropertyNotifyEvent), #[cfg(feature = "xinput")] XinputDeviceStateNotify(xinput::DeviceStateNotifyEvent), #[cfg(feature = "xinput")] XinputDeviceValuator(xinput::DeviceValuatorEvent), #[cfg(feature = "xinput")] XinputEnter(xinput::EnterEvent), #[cfg(feature = "xinput")] XinputFocusIn(xinput::FocusInEvent), #[cfg(feature = "xinput")] XinputFocusOut(xinput::FocusOutEvent), #[cfg(feature = "xinput")] XinputHierarchy(xinput::HierarchyEvent), #[cfg(feature = "xinput")] XinputKeyPress(xinput::KeyPressEvent), #[cfg(feature = "xinput")] XinputKeyRelease(xinput::KeyReleaseEvent), #[cfg(feature = "xinput")] XinputLeave(xinput::LeaveEvent), #[cfg(feature = "xinput")] XinputMotion(xinput::MotionEvent), #[cfg(feature = "xinput")] XinputProperty(xinput::PropertyEvent), #[cfg(feature = "xinput")] XinputProximityIn(xinput::ProximityInEvent), #[cfg(feature = "xinput")] XinputProximityOut(xinput::ProximityOutEvent), #[cfg(feature = "xinput")] XinputRawButtonPress(xinput::RawButtonPressEvent), #[cfg(feature = "xinput")] XinputRawButtonRelease(xinput::RawButtonReleaseEvent), #[cfg(feature = "xinput")] XinputRawKeyPress(xinput::RawKeyPressEvent), #[cfg(feature = "xinput")] XinputRawKeyRelease(xinput::RawKeyReleaseEvent), #[cfg(feature = "xinput")] XinputRawMotion(xinput::RawMotionEvent), #[cfg(feature = "xinput")] XinputRawTouchBegin(xinput::RawTouchBeginEvent), #[cfg(feature = "xinput")] XinputRawTouchEnd(xinput::RawTouchEndEvent), #[cfg(feature = "xinput")] XinputRawTouchUpdate(xinput::RawTouchUpdateEvent), #[cfg(feature = "xinput")] XinputTouchBegin(xinput::TouchBeginEvent), #[cfg(feature = "xinput")] XinputTouchEnd(xinput::TouchEndEvent), #[cfg(feature = "xinput")] XinputTouchOwnership(xinput::TouchOwnershipEvent), #[cfg(feature = "xinput")] XinputTouchUpdate(xinput::TouchUpdateEvent), #[cfg(feature = "xkb")] XkbAccessXNotify(xkb::AccessXNotifyEvent), #[cfg(feature = "xkb")] XkbActionMessage(xkb::ActionMessageEvent), #[cfg(feature = "xkb")] XkbBellNotify(xkb::BellNotifyEvent), #[cfg(feature = "xkb")] XkbCompatMapNotify(xkb::CompatMapNotifyEvent), #[cfg(feature = "xkb")] XkbControlsNotify(xkb::ControlsNotifyEvent), #[cfg(feature = "xkb")] XkbExtensionDeviceNotify(xkb::ExtensionDeviceNotifyEvent), #[cfg(feature = "xkb")] XkbIndicatorMapNotify(xkb::IndicatorMapNotifyEvent), #[cfg(feature = "xkb")] XkbIndicatorStateNotify(xkb::IndicatorStateNotifyEvent), #[cfg(feature = "xkb")] XkbMapNotify(xkb::MapNotifyEvent), #[cfg(feature = "xkb")] XkbNamesNotify(xkb::NamesNotifyEvent), #[cfg(feature = "xkb")] XkbNewKeyboardNotify(xkb::NewKeyboardNotifyEvent), #[cfg(feature = "xkb")] XkbStateNotify(xkb::StateNotifyEvent), #[cfg(feature = "xprint")] XprintAttributNotify(xprint::AttributNotifyEvent), #[cfg(feature = "xprint")] XprintNotify(xprint::NotifyEvent), #[cfg(feature = "xv")] XvPortNotify(xv::PortNotifyEvent), #[cfg(feature = "xv")] XvVideoNotify(xv::VideoNotifyEvent), } impl Event { /// Parse a generic X11 event into a concrete event type. #[allow(clippy::cognitive_complexity, clippy::match_single_binding)] pub fn parse( event: &[u8], ext_info_provider: &dyn ExtInfoProvider, ) -> Result { let event_code = response_type(event)?; // Check if this is a core protocol event or error, or from the generic event extension match event_code { 0 => return Ok(Self::Error(X11Error::try_parse(event, ext_info_provider)?)), xproto::BUTTON_PRESS_EVENT => return Ok(Self::ButtonPress(TryParse::try_parse(event)?.0)), xproto::BUTTON_RELEASE_EVENT => return Ok(Self::ButtonRelease(TryParse::try_parse(event)?.0)), xproto::CIRCULATE_NOTIFY_EVENT => return Ok(Self::CirculateNotify(TryParse::try_parse(event)?.0)), xproto::CIRCULATE_REQUEST_EVENT => return Ok(Self::CirculateRequest(TryParse::try_parse(event)?.0)), xproto::CLIENT_MESSAGE_EVENT => return Ok(Self::ClientMessage(TryParse::try_parse(event)?.0)), xproto::COLORMAP_NOTIFY_EVENT => return Ok(Self::ColormapNotify(TryParse::try_parse(event)?.0)), xproto::CONFIGURE_NOTIFY_EVENT => return Ok(Self::ConfigureNotify(TryParse::try_parse(event)?.0)), xproto::CONFIGURE_REQUEST_EVENT => return Ok(Self::ConfigureRequest(TryParse::try_parse(event)?.0)), xproto::CREATE_NOTIFY_EVENT => return Ok(Self::CreateNotify(TryParse::try_parse(event)?.0)), xproto::DESTROY_NOTIFY_EVENT => return Ok(Self::DestroyNotify(TryParse::try_parse(event)?.0)), xproto::ENTER_NOTIFY_EVENT => return Ok(Self::EnterNotify(TryParse::try_parse(event)?.0)), xproto::EXPOSE_EVENT => return Ok(Self::Expose(TryParse::try_parse(event)?.0)), xproto::FOCUS_IN_EVENT => return Ok(Self::FocusIn(TryParse::try_parse(event)?.0)), xproto::FOCUS_OUT_EVENT => return Ok(Self::FocusOut(TryParse::try_parse(event)?.0)), xproto::GRAPHICS_EXPOSURE_EVENT => return Ok(Self::GraphicsExposure(TryParse::try_parse(event)?.0)), xproto::GRAVITY_NOTIFY_EVENT => return Ok(Self::GravityNotify(TryParse::try_parse(event)?.0)), xproto::KEY_PRESS_EVENT => return Ok(Self::KeyPress(TryParse::try_parse(event)?.0)), xproto::KEY_RELEASE_EVENT => return Ok(Self::KeyRelease(TryParse::try_parse(event)?.0)), xproto::KEYMAP_NOTIFY_EVENT => return Ok(Self::KeymapNotify(TryParse::try_parse(event)?.0)), xproto::LEAVE_NOTIFY_EVENT => return Ok(Self::LeaveNotify(TryParse::try_parse(event)?.0)), xproto::MAP_NOTIFY_EVENT => return Ok(Self::MapNotify(TryParse::try_parse(event)?.0)), xproto::MAP_REQUEST_EVENT => return Ok(Self::MapRequest(TryParse::try_parse(event)?.0)), xproto::MAPPING_NOTIFY_EVENT => return Ok(Self::MappingNotify(TryParse::try_parse(event)?.0)), xproto::MOTION_NOTIFY_EVENT => return Ok(Self::MotionNotify(TryParse::try_parse(event)?.0)), xproto::NO_EXPOSURE_EVENT => return Ok(Self::NoExposure(TryParse::try_parse(event)?.0)), xproto::PROPERTY_NOTIFY_EVENT => return Ok(Self::PropertyNotify(TryParse::try_parse(event)?.0)), xproto::REPARENT_NOTIFY_EVENT => return Ok(Self::ReparentNotify(TryParse::try_parse(event)?.0)), xproto::RESIZE_REQUEST_EVENT => return Ok(Self::ResizeRequest(TryParse::try_parse(event)?.0)), xproto::SELECTION_CLEAR_EVENT => return Ok(Self::SelectionClear(TryParse::try_parse(event)?.0)), xproto::SELECTION_NOTIFY_EVENT => return Ok(Self::SelectionNotify(TryParse::try_parse(event)?.0)), xproto::SELECTION_REQUEST_EVENT => return Ok(Self::SelectionRequest(TryParse::try_parse(event)?.0)), xproto::UNMAP_NOTIFY_EVENT => return Ok(Self::UnmapNotify(TryParse::try_parse(event)?.0)), xproto::VISIBILITY_NOTIFY_EVENT => return Ok(Self::VisibilityNotify(TryParse::try_parse(event)?.0)), xproto::GE_GENERIC_EVENT => return Self::from_generic_event(event, ext_info_provider), _ => {} } // Find the extension that this event could belong to let ext_info = ext_info_provider.get_from_event_code(event_code); match ext_info { #[cfg(feature = "damage")] Some((damage::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { damage::NOTIFY_EVENT => Ok(Self::DamageNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "dri2")] Some((dri2::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { dri2::BUFFER_SWAP_COMPLETE_EVENT => Ok(Self::Dri2BufferSwapComplete(TryParse::try_parse(event)?.0)), dri2::INVALIDATE_BUFFERS_EVENT => Ok(Self::Dri2InvalidateBuffers(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "glx")] Some((glx::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { glx::BUFFER_SWAP_COMPLETE_EVENT => Ok(Self::GlxBufferSwapComplete(TryParse::try_parse(event)?.0)), glx::PBUFFER_CLOBBER_EVENT => Ok(Self::GlxPbufferClobber(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "present")] Some((present::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { present::GENERIC_EVENT => Ok(Self::PresentGeneric(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "randr")] Some((randr::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { randr::NOTIFY_EVENT => Ok(Self::RandrNotify(TryParse::try_parse(event)?.0)), randr::SCREEN_CHANGE_NOTIFY_EVENT => Ok(Self::RandrScreenChangeNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "screensaver")] Some((screensaver::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { screensaver::NOTIFY_EVENT => Ok(Self::ScreensaverNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "shape")] Some((shape::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { shape::NOTIFY_EVENT => Ok(Self::ShapeNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "shm")] Some((shm::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { shm::COMPLETION_EVENT => Ok(Self::ShmCompletion(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "sync")] Some((sync::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { sync::ALARM_NOTIFY_EVENT => Ok(Self::SyncAlarmNotify(TryParse::try_parse(event)?.0)), sync::COUNTER_NOTIFY_EVENT => Ok(Self::SyncCounterNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "xfixes")] Some((xfixes::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { xfixes::CURSOR_NOTIFY_EVENT => Ok(Self::XfixesCursorNotify(TryParse::try_parse(event)?.0)), xfixes::SELECTION_NOTIFY_EVENT => Ok(Self::XfixesSelectionNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "xinput")] Some((xinput::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { xinput::CHANGE_DEVICE_NOTIFY_EVENT => Ok(Self::XinputChangeDeviceNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_BUTTON_PRESS_EVENT => Ok(Self::XinputDeviceButtonPress(TryParse::try_parse(event)?.0)), xinput::DEVICE_BUTTON_RELEASE_EVENT => Ok(Self::XinputDeviceButtonRelease(TryParse::try_parse(event)?.0)), xinput::DEVICE_BUTTON_STATE_NOTIFY_EVENT => Ok(Self::XinputDeviceButtonStateNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_FOCUS_IN_EVENT => Ok(Self::XinputDeviceFocusIn(TryParse::try_parse(event)?.0)), xinput::DEVICE_FOCUS_OUT_EVENT => Ok(Self::XinputDeviceFocusOut(TryParse::try_parse(event)?.0)), xinput::DEVICE_KEY_PRESS_EVENT => Ok(Self::XinputDeviceKeyPress(TryParse::try_parse(event)?.0)), xinput::DEVICE_KEY_RELEASE_EVENT => Ok(Self::XinputDeviceKeyRelease(TryParse::try_parse(event)?.0)), xinput::DEVICE_KEY_STATE_NOTIFY_EVENT => Ok(Self::XinputDeviceKeyStateNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_MAPPING_NOTIFY_EVENT => Ok(Self::XinputDeviceMappingNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_MOTION_NOTIFY_EVENT => Ok(Self::XinputDeviceMotionNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_PRESENCE_NOTIFY_EVENT => Ok(Self::XinputDevicePresenceNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_PROPERTY_NOTIFY_EVENT => Ok(Self::XinputDevicePropertyNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_STATE_NOTIFY_EVENT => Ok(Self::XinputDeviceStateNotify(TryParse::try_parse(event)?.0)), xinput::DEVICE_VALUATOR_EVENT => Ok(Self::XinputDeviceValuator(TryParse::try_parse(event)?.0)), xinput::PROXIMITY_IN_EVENT => Ok(Self::XinputProximityIn(TryParse::try_parse(event)?.0)), xinput::PROXIMITY_OUT_EVENT => Ok(Self::XinputProximityOut(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "xkb")] Some((xkb::X11_EXTENSION_NAME, ext_info)) => { if event_code != ext_info.first_event { return Ok(Self::Unknown(event.to_vec())); } match *event.get(1).ok_or(ParseError::InsufficientData)? { xkb::ACCESS_X_NOTIFY_EVENT => Ok(Self::XkbAccessXNotify(TryParse::try_parse(event)?.0)), xkb::ACTION_MESSAGE_EVENT => Ok(Self::XkbActionMessage(TryParse::try_parse(event)?.0)), xkb::BELL_NOTIFY_EVENT => Ok(Self::XkbBellNotify(TryParse::try_parse(event)?.0)), xkb::COMPAT_MAP_NOTIFY_EVENT => Ok(Self::XkbCompatMapNotify(TryParse::try_parse(event)?.0)), xkb::CONTROLS_NOTIFY_EVENT => Ok(Self::XkbControlsNotify(TryParse::try_parse(event)?.0)), xkb::EXTENSION_DEVICE_NOTIFY_EVENT => Ok(Self::XkbExtensionDeviceNotify(TryParse::try_parse(event)?.0)), xkb::INDICATOR_MAP_NOTIFY_EVENT => Ok(Self::XkbIndicatorMapNotify(TryParse::try_parse(event)?.0)), xkb::INDICATOR_STATE_NOTIFY_EVENT => Ok(Self::XkbIndicatorStateNotify(TryParse::try_parse(event)?.0)), xkb::MAP_NOTIFY_EVENT => Ok(Self::XkbMapNotify(TryParse::try_parse(event)?.0)), xkb::NAMES_NOTIFY_EVENT => Ok(Self::XkbNamesNotify(TryParse::try_parse(event)?.0)), xkb::NEW_KEYBOARD_NOTIFY_EVENT => Ok(Self::XkbNewKeyboardNotify(TryParse::try_parse(event)?.0)), xkb::STATE_NOTIFY_EVENT => Ok(Self::XkbStateNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "xprint")] Some((xprint::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { xprint::ATTRIBUT_NOTIFY_EVENT => Ok(Self::XprintAttributNotify(TryParse::try_parse(event)?.0)), xprint::NOTIFY_EVENT => Ok(Self::XprintNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "xv")] Some((xv::X11_EXTENSION_NAME, ext_info)) => { match event_code - ext_info.first_event { xv::PORT_NOTIFY_EVENT => Ok(Self::XvPortNotify(TryParse::try_parse(event)?.0)), xv::VIDEO_NOTIFY_EVENT => Ok(Self::XvVideoNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } _ => Ok(Self::Unknown(event.to_vec())), } } #[allow(clippy::match_single_binding)] fn from_generic_event( event: &[u8], ext_info_provider: &dyn ExtInfoProvider, ) -> Result { let ge_event = xproto::GeGenericEvent::try_parse(event)?.0; let ext_name = ext_info_provider .get_from_major_opcode(ge_event.extension) .map(|(name, _)| name); match ext_name { #[cfg(feature = "present")] Some(present::X11_EXTENSION_NAME) => { match ge_event.event_type { present::COMPLETE_NOTIFY_EVENT => Ok(Self::PresentCompleteNotify(TryParse::try_parse(event)?.0)), present::CONFIGURE_NOTIFY_EVENT => Ok(Self::PresentConfigureNotify(TryParse::try_parse(event)?.0)), present::IDLE_NOTIFY_EVENT => Ok(Self::PresentIdleNotify(TryParse::try_parse(event)?.0)), present::REDIRECT_NOTIFY_EVENT => Ok(Self::PresentRedirectNotify(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } #[cfg(feature = "xinput")] Some(xinput::X11_EXTENSION_NAME) => { match ge_event.event_type { xinput::BARRIER_HIT_EVENT => Ok(Self::XinputBarrierHit(TryParse::try_parse(event)?.0)), xinput::BARRIER_LEAVE_EVENT => Ok(Self::XinputBarrierLeave(TryParse::try_parse(event)?.0)), xinput::BUTTON_PRESS_EVENT => Ok(Self::XinputButtonPress(TryParse::try_parse(event)?.0)), xinput::BUTTON_RELEASE_EVENT => Ok(Self::XinputButtonRelease(TryParse::try_parse(event)?.0)), xinput::DEVICE_CHANGED_EVENT => Ok(Self::XinputDeviceChanged(TryParse::try_parse(event)?.0)), xinput::ENTER_EVENT => Ok(Self::XinputEnter(TryParse::try_parse(event)?.0)), xinput::FOCUS_IN_EVENT => Ok(Self::XinputFocusIn(TryParse::try_parse(event)?.0)), xinput::FOCUS_OUT_EVENT => Ok(Self::XinputFocusOut(TryParse::try_parse(event)?.0)), xinput::HIERARCHY_EVENT => Ok(Self::XinputHierarchy(TryParse::try_parse(event)?.0)), xinput::KEY_PRESS_EVENT => Ok(Self::XinputKeyPress(TryParse::try_parse(event)?.0)), xinput::KEY_RELEASE_EVENT => Ok(Self::XinputKeyRelease(TryParse::try_parse(event)?.0)), xinput::LEAVE_EVENT => Ok(Self::XinputLeave(TryParse::try_parse(event)?.0)), xinput::MOTION_EVENT => Ok(Self::XinputMotion(TryParse::try_parse(event)?.0)), xinput::PROPERTY_EVENT => Ok(Self::XinputProperty(TryParse::try_parse(event)?.0)), xinput::RAW_BUTTON_PRESS_EVENT => Ok(Self::XinputRawButtonPress(TryParse::try_parse(event)?.0)), xinput::RAW_BUTTON_RELEASE_EVENT => Ok(Self::XinputRawButtonRelease(TryParse::try_parse(event)?.0)), xinput::RAW_KEY_PRESS_EVENT => Ok(Self::XinputRawKeyPress(TryParse::try_parse(event)?.0)), xinput::RAW_KEY_RELEASE_EVENT => Ok(Self::XinputRawKeyRelease(TryParse::try_parse(event)?.0)), xinput::RAW_MOTION_EVENT => Ok(Self::XinputRawMotion(TryParse::try_parse(event)?.0)), xinput::RAW_TOUCH_BEGIN_EVENT => Ok(Self::XinputRawTouchBegin(TryParse::try_parse(event)?.0)), xinput::RAW_TOUCH_END_EVENT => Ok(Self::XinputRawTouchEnd(TryParse::try_parse(event)?.0)), xinput::RAW_TOUCH_UPDATE_EVENT => Ok(Self::XinputRawTouchUpdate(TryParse::try_parse(event)?.0)), xinput::TOUCH_BEGIN_EVENT => Ok(Self::XinputTouchBegin(TryParse::try_parse(event)?.0)), xinput::TOUCH_END_EVENT => Ok(Self::XinputTouchEnd(TryParse::try_parse(event)?.0)), xinput::TOUCH_OWNERSHIP_EVENT => Ok(Self::XinputTouchOwnership(TryParse::try_parse(event)?.0)), xinput::TOUCH_UPDATE_EVENT => Ok(Self::XinputTouchUpdate(TryParse::try_parse(event)?.0)), _ => Ok(Self::Unknown(event.to_vec())), } } _ => Ok(Self::Unknown(event.to_vec())), } } /// Get the sequence number contained in this X11 event pub fn wire_sequence_number(&self) -> Option { match self { Event::Unknown(value) => sequence_number(value).ok(), Event::Error(value) => Some(value.sequence), Event::ButtonPress(value) => Some(value.sequence), Event::ButtonRelease(value) => Some(value.sequence), Event::CirculateNotify(value) => Some(value.sequence), Event::CirculateRequest(value) => Some(value.sequence), Event::ClientMessage(value) => Some(value.sequence), Event::ColormapNotify(value) => Some(value.sequence), Event::ConfigureNotify(value) => Some(value.sequence), Event::ConfigureRequest(value) => Some(value.sequence), Event::CreateNotify(value) => Some(value.sequence), Event::DestroyNotify(value) => Some(value.sequence), Event::EnterNotify(value) => Some(value.sequence), Event::Expose(value) => Some(value.sequence), Event::FocusIn(value) => Some(value.sequence), Event::FocusOut(value) => Some(value.sequence), Event::GeGeneric(value) => Some(value.sequence), Event::GraphicsExposure(value) => Some(value.sequence), Event::GravityNotify(value) => Some(value.sequence), Event::KeyPress(value) => Some(value.sequence), Event::KeyRelease(value) => Some(value.sequence), Event::KeymapNotify(_) => None, Event::LeaveNotify(value) => Some(value.sequence), Event::MapNotify(value) => Some(value.sequence), Event::MapRequest(value) => Some(value.sequence), Event::MappingNotify(value) => Some(value.sequence), Event::MotionNotify(value) => Some(value.sequence), Event::NoExposure(value) => Some(value.sequence), Event::PropertyNotify(value) => Some(value.sequence), Event::ReparentNotify(value) => Some(value.sequence), Event::ResizeRequest(value) => Some(value.sequence), Event::SelectionClear(value) => Some(value.sequence), Event::SelectionNotify(value) => Some(value.sequence), Event::SelectionRequest(value) => Some(value.sequence), Event::UnmapNotify(value) => Some(value.sequence), Event::VisibilityNotify(value) => Some(value.sequence), #[cfg(feature = "damage")] Event::DamageNotify(value) => Some(value.sequence), #[cfg(feature = "dri2")] Event::Dri2BufferSwapComplete(value) => Some(value.sequence), #[cfg(feature = "dri2")] Event::Dri2InvalidateBuffers(value) => Some(value.sequence), #[cfg(feature = "glx")] Event::GlxBufferSwapComplete(value) => Some(value.sequence), #[cfg(feature = "glx")] Event::GlxPbufferClobber(value) => Some(value.sequence), #[cfg(feature = "present")] Event::PresentCompleteNotify(value) => Some(value.sequence), #[cfg(feature = "present")] Event::PresentConfigureNotify(value) => Some(value.sequence), #[cfg(feature = "present")] Event::PresentGeneric(value) => Some(value.sequence), #[cfg(feature = "present")] Event::PresentIdleNotify(value) => Some(value.sequence), #[cfg(feature = "present")] Event::PresentRedirectNotify(value) => Some(value.sequence), #[cfg(feature = "randr")] Event::RandrNotify(value) => Some(value.sequence), #[cfg(feature = "randr")] Event::RandrScreenChangeNotify(value) => Some(value.sequence), #[cfg(feature = "screensaver")] Event::ScreensaverNotify(value) => Some(value.sequence), #[cfg(feature = "shape")] Event::ShapeNotify(value) => Some(value.sequence), #[cfg(feature = "shm")] Event::ShmCompletion(value) => Some(value.sequence), #[cfg(feature = "sync")] Event::SyncAlarmNotify(value) => Some(value.sequence), #[cfg(feature = "sync")] Event::SyncCounterNotify(value) => Some(value.sequence), #[cfg(feature = "xfixes")] Event::XfixesCursorNotify(value) => Some(value.sequence), #[cfg(feature = "xfixes")] Event::XfixesSelectionNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputBarrierHit(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputBarrierLeave(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputButtonPress(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputButtonRelease(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputChangeDeviceNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceButtonPress(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceButtonRelease(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceButtonStateNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceChanged(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceFocusIn(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceFocusOut(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceKeyPress(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceKeyRelease(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceKeyStateNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceMappingNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceMotionNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDevicePresenceNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDevicePropertyNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceStateNotify(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputDeviceValuator(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputEnter(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputFocusIn(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputFocusOut(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputHierarchy(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputKeyPress(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputKeyRelease(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputLeave(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputMotion(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputProperty(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputProximityIn(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputProximityOut(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawButtonPress(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawButtonRelease(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawKeyPress(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawKeyRelease(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawMotion(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawTouchBegin(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawTouchEnd(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputRawTouchUpdate(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputTouchBegin(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputTouchEnd(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputTouchOwnership(value) => Some(value.sequence), #[cfg(feature = "xinput")] Event::XinputTouchUpdate(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbAccessXNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbActionMessage(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbBellNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbCompatMapNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbControlsNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbExtensionDeviceNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbIndicatorMapNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbIndicatorStateNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbMapNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbNamesNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbNewKeyboardNotify(value) => Some(value.sequence), #[cfg(feature = "xkb")] Event::XkbStateNotify(value) => Some(value.sequence), #[cfg(feature = "xprint")] Event::XprintAttributNotify(value) => Some(value.sequence), #[cfg(feature = "xprint")] Event::XprintNotify(value) => Some(value.sequence), #[cfg(feature = "xv")] Event::XvPortNotify(value) => Some(value.sequence), #[cfg(feature = "xv")] Event::XvVideoNotify(value) => Some(value.sequence), } } /// Get the raw response type of this X11 event /// /// Response types have seven bits in X11. The eight bit indicates whether /// the packet was generated through the `SendEvent` request. This function /// returns all eight bits. /// /// See also the `response_type()`, `server_generated()` and `sent_event()` methods. pub fn raw_response_type(&self) -> u8 { match self { Event::Unknown(value) => response_type(value).unwrap(), Event::Error(_) => 0, Event::ButtonPress(value) => value.response_type, Event::ButtonRelease(value) => value.response_type, Event::CirculateNotify(value) => value.response_type, Event::CirculateRequest(value) => value.response_type, Event::ClientMessage(value) => value.response_type, Event::ColormapNotify(value) => value.response_type, Event::ConfigureNotify(value) => value.response_type, Event::ConfigureRequest(value) => value.response_type, Event::CreateNotify(value) => value.response_type, Event::DestroyNotify(value) => value.response_type, Event::EnterNotify(value) => value.response_type, Event::Expose(value) => value.response_type, Event::FocusIn(value) => value.response_type, Event::FocusOut(value) => value.response_type, Event::GeGeneric(value) => value.response_type, Event::GraphicsExposure(value) => value.response_type, Event::GravityNotify(value) => value.response_type, Event::KeyPress(value) => value.response_type, Event::KeyRelease(value) => value.response_type, Event::KeymapNotify(value) => value.response_type, Event::LeaveNotify(value) => value.response_type, Event::MapNotify(value) => value.response_type, Event::MapRequest(value) => value.response_type, Event::MappingNotify(value) => value.response_type, Event::MotionNotify(value) => value.response_type, Event::NoExposure(value) => value.response_type, Event::PropertyNotify(value) => value.response_type, Event::ReparentNotify(value) => value.response_type, Event::ResizeRequest(value) => value.response_type, Event::SelectionClear(value) => value.response_type, Event::SelectionNotify(value) => value.response_type, Event::SelectionRequest(value) => value.response_type, Event::UnmapNotify(value) => value.response_type, Event::VisibilityNotify(value) => value.response_type, #[cfg(feature = "damage")] Event::DamageNotify(value) => value.response_type, #[cfg(feature = "dri2")] Event::Dri2BufferSwapComplete(value) => value.response_type, #[cfg(feature = "dri2")] Event::Dri2InvalidateBuffers(value) => value.response_type, #[cfg(feature = "glx")] Event::GlxBufferSwapComplete(value) => value.response_type, #[cfg(feature = "glx")] Event::GlxPbufferClobber(value) => value.response_type, #[cfg(feature = "present")] Event::PresentCompleteNotify(value) => value.response_type, #[cfg(feature = "present")] Event::PresentConfigureNotify(value) => value.response_type, #[cfg(feature = "present")] Event::PresentGeneric(value) => value.response_type, #[cfg(feature = "present")] Event::PresentIdleNotify(value) => value.response_type, #[cfg(feature = "present")] Event::PresentRedirectNotify(value) => value.response_type, #[cfg(feature = "randr")] Event::RandrNotify(value) => value.response_type, #[cfg(feature = "randr")] Event::RandrScreenChangeNotify(value) => value.response_type, #[cfg(feature = "screensaver")] Event::ScreensaverNotify(value) => value.response_type, #[cfg(feature = "shape")] Event::ShapeNotify(value) => value.response_type, #[cfg(feature = "shm")] Event::ShmCompletion(value) => value.response_type, #[cfg(feature = "sync")] Event::SyncAlarmNotify(value) => value.response_type, #[cfg(feature = "sync")] Event::SyncCounterNotify(value) => value.response_type, #[cfg(feature = "xfixes")] Event::XfixesCursorNotify(value) => value.response_type, #[cfg(feature = "xfixes")] Event::XfixesSelectionNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputBarrierHit(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputBarrierLeave(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputButtonPress(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputButtonRelease(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputChangeDeviceNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceButtonPress(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceButtonRelease(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceButtonStateNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceChanged(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceFocusIn(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceFocusOut(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceKeyPress(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceKeyRelease(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceKeyStateNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceMappingNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceMotionNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDevicePresenceNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDevicePropertyNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceStateNotify(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputDeviceValuator(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputEnter(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputFocusIn(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputFocusOut(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputHierarchy(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputKeyPress(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputKeyRelease(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputLeave(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputMotion(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputProperty(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputProximityIn(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputProximityOut(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawButtonPress(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawButtonRelease(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawKeyPress(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawKeyRelease(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawMotion(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawTouchBegin(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawTouchEnd(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputRawTouchUpdate(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputTouchBegin(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputTouchEnd(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputTouchOwnership(value) => value.response_type, #[cfg(feature = "xinput")] Event::XinputTouchUpdate(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbAccessXNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbActionMessage(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbBellNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbCompatMapNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbControlsNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbExtensionDeviceNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbIndicatorMapNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbIndicatorStateNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbMapNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbNamesNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbNewKeyboardNotify(value) => value.response_type, #[cfg(feature = "xkb")] Event::XkbStateNotify(value) => value.response_type, #[cfg(feature = "xprint")] Event::XprintAttributNotify(value) => value.response_type, #[cfg(feature = "xprint")] Event::XprintNotify(value) => value.response_type, #[cfg(feature = "xv")] Event::XvPortNotify(value) => value.response_type, #[cfg(feature = "xv")] Event::XvVideoNotify(value) => value.response_type, } } /// Get the response type of this X11 event pub fn response_type(&self) -> u8 { self.raw_response_type() & 0x7f } /// Was this event generated by the X11 server? /// /// If this function returns true, then this event comes from the X11 server. /// Otherwise, it was sent from another client via the `SendEvent` request. pub fn server_generated(&self) -> bool { self.raw_response_type() & 0x80 == 0 } /// Was this event generated by another X11 client? /// /// If this function returns true, then this event comes from another client via /// the `SendEvent` request. Otherwise, it was generated by the X11 server. pub fn sent_event(&self) -> bool { self.raw_response_type() & 0x80 != 0 } } /// Get the response type out of the raw bytes of an X11 error or event. fn response_type(raw_bytes: &[u8]) -> Result { raw_bytes.get(0) .map(|x| x & 0x7f) .ok_or(ParseError::InsufficientData) } /// Get the sequence number out of an X11 packet. fn sequence_number(raw_bytes: &[u8]) -> Result { raw_bytes.get(2..4) .map(|b| u16::from_ne_bytes(b.try_into().unwrap())) .ok_or(ParseError::InsufficientData) } x11rb-0.8.1/src/protocol/present.rs010064400017500001750000001370511402220031600153110ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Present` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::randr; use super::sync; use super::xfixes; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "Present"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 2); #[derive(Clone, Copy, PartialEq, Eq)] pub struct EventEnum(u8); impl EventEnum { pub const CONFIGURE_NOTIFY: Self = Self(0); pub const COMPLETE_NOTIFY: Self = Self(1); pub const IDLE_NOTIFY: Self = Self(2); pub const REDIRECT_NOTIFY: Self = Self(3); } impl From for u8 { #[inline] fn from(input: EventEnum) -> Self { input.0 } } impl From for std::option::Option { #[inline] fn from(input: EventEnum) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: EventEnum) -> Self { u16::from(input.0) } } impl From for std::option::Option { #[inline] fn from(input: EventEnum) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: EventEnum) -> Self { u32::from(input.0) } } impl From for std::option::Option { #[inline] fn from(input: EventEnum) -> Self { Some(u32::from(input.0)) } } impl From for EventEnum { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for EventEnum { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CONFIGURE_NOTIFY.0.into(), "CONFIGURE_NOTIFY", "ConfigureNotify"), (Self::COMPLETE_NOTIFY.0.into(), "COMPLETE_NOTIFY", "CompleteNotify"), (Self::IDLE_NOTIFY.0.into(), "IDLE_NOTIFY", "IdleNotify"), (Self::REDIRECT_NOTIFY.0.into(), "REDIRECT_NOTIFY", "RedirectNotify"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct EventMask(u8); impl EventMask { pub const NO_EVENT: Self = Self(0); pub const CONFIGURE_NOTIFY: Self = Self(1 << 0); pub const COMPLETE_NOTIFY: Self = Self(1 << 1); pub const IDLE_NOTIFY: Self = Self(1 << 2); pub const REDIRECT_NOTIFY: Self = Self(1 << 3); } impl From for u8 { #[inline] fn from(input: EventMask) -> Self { input.0 } } impl From for std::option::Option { #[inline] fn from(input: EventMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: EventMask) -> Self { u16::from(input.0) } } impl From for std::option::Option { #[inline] fn from(input: EventMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: EventMask) -> Self { u32::from(input.0) } } impl From for std::option::Option { #[inline] fn from(input: EventMask) -> Self { Some(u32::from(input.0)) } } impl From for EventMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for EventMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_EVENT.0.into(), "NO_EVENT", "NoEvent"), (Self::CONFIGURE_NOTIFY.0.into(), "CONFIGURE_NOTIFY", "ConfigureNotify"), (Self::COMPLETE_NOTIFY.0.into(), "COMPLETE_NOTIFY", "CompleteNotify"), (Self::IDLE_NOTIFY.0.into(), "IDLE_NOTIFY", "IdleNotify"), (Self::REDIRECT_NOTIFY.0.into(), "REDIRECT_NOTIFY", "RedirectNotify"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(EventMask, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Option(u8); impl Option { pub const NONE: Self = Self(0); pub const ASYNC: Self = Self(1 << 0); pub const COPY: Self = Self(1 << 1); pub const UST: Self = Self(1 << 2); pub const SUBOPTIMAL: Self = Self(1 << 3); } impl From(&self, eid: Event, window: xproto::Window, event_mask: A) -> Result, ConnectionError> where A: Into, { select_input(self, eid, window, event_mask) } fn present_query_capabilities(&self, target: u32) -> Result, ConnectionError> { query_capabilities(self, target) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/randr.rs010064400017500001750000010243051402220031600147350ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `RandR` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::render; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "RANDR"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 6); pub type Mode = u32; pub type Crtc = u32; pub type Output = u32; pub type Provider = u32; pub type Lease = u32; /// Opcode for the BadOutput error pub const BAD_OUTPUT_ERROR: u8 = 0; /// Opcode for the BadCrtc error pub const BAD_CRTC_ERROR: u8 = 1; /// Opcode for the BadMode error pub const BAD_MODE_ERROR: u8 = 2; /// Opcode for the BadProvider error pub const BAD_PROVIDER_ERROR: u8 = 3; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Rotation(u8); impl Rotation { pub const ROTATE0: Self = Self(1 << 0); pub const ROTATE90: Self = Self(1 << 1); pub const ROTATE180: Self = Self(1 << 2); pub const ROTATE270: Self = Self(1 << 3); pub const REFLECT_X: Self = Self(1 << 4); pub const REFLECT_Y: Self = Self(1 << 5); } impl From for u8 { #[inline] fn from(input: Rotation) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Rotation) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Rotation) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Rotation) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Rotation) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Rotation) -> Self { Some(u32::from(input.0)) } } impl From for Rotation { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Rotation { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ROTATE0.0.into(), "ROTATE0", "Rotate0"), (Self::ROTATE90.0.into(), "ROTATE90", "Rotate90"), (Self::ROTATE180.0.into(), "ROTATE180", "Rotate180"), (Self::ROTATE270.0.into(), "ROTATE270", "Rotate270"), (Self::REFLECT_X.0.into(), "REFLECT_X", "ReflectX"), (Self::REFLECT_Y.0.into(), "REFLECT_Y", "ReflectY"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(Rotation, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ScreenSize { pub width: u16, pub height: u16, pub mwidth: u16, pub mheight: u16, } impl TryParse for ScreenSize { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (mwidth, remaining) = u16::try_parse(remaining)?; let (mheight, remaining) = u16::try_parse(remaining)?; let result = ScreenSize { width, height, mwidth, mheight }; Ok((result, remaining)) } } impl Serialize for ScreenSize { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let mwidth_bytes = self.mwidth.serialize(); let mheight_bytes = self.mheight.serialize(); [ width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], mwidth_bytes[0], mwidth_bytes[1], mheight_bytes[0], mheight_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.mwidth.serialize_into(bytes); self.mheight.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct RefreshRates { pub rates: Vec, } impl TryParse for RefreshRates { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (n_rates, remaining) = u16::try_parse(remaining)?; let (rates, remaining) = crate::x11_utils::parse_list::(remaining, n_rates.try_to_usize()?)?; let result = RefreshRates { rates }; Ok((result, remaining)) } } impl Serialize for RefreshRates { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let n_rates = u16::try_from(self.rates.len()).expect("`rates` has too many elements"); n_rates.serialize_into(bytes); self.rates.serialize_into(bytes); } } impl RefreshRates { /// Get the value of the `nRates` field. /// /// The `nRates` field is used as the length field of the `rates` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_rates(&self) -> u16 { self.rates.len() .try_into().unwrap() } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub major_version: u32, pub minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], major_version_bytes[2], major_version_bytes[3], minor_version_bytes[0], minor_version_bytes[1], minor_version_bytes[2], minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u32::try_parse(value)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { major_version, minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, major_version: u32, minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { major_version, minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SetConfig(u8); impl SetConfig { pub const SUCCESS: Self = Self(0); pub const INVALID_CONFIG_TIME: Self = Self(1); pub const INVALID_TIME: Self = Self(2); pub const FAILED: Self = Self(3); } impl From for u8 { #[inline] fn from(input: SetConfig) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SetConfig) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SetConfig) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SetConfig) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SetConfig) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SetConfig) -> Self { Some(u32::from(input.0)) } } impl From for SetConfig { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SetConfig { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SUCCESS.0.into(), "SUCCESS", "Success"), (Self::INVALID_CONFIG_TIME.0.into(), "INVALID_CONFIG_TIME", "InvalidConfigTime"), (Self::INVALID_TIME.0.into(), "INVALID_TIME", "InvalidTime"), (Self::FAILED.0.into(), "FAILED", "Failed"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the SetScreenConfig request pub const SET_SCREEN_CONFIG_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetScreenConfigRequest { pub window: xproto::Window, pub timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub size_id: u16, pub rotation: u16, pub rate: u16, } impl SetScreenConfigRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let timestamp_bytes = self.timestamp.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let size_id_bytes = self.size_id.serialize(); let rotation_bytes = self.rotation.serialize(); let rate_bytes = self.rate.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_SCREEN_CONFIG_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], size_id_bytes[0], size_id_bytes[1], rotation_bytes[0], rotation_bytes[1], rate_bytes[0], rate_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_SCREEN_CONFIG_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (size_id, remaining) = u16::try_parse(remaining)?; let (rotation, remaining) = u16::try_parse(remaining)?; let (rate, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SetScreenConfigRequest { window, timestamp, config_timestamp, size_id, rotation, rate, }) } } impl Request for SetScreenConfigRequest { type Reply = SetScreenConfigReply; } pub fn set_screen_config(conn: &Conn, window: xproto::Window, timestamp: xproto::Timestamp, config_timestamp: xproto::Timestamp, size_id: u16, rotation: A, rate: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let rotation: u16 = rotation.into(); let request0 = SetScreenConfigRequest { window, timestamp, config_timestamp, size_id, rotation, rate, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetScreenConfigReply { pub status: SetConfig, pub sequence: u16, pub length: u32, pub new_timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub root: xproto::Window, pub subpixel_order: render::SubPixel, } impl TryParse for SetScreenConfigReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (new_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (subpixel_order, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(10..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let subpixel_order = subpixel_order.into(); let result = SetScreenConfigReply { status, sequence, length, new_timestamp, config_timestamp, root, subpixel_order }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct NotifyMask(u8); impl NotifyMask { pub const SCREEN_CHANGE: Self = Self(1 << 0); pub const CRTC_CHANGE: Self = Self(1 << 1); pub const OUTPUT_CHANGE: Self = Self(1 << 2); pub const OUTPUT_PROPERTY: Self = Self(1 << 3); pub const PROVIDER_CHANGE: Self = Self(1 << 4); pub const PROVIDER_PROPERTY: Self = Self(1 << 5); pub const RESOURCE_CHANGE: Self = Self(1 << 6); pub const LEASE: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: NotifyMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: NotifyMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: NotifyMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: NotifyMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyMask) -> Self { Some(u32::from(input.0)) } } impl From for NotifyMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for NotifyMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SCREEN_CHANGE.0.into(), "SCREEN_CHANGE", "ScreenChange"), (Self::CRTC_CHANGE.0.into(), "CRTC_CHANGE", "CrtcChange"), (Self::OUTPUT_CHANGE.0.into(), "OUTPUT_CHANGE", "OutputChange"), (Self::OUTPUT_PROPERTY.0.into(), "OUTPUT_PROPERTY", "OutputProperty"), (Self::PROVIDER_CHANGE.0.into(), "PROVIDER_CHANGE", "ProviderChange"), (Self::PROVIDER_PROPERTY.0.into(), "PROVIDER_PROPERTY", "ProviderProperty"), (Self::RESOURCE_CHANGE.0.into(), "RESOURCE_CHANGE", "ResourceChange"), (Self::LEASE.0.into(), "LEASE", "Lease"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(NotifyMask, u8); /// Opcode for the SelectInput request pub const SELECT_INPUT_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectInputRequest { pub window: xproto::Window, pub enable: u16, } impl SelectInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let enable_bytes = self.enable.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_INPUT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], enable_bytes[0], enable_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (enable, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SelectInputRequest { window, enable, }) } } impl Request for SelectInputRequest { type Reply = (); } pub fn select_input(conn: &Conn, window: xproto::Window, enable: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let enable: u16 = enable.into(); let request0 = SelectInputRequest { window, enable, }; request0.send(conn) } /// Opcode for the GetScreenInfo request pub const GET_SCREEN_INFO_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenInfoRequest { pub window: xproto::Window, } impl GetScreenInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SCREEN_INFO_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SCREEN_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetScreenInfoRequest { window, }) } } impl Request for GetScreenInfoRequest { type Reply = GetScreenInfoReply; } pub fn get_screen_info(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetScreenInfoRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetScreenInfoReply { pub rotations: u8, pub sequence: u16, pub length: u32, pub root: xproto::Window, pub timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub size_id: u16, pub rotation: u16, pub rate: u16, pub n_info: u16, pub sizes: Vec, pub rates: Vec, } impl TryParse for GetScreenInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (rotations, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (n_sizes, remaining) = u16::try_parse(remaining)?; let (size_id, remaining) = u16::try_parse(remaining)?; let (rotation, remaining) = u16::try_parse(remaining)?; let (rate, remaining) = u16::try_parse(remaining)?; let (n_info, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (sizes, remaining) = crate::x11_utils::parse_list::(remaining, n_sizes.try_to_usize()?)?; let (rates, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(n_info).checked_sub(u32::from(n_sizes)).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetScreenInfoReply { rotations, sequence, length, root, timestamp, config_timestamp, size_id, rotation, rate, n_info, sizes, rates }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetScreenInfoReply { /// Get the value of the `nSizes` field. /// /// The `nSizes` field is used as the length field of the `sizes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_sizes(&self) -> u16 { self.sizes.len() .try_into().unwrap() } } /// Opcode for the GetScreenSizeRange request pub const GET_SCREEN_SIZE_RANGE_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenSizeRangeRequest { pub window: xproto::Window, } impl GetScreenSizeRangeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SCREEN_SIZE_RANGE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SCREEN_SIZE_RANGE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetScreenSizeRangeRequest { window, }) } } impl Request for GetScreenSizeRangeRequest { type Reply = GetScreenSizeRangeReply; } pub fn get_screen_size_range(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetScreenSizeRangeRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenSizeRangeReply { pub sequence: u16, pub length: u32, pub min_width: u16, pub min_height: u16, pub max_width: u16, pub max_height: u16, } impl TryParse for GetScreenSizeRangeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (min_width, remaining) = u16::try_parse(remaining)?; let (min_height, remaining) = u16::try_parse(remaining)?; let (max_width, remaining) = u16::try_parse(remaining)?; let (max_height, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetScreenSizeRangeReply { sequence, length, min_width, min_height, max_width, max_height }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetScreenSize request pub const SET_SCREEN_SIZE_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetScreenSizeRequest { pub window: xproto::Window, pub width: u16, pub height: u16, pub mm_width: u32, pub mm_height: u32, } impl SetScreenSizeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let mm_width_bytes = self.mm_width.serialize(); let mm_height_bytes = self.mm_height.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_SCREEN_SIZE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], mm_width_bytes[0], mm_width_bytes[1], mm_width_bytes[2], mm_width_bytes[3], mm_height_bytes[0], mm_height_bytes[1], mm_height_bytes[2], mm_height_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_SCREEN_SIZE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (mm_width, remaining) = u32::try_parse(remaining)?; let (mm_height, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SetScreenSizeRequest { window, width, height, mm_width, mm_height, }) } } impl Request for SetScreenSizeRequest { type Reply = (); } pub fn set_screen_size(conn: &Conn, window: xproto::Window, width: u16, height: u16, mm_width: u32, mm_height: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetScreenSizeRequest { window, width, height, mm_width, mm_height, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ModeFlag(u16); impl ModeFlag { pub const HSYNC_POSITIVE: Self = Self(1 << 0); pub const HSYNC_NEGATIVE: Self = Self(1 << 1); pub const VSYNC_POSITIVE: Self = Self(1 << 2); pub const VSYNC_NEGATIVE: Self = Self(1 << 3); pub const INTERLACE: Self = Self(1 << 4); pub const DOUBLE_SCAN: Self = Self(1 << 5); pub const CSYNC: Self = Self(1 << 6); pub const CSYNC_POSITIVE: Self = Self(1 << 7); pub const CSYNC_NEGATIVE: Self = Self(1 << 8); pub const HSKEW_PRESENT: Self = Self(1 << 9); pub const BCAST: Self = Self(1 << 10); pub const PIXEL_MULTIPLEX: Self = Self(1 << 11); pub const DOUBLE_CLOCK: Self = Self(1 << 12); pub const HALVE_CLOCK: Self = Self(1 << 13); } impl From for u16 { #[inline] fn from(input: ModeFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ModeFlag) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: ModeFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ModeFlag) -> Self { Some(u32::from(input.0)) } } impl From for ModeFlag { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for ModeFlag { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for ModeFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::HSYNC_POSITIVE.0.into(), "HSYNC_POSITIVE", "HsyncPositive"), (Self::HSYNC_NEGATIVE.0.into(), "HSYNC_NEGATIVE", "HsyncNegative"), (Self::VSYNC_POSITIVE.0.into(), "VSYNC_POSITIVE", "VsyncPositive"), (Self::VSYNC_NEGATIVE.0.into(), "VSYNC_NEGATIVE", "VsyncNegative"), (Self::INTERLACE.0.into(), "INTERLACE", "Interlace"), (Self::DOUBLE_SCAN.0.into(), "DOUBLE_SCAN", "DoubleScan"), (Self::CSYNC.0.into(), "CSYNC", "Csync"), (Self::CSYNC_POSITIVE.0.into(), "CSYNC_POSITIVE", "CsyncPositive"), (Self::CSYNC_NEGATIVE.0.into(), "CSYNC_NEGATIVE", "CsyncNegative"), (Self::HSKEW_PRESENT.0.into(), "HSKEW_PRESENT", "HskewPresent"), (Self::BCAST.0.into(), "BCAST", "Bcast"), (Self::PIXEL_MULTIPLEX.0.into(), "PIXEL_MULTIPLEX", "PixelMultiplex"), (Self::DOUBLE_CLOCK.0.into(), "DOUBLE_CLOCK", "DoubleClock"), (Self::HALVE_CLOCK.0.into(), "HALVE_CLOCK", "HalveClock"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ModeFlag, u16); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ModeInfo { pub id: u32, pub width: u16, pub height: u16, pub dot_clock: u32, pub hsync_start: u16, pub hsync_end: u16, pub htotal: u16, pub hskew: u16, pub vsync_start: u16, pub vsync_end: u16, pub vtotal: u16, pub name_len: u16, pub mode_flags: u32, } impl TryParse for ModeInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (id, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (dot_clock, remaining) = u32::try_parse(remaining)?; let (hsync_start, remaining) = u16::try_parse(remaining)?; let (hsync_end, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u16::try_parse(remaining)?; let (vsync_start, remaining) = u16::try_parse(remaining)?; let (vsync_end, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let (name_len, remaining) = u16::try_parse(remaining)?; let (mode_flags, remaining) = u32::try_parse(remaining)?; let result = ModeInfo { id, width, height, dot_clock, hsync_start, hsync_end, htotal, hskew, vsync_start, vsync_end, vtotal, name_len, mode_flags }; Ok((result, remaining)) } } impl Serialize for ModeInfo { type Bytes = [u8; 32]; fn serialize(&self) -> [u8; 32] { let id_bytes = self.id.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let dot_clock_bytes = self.dot_clock.serialize(); let hsync_start_bytes = self.hsync_start.serialize(); let hsync_end_bytes = self.hsync_end.serialize(); let htotal_bytes = self.htotal.serialize(); let hskew_bytes = self.hskew.serialize(); let vsync_start_bytes = self.vsync_start.serialize(); let vsync_end_bytes = self.vsync_end.serialize(); let vtotal_bytes = self.vtotal.serialize(); let name_len_bytes = self.name_len.serialize(); let mode_flags_bytes = self.mode_flags.serialize(); [ id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], dot_clock_bytes[0], dot_clock_bytes[1], dot_clock_bytes[2], dot_clock_bytes[3], hsync_start_bytes[0], hsync_start_bytes[1], hsync_end_bytes[0], hsync_end_bytes[1], htotal_bytes[0], htotal_bytes[1], hskew_bytes[0], hskew_bytes[1], vsync_start_bytes[0], vsync_start_bytes[1], vsync_end_bytes[0], vsync_end_bytes[1], vtotal_bytes[0], vtotal_bytes[1], name_len_bytes[0], name_len_bytes[1], mode_flags_bytes[0], mode_flags_bytes[1], mode_flags_bytes[2], mode_flags_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(32); self.id.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.dot_clock.serialize_into(bytes); self.hsync_start.serialize_into(bytes); self.hsync_end.serialize_into(bytes); self.htotal.serialize_into(bytes); self.hskew.serialize_into(bytes); self.vsync_start.serialize_into(bytes); self.vsync_end.serialize_into(bytes); self.vtotal.serialize_into(bytes); self.name_len.serialize_into(bytes); self.mode_flags.serialize_into(bytes); } } /// Opcode for the GetScreenResources request pub const GET_SCREEN_RESOURCES_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenResourcesRequest { pub window: xproto::Window, } impl GetScreenResourcesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SCREEN_RESOURCES_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SCREEN_RESOURCES_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetScreenResourcesRequest { window, }) } } impl Request for GetScreenResourcesRequest { type Reply = GetScreenResourcesReply; } pub fn get_screen_resources(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetScreenResourcesRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetScreenResourcesReply { pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub crtcs: Vec, pub outputs: Vec, pub modes: Vec, pub names: Vec, } impl TryParse for GetScreenResourcesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (num_crtcs, remaining) = u16::try_parse(remaining)?; let (num_outputs, remaining) = u16::try_parse(remaining)?; let (num_modes, remaining) = u16::try_parse(remaining)?; let (names_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (crtcs, remaining) = crate::x11_utils::parse_list::(remaining, num_crtcs.try_to_usize()?)?; let (outputs, remaining) = crate::x11_utils::parse_list::(remaining, num_outputs.try_to_usize()?)?; let (modes, remaining) = crate::x11_utils::parse_list::(remaining, num_modes.try_to_usize()?)?; let (names, remaining) = crate::x11_utils::parse_u8_list(remaining, names_len.try_to_usize()?)?; let names = names.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetScreenResourcesReply { sequence, length, timestamp, config_timestamp, crtcs, outputs, modes, names }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetScreenResourcesReply { /// Get the value of the `num_crtcs` field. /// /// The `num_crtcs` field is used as the length field of the `crtcs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_crtcs(&self) -> u16 { self.crtcs.len() .try_into().unwrap() } /// Get the value of the `num_outputs` field. /// /// The `num_outputs` field is used as the length field of the `outputs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_outputs(&self) -> u16 { self.outputs.len() .try_into().unwrap() } /// Get the value of the `num_modes` field. /// /// The `num_modes` field is used as the length field of the `modes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_modes(&self) -> u16 { self.modes.len() .try_into().unwrap() } /// Get the value of the `names_len` field. /// /// The `names_len` field is used as the length field of the `names` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn names_len(&self) -> u16 { self.names.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Connection(u8); impl Connection { pub const CONNECTED: Self = Self(0); pub const DISCONNECTED: Self = Self(1); pub const UNKNOWN: Self = Self(2); } impl From for u8 { #[inline] fn from(input: Connection) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Connection) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Connection) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Connection) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Connection) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Connection) -> Self { Some(u32::from(input.0)) } } impl From for Connection { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Connection { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CONNECTED.0.into(), "CONNECTED", "Connected"), (Self::DISCONNECTED.0.into(), "DISCONNECTED", "Disconnected"), (Self::UNKNOWN.0.into(), "UNKNOWN", "Unknown"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the GetOutputInfo request pub const GET_OUTPUT_INFO_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetOutputInfoRequest { pub output: Output, pub config_timestamp: xproto::Timestamp, } impl GetOutputInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_OUTPUT_INFO_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_OUTPUT_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let _ = remaining; Ok(GetOutputInfoRequest { output, config_timestamp, }) } } impl Request for GetOutputInfoRequest { type Reply = GetOutputInfoReply; } pub fn get_output_info(conn: &Conn, output: Output, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetOutputInfoRequest { output, config_timestamp, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetOutputInfoReply { pub status: SetConfig, pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub crtc: Crtc, pub mm_width: u32, pub mm_height: u32, pub connection: Connection, pub subpixel_order: render::SubPixel, pub num_preferred: u16, pub crtcs: Vec, pub modes: Vec, pub clones: Vec, pub name: Vec, } impl TryParse for GetOutputInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (crtc, remaining) = Crtc::try_parse(remaining)?; let (mm_width, remaining) = u32::try_parse(remaining)?; let (mm_height, remaining) = u32::try_parse(remaining)?; let (connection, remaining) = u8::try_parse(remaining)?; let (subpixel_order, remaining) = u8::try_parse(remaining)?; let (num_crtcs, remaining) = u16::try_parse(remaining)?; let (num_modes, remaining) = u16::try_parse(remaining)?; let (num_preferred, remaining) = u16::try_parse(remaining)?; let (num_clones, remaining) = u16::try_parse(remaining)?; let (name_len, remaining) = u16::try_parse(remaining)?; let (crtcs, remaining) = crate::x11_utils::parse_list::(remaining, num_crtcs.try_to_usize()?)?; let (modes, remaining) = crate::x11_utils::parse_list::(remaining, num_modes.try_to_usize()?)?; let (clones, remaining) = crate::x11_utils::parse_list::(remaining, num_clones.try_to_usize()?)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let connection = connection.into(); let subpixel_order = subpixel_order.into(); let result = GetOutputInfoReply { status, sequence, length, timestamp, crtc, mm_width, mm_height, connection, subpixel_order, num_preferred, crtcs, modes, clones, name }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetOutputInfoReply { /// Get the value of the `num_crtcs` field. /// /// The `num_crtcs` field is used as the length field of the `crtcs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_crtcs(&self) -> u16 { self.crtcs.len() .try_into().unwrap() } /// Get the value of the `num_modes` field. /// /// The `num_modes` field is used as the length field of the `modes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_modes(&self) -> u16 { self.modes.len() .try_into().unwrap() } /// Get the value of the `num_clones` field. /// /// The `num_clones` field is used as the length field of the `clones` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_clones(&self) -> u16 { self.clones.len() .try_into().unwrap() } /// Get the value of the `name_len` field. /// /// The `name_len` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u16 { self.name.len() .try_into().unwrap() } } /// Opcode for the ListOutputProperties request pub const LIST_OUTPUT_PROPERTIES_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListOutputPropertiesRequest { pub output: Output, } impl ListOutputPropertiesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_OUTPUT_PROPERTIES_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_OUTPUT_PROPERTIES_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let _ = remaining; Ok(ListOutputPropertiesRequest { output, }) } } impl Request for ListOutputPropertiesRequest { type Reply = ListOutputPropertiesReply; } pub fn list_output_properties(conn: &Conn, output: Output) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListOutputPropertiesRequest { output, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListOutputPropertiesReply { pub sequence: u16, pub length: u32, pub atoms: Vec, } impl TryParse for ListOutputPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_atoms, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (atoms, remaining) = crate::x11_utils::parse_list::(remaining, num_atoms.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListOutputPropertiesReply { sequence, length, atoms }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListOutputPropertiesReply { /// Get the value of the `num_atoms` field. /// /// The `num_atoms` field is used as the length field of the `atoms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_atoms(&self) -> u16 { self.atoms.len() .try_into().unwrap() } } /// Opcode for the QueryOutputProperty request pub const QUERY_OUTPUT_PROPERTY_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryOutputPropertyRequest { pub output: Output, pub property: xproto::Atom, } impl QueryOutputPropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let property_bytes = self.property.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_OUTPUT_PROPERTY_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_OUTPUT_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(QueryOutputPropertyRequest { output, property, }) } } impl Request for QueryOutputPropertyRequest { type Reply = QueryOutputPropertyReply; } pub fn query_output_property(conn: &Conn, output: Output, property: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryOutputPropertyRequest { output, property, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryOutputPropertyReply { pub sequence: u16, pub pending: bool, pub range: bool, pub immutable: bool, pub valid_values: Vec, } impl TryParse for QueryOutputPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (pending, remaining) = bool::try_parse(remaining)?; let (range, remaining) = bool::try_parse(remaining)?; let (immutable, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(21..).ok_or(ParseError::InsufficientData)?; let (valid_values, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryOutputPropertyReply { sequence, pending, range, immutable, valid_values }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryOutputPropertyReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `validValues` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.valid_values.len() .try_into().unwrap() } } /// Opcode for the ConfigureOutputProperty request pub const CONFIGURE_OUTPUT_PROPERTY_REQUEST: u8 = 12; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConfigureOutputPropertyRequest<'input> { pub output: Output, pub property: xproto::Atom, pub pending: bool, pub range: bool, pub values: Cow<'input, [i32]>, } impl<'input> ConfigureOutputPropertyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let property_bytes = self.property.serialize(); let pending_bytes = self.pending.serialize(); let range_bytes = self.range.serialize(); let mut request0 = vec![ extension_information.major_opcode, CONFIGURE_OUTPUT_PROPERTY_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], pending_bytes[0], range_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let values_bytes = self.values.serialize(); let length_so_far = length_so_far + values_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), values_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CONFIGURE_OUTPUT_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (pending, remaining) = bool::try_parse(remaining)?; let (range, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut values = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = i32::try_parse(remaining)?; remaining = new_remaining; values.push(v); } let _ = remaining; Ok(ConfigureOutputPropertyRequest { output, property, pending, range, values: Cow::Owned(values), }) } /// Clone all borrowed data in this ConfigureOutputPropertyRequest. pub fn into_owned(self) -> ConfigureOutputPropertyRequest<'static> { ConfigureOutputPropertyRequest { output: self.output, property: self.property, pending: self.pending, range: self.range, values: Cow::Owned(self.values.into_owned()), } } } impl<'input> Request for ConfigureOutputPropertyRequest<'input> { type Reply = (); } pub fn configure_output_property<'c, 'input, Conn>(conn: &'c Conn, output: Output, property: xproto::Atom, pending: bool, range: bool, values: &'input [i32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ConfigureOutputPropertyRequest { output, property, pending, range, values: Cow::Borrowed(values), }; request0.send(conn) } /// Opcode for the ChangeOutputProperty request pub const CHANGE_OUTPUT_PROPERTY_REQUEST: u8 = 13; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeOutputPropertyRequest<'input> { pub output: Output, pub property: xproto::Atom, pub type_: xproto::Atom, pub format: u8, pub mode: xproto::PropMode, pub num_units: u32, pub data: Cow<'input, [u8]>, } impl<'input> ChangeOutputPropertyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let format_bytes = self.format.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let num_units_bytes = self.num_units.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_OUTPUT_PROPERTY_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], format_bytes[0], mode_bytes[0], 0, 0, num_units_bytes[0], num_units_bytes[1], num_units_bytes[2], num_units_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(self.data.len(), usize::try_from(self.num_units.checked_mul(u32::from(self.format)).unwrap().checked_div(8u32).unwrap()).unwrap(), "`data` has an incorrect length"); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_OUTPUT_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (num_units, remaining) = u32::try_parse(remaining)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, num_units.checked_mul(u32::from(format)).ok_or(ParseError::InvalidExpression)?.checked_div(8u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(ChangeOutputPropertyRequest { output, property, type_, format, mode, num_units, data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this ChangeOutputPropertyRequest. pub fn into_owned(self) -> ChangeOutputPropertyRequest<'static> { ChangeOutputPropertyRequest { output: self.output, property: self.property, type_: self.type_, format: self.format, mode: self.mode, num_units: self.num_units, data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for ChangeOutputPropertyRequest<'input> { type Reply = (); } pub fn change_output_property<'c, 'input, Conn>(conn: &'c Conn, output: Output, property: xproto::Atom, type_: xproto::Atom, format: u8, mode: xproto::PropMode, num_units: u32, data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeOutputPropertyRequest { output, property, type_, format, mode, num_units, data: Cow::Borrowed(data), }; request0.send(conn) } /// Opcode for the DeleteOutputProperty request pub const DELETE_OUTPUT_PROPERTY_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeleteOutputPropertyRequest { pub output: Output, pub property: xproto::Atom, } impl DeleteOutputPropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let property_bytes = self.property.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_OUTPUT_PROPERTY_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_OUTPUT_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(DeleteOutputPropertyRequest { output, property, }) } } impl Request for DeleteOutputPropertyRequest { type Reply = (); } pub fn delete_output_property(conn: &Conn, output: Output, property: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteOutputPropertyRequest { output, property, }; request0.send(conn) } /// Opcode for the GetOutputProperty request pub const GET_OUTPUT_PROPERTY_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetOutputPropertyRequest { pub output: Output, pub property: xproto::Atom, pub type_: xproto::Atom, pub long_offset: u32, pub long_length: u32, pub delete: bool, pub pending: bool, } impl GetOutputPropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let long_offset_bytes = self.long_offset.serialize(); let long_length_bytes = self.long_length.serialize(); let delete_bytes = self.delete.serialize(); let pending_bytes = self.pending.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_OUTPUT_PROPERTY_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], long_offset_bytes[0], long_offset_bytes[1], long_offset_bytes[2], long_offset_bytes[3], long_length_bytes[0], long_length_bytes[1], long_length_bytes[2], long_length_bytes[3], delete_bytes[0], pending_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_OUTPUT_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (long_offset, remaining) = u32::try_parse(remaining)?; let (long_length, remaining) = u32::try_parse(remaining)?; let (delete, remaining) = bool::try_parse(remaining)?; let (pending, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetOutputPropertyRequest { output, property, type_, long_offset, long_length, delete, pending, }) } } impl Request for GetOutputPropertyRequest { type Reply = GetOutputPropertyReply; } pub fn get_output_property(conn: &Conn, output: Output, property: xproto::Atom, type_: A, long_offset: u32, long_length: u32, delete: bool, pending: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let type_: xproto::Atom = type_.into(); let request0 = GetOutputPropertyRequest { output, property, type_, long_offset, long_length, delete, pending, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetOutputPropertyReply { pub format: u8, pub sequence: u16, pub length: u32, pub type_: xproto::Atom, pub bytes_after: u32, pub num_items: u32, pub data: Vec, } impl TryParse for GetOutputPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (bytes_after, remaining) = u32::try_parse(remaining)?; let (num_items, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, num_items.checked_mul(u32::from(format).checked_div(8u32).ok_or(ParseError::InvalidExpression)?).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetOutputPropertyReply { format, sequence, length, type_, bytes_after, num_items, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the CreateMode request pub const CREATE_MODE_REQUEST: u8 = 16; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateModeRequest<'input> { pub window: xproto::Window, pub mode_info: ModeInfo, pub name: Cow<'input, [u8]>, } impl<'input> CreateModeRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mode_info_bytes = self.mode_info.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_MODE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], mode_info_bytes[0], mode_info_bytes[1], mode_info_bytes[2], mode_info_bytes[3], mode_info_bytes[4], mode_info_bytes[5], mode_info_bytes[6], mode_info_bytes[7], mode_info_bytes[8], mode_info_bytes[9], mode_info_bytes[10], mode_info_bytes[11], mode_info_bytes[12], mode_info_bytes[13], mode_info_bytes[14], mode_info_bytes[15], mode_info_bytes[16], mode_info_bytes[17], mode_info_bytes[18], mode_info_bytes[19], mode_info_bytes[20], mode_info_bytes[21], mode_info_bytes[22], mode_info_bytes[23], mode_info_bytes[24], mode_info_bytes[25], mode_info_bytes[26], mode_info_bytes[27], mode_info_bytes[28], mode_info_bytes[29], mode_info_bytes[30], mode_info_bytes[31], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.name.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.name, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (mode_info, remaining) = ModeInfo::try_parse(remaining)?; let (name, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(CreateModeRequest { window, mode_info, name: Cow::Borrowed(name), }) } /// Clone all borrowed data in this CreateModeRequest. pub fn into_owned(self) -> CreateModeRequest<'static> { CreateModeRequest { window: self.window, mode_info: self.mode_info, name: Cow::Owned(self.name.into_owned()), } } } impl<'input> Request for CreateModeRequest<'input> { type Reply = CreateModeReply; } pub fn create_mode<'c, 'input, Conn>(conn: &'c Conn, window: xproto::Window, mode_info: ModeInfo, name: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateModeRequest { window, mode_info, name: Cow::Borrowed(name), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateModeReply { pub sequence: u16, pub length: u32, pub mode: Mode, } impl TryParse for CreateModeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (mode, remaining) = Mode::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateModeReply { sequence, length, mode }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the DestroyMode request pub const DESTROY_MODE_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyModeRequest { pub mode: Mode, } impl DestroyModeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mode_bytes = self.mode.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_MODE_REQUEST, 0, 0, mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (mode, remaining) = Mode::try_parse(value)?; let _ = remaining; Ok(DestroyModeRequest { mode, }) } } impl Request for DestroyModeRequest { type Reply = (); } pub fn destroy_mode(conn: &Conn, mode: Mode) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyModeRequest { mode, }; request0.send(conn) } /// Opcode for the AddOutputMode request pub const ADD_OUTPUT_MODE_REQUEST: u8 = 18; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AddOutputModeRequest { pub output: Output, pub mode: Mode, } impl AddOutputModeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let mode_bytes = self.mode.serialize(); let mut request0 = vec![ extension_information.major_opcode, ADD_OUTPUT_MODE_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != ADD_OUTPUT_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (mode, remaining) = Mode::try_parse(remaining)?; let _ = remaining; Ok(AddOutputModeRequest { output, mode, }) } } impl Request for AddOutputModeRequest { type Reply = (); } pub fn add_output_mode(conn: &Conn, output: Output, mode: Mode) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AddOutputModeRequest { output, mode, }; request0.send(conn) } /// Opcode for the DeleteOutputMode request pub const DELETE_OUTPUT_MODE_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeleteOutputModeRequest { pub output: Output, pub mode: Mode, } impl DeleteOutputModeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_bytes = self.output.serialize(); let mode_bytes = self.mode.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_OUTPUT_MODE_REQUEST, 0, 0, output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_OUTPUT_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (output, remaining) = Output::try_parse(value)?; let (mode, remaining) = Mode::try_parse(remaining)?; let _ = remaining; Ok(DeleteOutputModeRequest { output, mode, }) } } impl Request for DeleteOutputModeRequest { type Reply = (); } pub fn delete_output_mode(conn: &Conn, output: Output, mode: Mode) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteOutputModeRequest { output, mode, }; request0.send(conn) } /// Opcode for the GetCrtcInfo request pub const GET_CRTC_INFO_REQUEST: u8 = 20; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCrtcInfoRequest { pub crtc: Crtc, pub config_timestamp: xproto::Timestamp, } impl GetCrtcInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CRTC_INFO_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CRTC_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let _ = remaining; Ok(GetCrtcInfoRequest { crtc, config_timestamp, }) } } impl Request for GetCrtcInfoRequest { type Reply = GetCrtcInfoReply; } pub fn get_crtc_info(conn: &Conn, crtc: Crtc, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCrtcInfoRequest { crtc, config_timestamp, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCrtcInfoReply { pub status: SetConfig, pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub mode: Mode, pub rotation: u16, pub rotations: u16, pub outputs: Vec, pub possible: Vec, } impl TryParse for GetCrtcInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (mode, remaining) = Mode::try_parse(remaining)?; let (rotation, remaining) = u16::try_parse(remaining)?; let (rotations, remaining) = u16::try_parse(remaining)?; let (num_outputs, remaining) = u16::try_parse(remaining)?; let (num_possible_outputs, remaining) = u16::try_parse(remaining)?; let (outputs, remaining) = crate::x11_utils::parse_list::(remaining, num_outputs.try_to_usize()?)?; let (possible, remaining) = crate::x11_utils::parse_list::(remaining, num_possible_outputs.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = GetCrtcInfoReply { status, sequence, length, timestamp, x, y, width, height, mode, rotation, rotations, outputs, possible }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetCrtcInfoReply { /// Get the value of the `num_outputs` field. /// /// The `num_outputs` field is used as the length field of the `outputs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_outputs(&self) -> u16 { self.outputs.len() .try_into().unwrap() } /// Get the value of the `num_possible_outputs` field. /// /// The `num_possible_outputs` field is used as the length field of the `possible` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_possible_outputs(&self) -> u16 { self.possible.len() .try_into().unwrap() } } /// Opcode for the SetCrtcConfig request pub const SET_CRTC_CONFIG_REQUEST: u8 = 21; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetCrtcConfigRequest<'input> { pub crtc: Crtc, pub timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub x: i16, pub y: i16, pub mode: Mode, pub rotation: u16, pub outputs: Cow<'input, [Output]>, } impl<'input> SetCrtcConfigRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let timestamp_bytes = self.timestamp.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let mode_bytes = self.mode.serialize(); let rotation_bytes = self.rotation.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CRTC_CONFIG_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], rotation_bytes[0], rotation_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let outputs_bytes = self.outputs.serialize(); let length_so_far = length_so_far + outputs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), outputs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_CRTC_CONFIG_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (mode, remaining) = Mode::try_parse(remaining)?; let (rotation, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut outputs = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Output::try_parse(remaining)?; remaining = new_remaining; outputs.push(v); } let _ = remaining; Ok(SetCrtcConfigRequest { crtc, timestamp, config_timestamp, x, y, mode, rotation, outputs: Cow::Owned(outputs), }) } /// Clone all borrowed data in this SetCrtcConfigRequest. pub fn into_owned(self) -> SetCrtcConfigRequest<'static> { SetCrtcConfigRequest { crtc: self.crtc, timestamp: self.timestamp, config_timestamp: self.config_timestamp, x: self.x, y: self.y, mode: self.mode, rotation: self.rotation, outputs: Cow::Owned(self.outputs.into_owned()), } } } impl<'input> Request for SetCrtcConfigRequest<'input> { type Reply = SetCrtcConfigReply; } pub fn set_crtc_config<'c, 'input, Conn, A>(conn: &'c Conn, crtc: Crtc, timestamp: xproto::Timestamp, config_timestamp: xproto::Timestamp, x: i16, y: i16, mode: Mode, rotation: A, outputs: &'input [Output]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let rotation: u16 = rotation.into(); let request0 = SetCrtcConfigRequest { crtc, timestamp, config_timestamp, x, y, mode, rotation, outputs: Cow::Borrowed(outputs), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetCrtcConfigReply { pub status: SetConfig, pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, } impl TryParse for SetCrtcConfigReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = SetCrtcConfigReply { status, sequence, length, timestamp }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetCrtcGammaSize request pub const GET_CRTC_GAMMA_SIZE_REQUEST: u8 = 22; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCrtcGammaSizeRequest { pub crtc: Crtc, } impl GetCrtcGammaSizeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CRTC_GAMMA_SIZE_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CRTC_GAMMA_SIZE_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let _ = remaining; Ok(GetCrtcGammaSizeRequest { crtc, }) } } impl Request for GetCrtcGammaSizeRequest { type Reply = GetCrtcGammaSizeReply; } pub fn get_crtc_gamma_size(conn: &Conn, crtc: Crtc) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCrtcGammaSizeRequest { crtc, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCrtcGammaSizeReply { pub sequence: u16, pub length: u32, pub size: u16, } impl TryParse for GetCrtcGammaSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (size, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCrtcGammaSizeReply { sequence, length, size }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetCrtcGamma request pub const GET_CRTC_GAMMA_REQUEST: u8 = 23; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCrtcGammaRequest { pub crtc: Crtc, } impl GetCrtcGammaRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CRTC_GAMMA_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CRTC_GAMMA_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let _ = remaining; Ok(GetCrtcGammaRequest { crtc, }) } } impl Request for GetCrtcGammaRequest { type Reply = GetCrtcGammaReply; } pub fn get_crtc_gamma(conn: &Conn, crtc: Crtc) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCrtcGammaRequest { crtc, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCrtcGammaReply { pub sequence: u16, pub length: u32, pub red: Vec, pub green: Vec, pub blue: Vec, } impl TryParse for GetCrtcGammaReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (size, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (red, remaining) = crate::x11_utils::parse_list::(remaining, size.try_to_usize()?)?; let (green, remaining) = crate::x11_utils::parse_list::(remaining, size.try_to_usize()?)?; let (blue, remaining) = crate::x11_utils::parse_list::(remaining, size.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCrtcGammaReply { sequence, length, red, green, blue }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetCrtcGammaReply { /// Get the value of the `size` field. /// /// The `size` field is used as the length field of the `red` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn size(&self) -> u16 { self.red.len() .try_into().unwrap() } } /// Opcode for the SetCrtcGamma request pub const SET_CRTC_GAMMA_REQUEST: u8 = 24; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetCrtcGammaRequest<'input> { pub crtc: Crtc, pub red: Cow<'input, [u16]>, pub green: Cow<'input, [u16]>, pub blue: Cow<'input, [u16]>, } impl<'input> SetCrtcGammaRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let size = u16::try_from(self.red.len()).expect("`red` has too many elements"); let size_bytes = size.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CRTC_GAMMA_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], size_bytes[0], size_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let red_bytes = self.red.serialize(); let length_so_far = length_so_far + red_bytes.len(); assert_eq!(self.green.len(), usize::try_from(size).unwrap(), "`green` has an incorrect length"); let green_bytes = self.green.serialize(); let length_so_far = length_so_far + green_bytes.len(); assert_eq!(self.blue.len(), usize::try_from(size).unwrap(), "`blue` has an incorrect length"); let blue_bytes = self.blue.serialize(); let length_so_far = length_so_far + blue_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), red_bytes.into(), green_bytes.into(), blue_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_CRTC_GAMMA_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let (size, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (red, remaining) = crate::x11_utils::parse_list::(remaining, size.try_to_usize()?)?; let (green, remaining) = crate::x11_utils::parse_list::(remaining, size.try_to_usize()?)?; let (blue, remaining) = crate::x11_utils::parse_list::(remaining, size.try_to_usize()?)?; let _ = remaining; Ok(SetCrtcGammaRequest { crtc, red: Cow::Owned(red), green: Cow::Owned(green), blue: Cow::Owned(blue), }) } /// Clone all borrowed data in this SetCrtcGammaRequest. pub fn into_owned(self) -> SetCrtcGammaRequest<'static> { SetCrtcGammaRequest { crtc: self.crtc, red: Cow::Owned(self.red.into_owned()), green: Cow::Owned(self.green.into_owned()), blue: Cow::Owned(self.blue.into_owned()), } } } impl<'input> Request for SetCrtcGammaRequest<'input> { type Reply = (); } pub fn set_crtc_gamma<'c, 'input, Conn>(conn: &'c Conn, crtc: Crtc, red: &'input [u16], green: &'input [u16], blue: &'input [u16]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetCrtcGammaRequest { crtc, red: Cow::Borrowed(red), green: Cow::Borrowed(green), blue: Cow::Borrowed(blue), }; request0.send(conn) } /// Opcode for the GetScreenResourcesCurrent request pub const GET_SCREEN_RESOURCES_CURRENT_REQUEST: u8 = 25; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenResourcesCurrentRequest { pub window: xproto::Window, } impl GetScreenResourcesCurrentRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SCREEN_RESOURCES_CURRENT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SCREEN_RESOURCES_CURRENT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetScreenResourcesCurrentRequest { window, }) } } impl Request for GetScreenResourcesCurrentRequest { type Reply = GetScreenResourcesCurrentReply; } pub fn get_screen_resources_current(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetScreenResourcesCurrentRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetScreenResourcesCurrentReply { pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub crtcs: Vec, pub outputs: Vec, pub modes: Vec, pub names: Vec, } impl TryParse for GetScreenResourcesCurrentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (num_crtcs, remaining) = u16::try_parse(remaining)?; let (num_outputs, remaining) = u16::try_parse(remaining)?; let (num_modes, remaining) = u16::try_parse(remaining)?; let (names_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (crtcs, remaining) = crate::x11_utils::parse_list::(remaining, num_crtcs.try_to_usize()?)?; let (outputs, remaining) = crate::x11_utils::parse_list::(remaining, num_outputs.try_to_usize()?)?; let (modes, remaining) = crate::x11_utils::parse_list::(remaining, num_modes.try_to_usize()?)?; let (names, remaining) = crate::x11_utils::parse_u8_list(remaining, names_len.try_to_usize()?)?; let names = names.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetScreenResourcesCurrentReply { sequence, length, timestamp, config_timestamp, crtcs, outputs, modes, names }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetScreenResourcesCurrentReply { /// Get the value of the `num_crtcs` field. /// /// The `num_crtcs` field is used as the length field of the `crtcs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_crtcs(&self) -> u16 { self.crtcs.len() .try_into().unwrap() } /// Get the value of the `num_outputs` field. /// /// The `num_outputs` field is used as the length field of the `outputs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_outputs(&self) -> u16 { self.outputs.len() .try_into().unwrap() } /// Get the value of the `num_modes` field. /// /// The `num_modes` field is used as the length field of the `modes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_modes(&self) -> u16 { self.modes.len() .try_into().unwrap() } /// Get the value of the `names_len` field. /// /// The `names_len` field is used as the length field of the `names` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn names_len(&self) -> u16 { self.names.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Transform(u8); impl Transform { pub const UNIT: Self = Self(1 << 0); pub const SCALE_UP: Self = Self(1 << 1); pub const SCALE_DOWN: Self = Self(1 << 2); pub const PROJECTIVE: Self = Self(1 << 3); } impl From for u8 { #[inline] fn from(input: Transform) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Transform) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Transform) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Transform) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Transform) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Transform) -> Self { Some(u32::from(input.0)) } } impl From for Transform { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Transform { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::UNIT.0.into(), "UNIT", "Unit"), (Self::SCALE_UP.0.into(), "SCALE_UP", "ScaleUp"), (Self::SCALE_DOWN.0.into(), "SCALE_DOWN", "ScaleDown"), (Self::PROJECTIVE.0.into(), "PROJECTIVE", "Projective"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(Transform, u8); /// Opcode for the SetCrtcTransform request pub const SET_CRTC_TRANSFORM_REQUEST: u8 = 26; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetCrtcTransformRequest<'input> { pub crtc: Crtc, pub transform: render::Transform, pub filter_name: Cow<'input, [u8]>, pub filter_params: Cow<'input, [render::Fixed]>, } impl<'input> SetCrtcTransformRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let transform_bytes = self.transform.serialize(); let filter_len = u16::try_from(self.filter_name.len()).expect("`filter_name` has too many elements"); let filter_len_bytes = filter_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CRTC_TRANSFORM_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], transform_bytes[0], transform_bytes[1], transform_bytes[2], transform_bytes[3], transform_bytes[4], transform_bytes[5], transform_bytes[6], transform_bytes[7], transform_bytes[8], transform_bytes[9], transform_bytes[10], transform_bytes[11], transform_bytes[12], transform_bytes[13], transform_bytes[14], transform_bytes[15], transform_bytes[16], transform_bytes[17], transform_bytes[18], transform_bytes[19], transform_bytes[20], transform_bytes[21], transform_bytes[22], transform_bytes[23], transform_bytes[24], transform_bytes[25], transform_bytes[26], transform_bytes[27], transform_bytes[28], transform_bytes[29], transform_bytes[30], transform_bytes[31], transform_bytes[32], transform_bytes[33], transform_bytes[34], transform_bytes[35], filter_len_bytes[0], filter_len_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.filter_name.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); let filter_params_bytes = self.filter_params.serialize(); let length_so_far = length_so_far + filter_params_bytes.len(); let padding1 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding1.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.filter_name, padding0.into(), filter_params_bytes.into(), padding1.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_CRTC_TRANSFORM_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let (transform, remaining) = render::Transform::try_parse(remaining)?; let (filter_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (filter_name, remaining) = crate::x11_utils::parse_u8_list(remaining, filter_len.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut filter_params = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = render::Fixed::try_parse(remaining)?; remaining = new_remaining; filter_params.push(v); } let _ = remaining; Ok(SetCrtcTransformRequest { crtc, transform, filter_name: Cow::Borrowed(filter_name), filter_params: Cow::Owned(filter_params), }) } /// Clone all borrowed data in this SetCrtcTransformRequest. pub fn into_owned(self) -> SetCrtcTransformRequest<'static> { SetCrtcTransformRequest { crtc: self.crtc, transform: self.transform, filter_name: Cow::Owned(self.filter_name.into_owned()), filter_params: Cow::Owned(self.filter_params.into_owned()), } } } impl<'input> Request for SetCrtcTransformRequest<'input> { type Reply = (); } pub fn set_crtc_transform<'c, 'input, Conn>(conn: &'c Conn, crtc: Crtc, transform: render::Transform, filter_name: &'input [u8], filter_params: &'input [render::Fixed]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetCrtcTransformRequest { crtc, transform, filter_name: Cow::Borrowed(filter_name), filter_params: Cow::Borrowed(filter_params), }; request0.send(conn) } /// Opcode for the GetCrtcTransform request pub const GET_CRTC_TRANSFORM_REQUEST: u8 = 27; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCrtcTransformRequest { pub crtc: Crtc, } impl GetCrtcTransformRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CRTC_TRANSFORM_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CRTC_TRANSFORM_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let _ = remaining; Ok(GetCrtcTransformRequest { crtc, }) } } impl Request for GetCrtcTransformRequest { type Reply = GetCrtcTransformReply; } pub fn get_crtc_transform(conn: &Conn, crtc: Crtc) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCrtcTransformRequest { crtc, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCrtcTransformReply { pub sequence: u16, pub length: u32, pub pending_transform: render::Transform, pub has_transforms: bool, pub current_transform: render::Transform, pub pending_filter_name: Vec, pub pending_params: Vec, pub current_filter_name: Vec, pub current_params: Vec, } impl TryParse for GetCrtcTransformReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (pending_transform, remaining) = render::Transform::try_parse(remaining)?; let (has_transforms, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (current_transform, remaining) = render::Transform::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (pending_len, remaining) = u16::try_parse(remaining)?; let (pending_nparams, remaining) = u16::try_parse(remaining)?; let (current_len, remaining) = u16::try_parse(remaining)?; let (current_nparams, remaining) = u16::try_parse(remaining)?; let (pending_filter_name, remaining) = crate::x11_utils::parse_u8_list(remaining, pending_len.try_to_usize()?)?; let pending_filter_name = pending_filter_name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (pending_params, remaining) = crate::x11_utils::parse_list::(remaining, pending_nparams.try_to_usize()?)?; let (current_filter_name, remaining) = crate::x11_utils::parse_u8_list(remaining, current_len.try_to_usize()?)?; let current_filter_name = current_filter_name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (current_params, remaining) = crate::x11_utils::parse_list::(remaining, current_nparams.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCrtcTransformReply { sequence, length, pending_transform, has_transforms, current_transform, pending_filter_name, pending_params, current_filter_name, current_params }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetCrtcTransformReply { /// Get the value of the `pending_len` field. /// /// The `pending_len` field is used as the length field of the `pending_filter_name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn pending_len(&self) -> u16 { self.pending_filter_name.len() .try_into().unwrap() } /// Get the value of the `pending_nparams` field. /// /// The `pending_nparams` field is used as the length field of the `pending_params` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn pending_nparams(&self) -> u16 { self.pending_params.len() .try_into().unwrap() } /// Get the value of the `current_len` field. /// /// The `current_len` field is used as the length field of the `current_filter_name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn current_len(&self) -> u16 { self.current_filter_name.len() .try_into().unwrap() } /// Get the value of the `current_nparams` field. /// /// The `current_nparams` field is used as the length field of the `current_params` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn current_nparams(&self) -> u16 { self.current_params.len() .try_into().unwrap() } } /// Opcode for the GetPanning request pub const GET_PANNING_REQUEST: u8 = 28; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPanningRequest { pub crtc: Crtc, } impl GetPanningRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PANNING_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PANNING_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let _ = remaining; Ok(GetPanningRequest { crtc, }) } } impl Request for GetPanningRequest { type Reply = GetPanningReply; } pub fn get_panning(conn: &Conn, crtc: Crtc) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPanningRequest { crtc, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPanningReply { pub status: SetConfig, pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub left: u16, pub top: u16, pub width: u16, pub height: u16, pub track_left: u16, pub track_top: u16, pub track_width: u16, pub track_height: u16, pub border_left: i16, pub border_top: i16, pub border_right: i16, pub border_bottom: i16, } impl TryParse for GetPanningReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (left, remaining) = u16::try_parse(remaining)?; let (top, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (track_left, remaining) = u16::try_parse(remaining)?; let (track_top, remaining) = u16::try_parse(remaining)?; let (track_width, remaining) = u16::try_parse(remaining)?; let (track_height, remaining) = u16::try_parse(remaining)?; let (border_left, remaining) = i16::try_parse(remaining)?; let (border_top, remaining) = i16::try_parse(remaining)?; let (border_right, remaining) = i16::try_parse(remaining)?; let (border_bottom, remaining) = i16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = GetPanningReply { status, sequence, length, timestamp, left, top, width, height, track_left, track_top, track_width, track_height, border_left, border_top, border_right, border_bottom }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetPanning request pub const SET_PANNING_REQUEST: u8 = 29; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetPanningRequest { pub crtc: Crtc, pub timestamp: xproto::Timestamp, pub left: u16, pub top: u16, pub width: u16, pub height: u16, pub track_left: u16, pub track_top: u16, pub track_width: u16, pub track_height: u16, pub border_left: i16, pub border_top: i16, pub border_right: i16, pub border_bottom: i16, } impl SetPanningRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let crtc_bytes = self.crtc.serialize(); let timestamp_bytes = self.timestamp.serialize(); let left_bytes = self.left.serialize(); let top_bytes = self.top.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let track_left_bytes = self.track_left.serialize(); let track_top_bytes = self.track_top.serialize(); let track_width_bytes = self.track_width.serialize(); let track_height_bytes = self.track_height.serialize(); let border_left_bytes = self.border_left.serialize(); let border_top_bytes = self.border_top.serialize(); let border_right_bytes = self.border_right.serialize(); let border_bottom_bytes = self.border_bottom.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PANNING_REQUEST, 0, 0, crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], left_bytes[0], left_bytes[1], top_bytes[0], top_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], track_left_bytes[0], track_left_bytes[1], track_top_bytes[0], track_top_bytes[1], track_width_bytes[0], track_width_bytes[1], track_height_bytes[0], track_height_bytes[1], border_left_bytes[0], border_left_bytes[1], border_top_bytes[0], border_top_bytes[1], border_right_bytes[0], border_right_bytes[1], border_bottom_bytes[0], border_bottom_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_PANNING_REQUEST { return Err(ParseError::InvalidValue); } let (crtc, remaining) = Crtc::try_parse(value)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (left, remaining) = u16::try_parse(remaining)?; let (top, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (track_left, remaining) = u16::try_parse(remaining)?; let (track_top, remaining) = u16::try_parse(remaining)?; let (track_width, remaining) = u16::try_parse(remaining)?; let (track_height, remaining) = u16::try_parse(remaining)?; let (border_left, remaining) = i16::try_parse(remaining)?; let (border_top, remaining) = i16::try_parse(remaining)?; let (border_right, remaining) = i16::try_parse(remaining)?; let (border_bottom, remaining) = i16::try_parse(remaining)?; let _ = remaining; Ok(SetPanningRequest { crtc, timestamp, left, top, width, height, track_left, track_top, track_width, track_height, border_left, border_top, border_right, border_bottom, }) } } impl Request for SetPanningRequest { type Reply = SetPanningReply; } pub fn set_panning(conn: &Conn, crtc: Crtc, timestamp: xproto::Timestamp, left: u16, top: u16, width: u16, height: u16, track_left: u16, track_top: u16, track_width: u16, track_height: u16, border_left: i16, border_top: i16, border_right: i16, border_bottom: i16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPanningRequest { crtc, timestamp, left, top, width, height, track_left, track_top, track_width, track_height, border_left, border_top, border_right, border_bottom, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetPanningReply { pub status: SetConfig, pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, } impl TryParse for SetPanningReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = SetPanningReply { status, sequence, length, timestamp }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetOutputPrimary request pub const SET_OUTPUT_PRIMARY_REQUEST: u8 = 30; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetOutputPrimaryRequest { pub window: xproto::Window, pub output: Output, } impl SetOutputPrimaryRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let output_bytes = self.output.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_OUTPUT_PRIMARY_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_OUTPUT_PRIMARY_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (output, remaining) = Output::try_parse(remaining)?; let _ = remaining; Ok(SetOutputPrimaryRequest { window, output, }) } } impl Request for SetOutputPrimaryRequest { type Reply = (); } pub fn set_output_primary(conn: &Conn, window: xproto::Window, output: Output) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetOutputPrimaryRequest { window, output, }; request0.send(conn) } /// Opcode for the GetOutputPrimary request pub const GET_OUTPUT_PRIMARY_REQUEST: u8 = 31; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetOutputPrimaryRequest { pub window: xproto::Window, } impl GetOutputPrimaryRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_OUTPUT_PRIMARY_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_OUTPUT_PRIMARY_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetOutputPrimaryRequest { window, }) } } impl Request for GetOutputPrimaryRequest { type Reply = GetOutputPrimaryReply; } pub fn get_output_primary(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetOutputPrimaryRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetOutputPrimaryReply { pub sequence: u16, pub length: u32, pub output: Output, } impl TryParse for GetOutputPrimaryReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (output, remaining) = Output::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetOutputPrimaryReply { sequence, length, output }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetProviders request pub const GET_PROVIDERS_REQUEST: u8 = 32; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetProvidersRequest { pub window: xproto::Window, } impl GetProvidersRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PROVIDERS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PROVIDERS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetProvidersRequest { window, }) } } impl Request for GetProvidersRequest { type Reply = GetProvidersReply; } pub fn get_providers(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetProvidersRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetProvidersReply { pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub providers: Vec, } impl TryParse for GetProvidersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (num_providers, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(18..).ok_or(ParseError::InsufficientData)?; let (providers, remaining) = crate::x11_utils::parse_list::(remaining, num_providers.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetProvidersReply { sequence, length, timestamp, providers }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetProvidersReply { /// Get the value of the `num_providers` field. /// /// The `num_providers` field is used as the length field of the `providers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_providers(&self) -> u16 { self.providers.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ProviderCapability(u8); impl ProviderCapability { pub const SOURCE_OUTPUT: Self = Self(1 << 0); pub const SINK_OUTPUT: Self = Self(1 << 1); pub const SOURCE_OFFLOAD: Self = Self(1 << 2); pub const SINK_OFFLOAD: Self = Self(1 << 3); } impl From for u8 { #[inline] fn from(input: ProviderCapability) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ProviderCapability) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ProviderCapability) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ProviderCapability) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ProviderCapability) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ProviderCapability) -> Self { Some(u32::from(input.0)) } } impl From for ProviderCapability { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ProviderCapability { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SOURCE_OUTPUT.0.into(), "SOURCE_OUTPUT", "SourceOutput"), (Self::SINK_OUTPUT.0.into(), "SINK_OUTPUT", "SinkOutput"), (Self::SOURCE_OFFLOAD.0.into(), "SOURCE_OFFLOAD", "SourceOffload"), (Self::SINK_OFFLOAD.0.into(), "SINK_OFFLOAD", "SinkOffload"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ProviderCapability, u8); /// Opcode for the GetProviderInfo request pub const GET_PROVIDER_INFO_REQUEST: u8 = 33; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetProviderInfoRequest { pub provider: Provider, pub config_timestamp: xproto::Timestamp, } impl GetProviderInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PROVIDER_INFO_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PROVIDER_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let _ = remaining; Ok(GetProviderInfoRequest { provider, config_timestamp, }) } } impl Request for GetProviderInfoRequest { type Reply = GetProviderInfoReply; } pub fn get_provider_info(conn: &Conn, provider: Provider, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetProviderInfoRequest { provider, config_timestamp, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetProviderInfoReply { pub status: u8, pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub capabilities: u32, pub crtcs: Vec, pub outputs: Vec, pub associated_providers: Vec, pub associated_capability: Vec, pub name: Vec, } impl TryParse for GetProviderInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (capabilities, remaining) = u32::try_parse(remaining)?; let (num_crtcs, remaining) = u16::try_parse(remaining)?; let (num_outputs, remaining) = u16::try_parse(remaining)?; let (num_associated_providers, remaining) = u16::try_parse(remaining)?; let (name_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (crtcs, remaining) = crate::x11_utils::parse_list::(remaining, num_crtcs.try_to_usize()?)?; let (outputs, remaining) = crate::x11_utils::parse_list::(remaining, num_outputs.try_to_usize()?)?; let (associated_providers, remaining) = crate::x11_utils::parse_list::(remaining, num_associated_providers.try_to_usize()?)?; let (associated_capability, remaining) = crate::x11_utils::parse_list::(remaining, num_associated_providers.try_to_usize()?)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetProviderInfoReply { status, sequence, length, timestamp, capabilities, crtcs, outputs, associated_providers, associated_capability, name }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetProviderInfoReply { /// Get the value of the `num_crtcs` field. /// /// The `num_crtcs` field is used as the length field of the `crtcs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_crtcs(&self) -> u16 { self.crtcs.len() .try_into().unwrap() } /// Get the value of the `num_outputs` field. /// /// The `num_outputs` field is used as the length field of the `outputs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_outputs(&self) -> u16 { self.outputs.len() .try_into().unwrap() } /// Get the value of the `num_associated_providers` field. /// /// The `num_associated_providers` field is used as the length field of the `associated_providers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_associated_providers(&self) -> u16 { self.associated_providers.len() .try_into().unwrap() } /// Get the value of the `name_len` field. /// /// The `name_len` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u16 { self.name.len() .try_into().unwrap() } } /// Opcode for the SetProviderOffloadSink request pub const SET_PROVIDER_OFFLOAD_SINK_REQUEST: u8 = 34; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetProviderOffloadSinkRequest { pub provider: Provider, pub sink_provider: Provider, pub config_timestamp: xproto::Timestamp, } impl SetProviderOffloadSinkRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let sink_provider_bytes = self.sink_provider.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PROVIDER_OFFLOAD_SINK_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], sink_provider_bytes[0], sink_provider_bytes[1], sink_provider_bytes[2], sink_provider_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_PROVIDER_OFFLOAD_SINK_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (sink_provider, remaining) = Provider::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let _ = remaining; Ok(SetProviderOffloadSinkRequest { provider, sink_provider, config_timestamp, }) } } impl Request for SetProviderOffloadSinkRequest { type Reply = (); } pub fn set_provider_offload_sink(conn: &Conn, provider: Provider, sink_provider: Provider, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetProviderOffloadSinkRequest { provider, sink_provider, config_timestamp, }; request0.send(conn) } /// Opcode for the SetProviderOutputSource request pub const SET_PROVIDER_OUTPUT_SOURCE_REQUEST: u8 = 35; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetProviderOutputSourceRequest { pub provider: Provider, pub source_provider: Provider, pub config_timestamp: xproto::Timestamp, } impl SetProviderOutputSourceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let source_provider_bytes = self.source_provider.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PROVIDER_OUTPUT_SOURCE_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], source_provider_bytes[0], source_provider_bytes[1], source_provider_bytes[2], source_provider_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_PROVIDER_OUTPUT_SOURCE_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (source_provider, remaining) = Provider::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let _ = remaining; Ok(SetProviderOutputSourceRequest { provider, source_provider, config_timestamp, }) } } impl Request for SetProviderOutputSourceRequest { type Reply = (); } pub fn set_provider_output_source(conn: &Conn, provider: Provider, source_provider: Provider, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetProviderOutputSourceRequest { provider, source_provider, config_timestamp, }; request0.send(conn) } /// Opcode for the ListProviderProperties request pub const LIST_PROVIDER_PROPERTIES_REQUEST: u8 = 36; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListProviderPropertiesRequest { pub provider: Provider, } impl ListProviderPropertiesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_PROVIDER_PROPERTIES_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_PROVIDER_PROPERTIES_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let _ = remaining; Ok(ListProviderPropertiesRequest { provider, }) } } impl Request for ListProviderPropertiesRequest { type Reply = ListProviderPropertiesReply; } pub fn list_provider_properties(conn: &Conn, provider: Provider) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListProviderPropertiesRequest { provider, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListProviderPropertiesReply { pub sequence: u16, pub length: u32, pub atoms: Vec, } impl TryParse for ListProviderPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_atoms, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (atoms, remaining) = crate::x11_utils::parse_list::(remaining, num_atoms.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListProviderPropertiesReply { sequence, length, atoms }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListProviderPropertiesReply { /// Get the value of the `num_atoms` field. /// /// The `num_atoms` field is used as the length field of the `atoms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_atoms(&self) -> u16 { self.atoms.len() .try_into().unwrap() } } /// Opcode for the QueryProviderProperty request pub const QUERY_PROVIDER_PROPERTY_REQUEST: u8 = 37; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryProviderPropertyRequest { pub provider: Provider, pub property: xproto::Atom, } impl QueryProviderPropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let property_bytes = self.property.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_PROVIDER_PROPERTY_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_PROVIDER_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(QueryProviderPropertyRequest { provider, property, }) } } impl Request for QueryProviderPropertyRequest { type Reply = QueryProviderPropertyReply; } pub fn query_provider_property(conn: &Conn, provider: Provider, property: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryProviderPropertyRequest { provider, property, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryProviderPropertyReply { pub sequence: u16, pub pending: bool, pub range: bool, pub immutable: bool, pub valid_values: Vec, } impl TryParse for QueryProviderPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (pending, remaining) = bool::try_parse(remaining)?; let (range, remaining) = bool::try_parse(remaining)?; let (immutable, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(21..).ok_or(ParseError::InsufficientData)?; let (valid_values, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryProviderPropertyReply { sequence, pending, range, immutable, valid_values }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryProviderPropertyReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `valid_values` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.valid_values.len() .try_into().unwrap() } } /// Opcode for the ConfigureProviderProperty request pub const CONFIGURE_PROVIDER_PROPERTY_REQUEST: u8 = 38; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConfigureProviderPropertyRequest<'input> { pub provider: Provider, pub property: xproto::Atom, pub pending: bool, pub range: bool, pub values: Cow<'input, [i32]>, } impl<'input> ConfigureProviderPropertyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let property_bytes = self.property.serialize(); let pending_bytes = self.pending.serialize(); let range_bytes = self.range.serialize(); let mut request0 = vec![ extension_information.major_opcode, CONFIGURE_PROVIDER_PROPERTY_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], pending_bytes[0], range_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let values_bytes = self.values.serialize(); let length_so_far = length_so_far + values_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), values_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CONFIGURE_PROVIDER_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (pending, remaining) = bool::try_parse(remaining)?; let (range, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut values = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = i32::try_parse(remaining)?; remaining = new_remaining; values.push(v); } let _ = remaining; Ok(ConfigureProviderPropertyRequest { provider, property, pending, range, values: Cow::Owned(values), }) } /// Clone all borrowed data in this ConfigureProviderPropertyRequest. pub fn into_owned(self) -> ConfigureProviderPropertyRequest<'static> { ConfigureProviderPropertyRequest { provider: self.provider, property: self.property, pending: self.pending, range: self.range, values: Cow::Owned(self.values.into_owned()), } } } impl<'input> Request for ConfigureProviderPropertyRequest<'input> { type Reply = (); } pub fn configure_provider_property<'c, 'input, Conn>(conn: &'c Conn, provider: Provider, property: xproto::Atom, pending: bool, range: bool, values: &'input [i32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ConfigureProviderPropertyRequest { provider, property, pending, range, values: Cow::Borrowed(values), }; request0.send(conn) } /// Opcode for the ChangeProviderProperty request pub const CHANGE_PROVIDER_PROPERTY_REQUEST: u8 = 39; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeProviderPropertyRequest<'input> { pub provider: Provider, pub property: xproto::Atom, pub type_: xproto::Atom, pub format: u8, pub mode: u8, pub num_items: u32, pub data: Cow<'input, [u8]>, } impl<'input> ChangeProviderPropertyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let format_bytes = self.format.serialize(); let mode_bytes = self.mode.serialize(); let num_items_bytes = self.num_items.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_PROVIDER_PROPERTY_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], format_bytes[0], mode_bytes[0], 0, 0, num_items_bytes[0], num_items_bytes[1], num_items_bytes[2], num_items_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(self.data.len(), usize::try_from(self.num_items.checked_mul(u32::from(self.format).checked_div(8u32).unwrap()).unwrap()).unwrap(), "`data` has an incorrect length"); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_PROVIDER_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (num_items, remaining) = u32::try_parse(remaining)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, num_items.checked_mul(u32::from(format).checked_div(8u32).ok_or(ParseError::InvalidExpression)?).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(ChangeProviderPropertyRequest { provider, property, type_, format, mode, num_items, data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this ChangeProviderPropertyRequest. pub fn into_owned(self) -> ChangeProviderPropertyRequest<'static> { ChangeProviderPropertyRequest { provider: self.provider, property: self.property, type_: self.type_, format: self.format, mode: self.mode, num_items: self.num_items, data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for ChangeProviderPropertyRequest<'input> { type Reply = (); } pub fn change_provider_property<'c, 'input, Conn>(conn: &'c Conn, provider: Provider, property: xproto::Atom, type_: xproto::Atom, format: u8, mode: u8, num_items: u32, data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeProviderPropertyRequest { provider, property, type_, format, mode, num_items, data: Cow::Borrowed(data), }; request0.send(conn) } /// Opcode for the DeleteProviderProperty request pub const DELETE_PROVIDER_PROPERTY_REQUEST: u8 = 40; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeleteProviderPropertyRequest { pub provider: Provider, pub property: xproto::Atom, } impl DeleteProviderPropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let property_bytes = self.property.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_PROVIDER_PROPERTY_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_PROVIDER_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(DeleteProviderPropertyRequest { provider, property, }) } } impl Request for DeleteProviderPropertyRequest { type Reply = (); } pub fn delete_provider_property(conn: &Conn, provider: Provider, property: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteProviderPropertyRequest { provider, property, }; request0.send(conn) } /// Opcode for the GetProviderProperty request pub const GET_PROVIDER_PROPERTY_REQUEST: u8 = 41; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetProviderPropertyRequest { pub provider: Provider, pub property: xproto::Atom, pub type_: xproto::Atom, pub long_offset: u32, pub long_length: u32, pub delete: bool, pub pending: bool, } impl GetProviderPropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let provider_bytes = self.provider.serialize(); let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let long_offset_bytes = self.long_offset.serialize(); let long_length_bytes = self.long_length.serialize(); let delete_bytes = self.delete.serialize(); let pending_bytes = self.pending.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PROVIDER_PROPERTY_REQUEST, 0, 0, provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], long_offset_bytes[0], long_offset_bytes[1], long_offset_bytes[2], long_offset_bytes[3], long_length_bytes[0], long_length_bytes[1], long_length_bytes[2], long_length_bytes[3], delete_bytes[0], pending_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PROVIDER_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (provider, remaining) = Provider::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (long_offset, remaining) = u32::try_parse(remaining)?; let (long_length, remaining) = u32::try_parse(remaining)?; let (delete, remaining) = bool::try_parse(remaining)?; let (pending, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetProviderPropertyRequest { provider, property, type_, long_offset, long_length, delete, pending, }) } } impl Request for GetProviderPropertyRequest { type Reply = GetProviderPropertyReply; } pub fn get_provider_property(conn: &Conn, provider: Provider, property: xproto::Atom, type_: xproto::Atom, long_offset: u32, long_length: u32, delete: bool, pending: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetProviderPropertyRequest { provider, property, type_, long_offset, long_length, delete, pending, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetProviderPropertyReply { pub format: u8, pub sequence: u16, pub length: u32, pub type_: xproto::Atom, pub bytes_after: u32, pub num_items: u32, pub data: Vec, } impl TryParse for GetProviderPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (bytes_after, remaining) = u32::try_parse(remaining)?; let (num_items, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, num_items.checked_mul(u32::from(format).checked_div(8u32).ok_or(ParseError::InvalidExpression)?).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetProviderPropertyReply { format, sequence, length, type_, bytes_after, num_items, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the ScreenChangeNotify event pub const SCREEN_CHANGE_NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ScreenChangeNotifyEvent { pub response_type: u8, pub rotation: u8, pub sequence: u16, pub timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub root: xproto::Window, pub request_window: xproto::Window, pub size_id: u16, pub subpixel_order: render::SubPixel, pub width: u16, pub height: u16, pub mwidth: u16, pub mheight: u16, } impl TryParse for ScreenChangeNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (rotation, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (request_window, remaining) = xproto::Window::try_parse(remaining)?; let (size_id, remaining) = u16::try_parse(remaining)?; let (subpixel_order, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (mwidth, remaining) = u16::try_parse(remaining)?; let (mheight, remaining) = u16::try_parse(remaining)?; let subpixel_order = subpixel_order.into(); let result = ScreenChangeNotifyEvent { response_type, rotation, sequence, timestamp, config_timestamp, root, request_window, size_id, subpixel_order, width, height, mwidth, mheight }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ScreenChangeNotifyEvent> for [u8; 32] { fn from(input: &ScreenChangeNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let rotation_bytes = input.rotation.serialize(); let sequence_bytes = input.sequence.serialize(); let timestamp_bytes = input.timestamp.serialize(); let config_timestamp_bytes = input.config_timestamp.serialize(); let root_bytes = input.root.serialize(); let request_window_bytes = input.request_window.serialize(); let size_id_bytes = input.size_id.serialize(); let subpixel_order_bytes = (u32::from(input.subpixel_order) as u16).serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); let mwidth_bytes = input.mwidth.serialize(); let mheight_bytes = input.mheight.serialize(); [ response_type_bytes[0], rotation_bytes[0], sequence_bytes[0], sequence_bytes[1], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], request_window_bytes[0], request_window_bytes[1], request_window_bytes[2], request_window_bytes[3], size_id_bytes[0], size_id_bytes[1], subpixel_order_bytes[0], subpixel_order_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], mwidth_bytes[0], mwidth_bytes[1], mheight_bytes[0], mheight_bytes[1], ] } } impl From for [u8; 32] { fn from(input: ScreenChangeNotifyEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Notify(u8); impl Notify { pub const CRTC_CHANGE: Self = Self(0); pub const OUTPUT_CHANGE: Self = Self(1); pub const OUTPUT_PROPERTY: Self = Self(2); pub const PROVIDER_CHANGE: Self = Self(3); pub const PROVIDER_PROPERTY: Self = Self(4); pub const RESOURCE_CHANGE: Self = Self(5); pub const LEASE: Self = Self(6); } impl From for u8 { #[inline] fn from(input: Notify) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Notify) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Notify) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Notify) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Notify) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Notify) -> Self { Some(u32::from(input.0)) } } impl From for Notify { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Notify { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CRTC_CHANGE.0.into(), "CRTC_CHANGE", "CrtcChange"), (Self::OUTPUT_CHANGE.0.into(), "OUTPUT_CHANGE", "OutputChange"), (Self::OUTPUT_PROPERTY.0.into(), "OUTPUT_PROPERTY", "OutputProperty"), (Self::PROVIDER_CHANGE.0.into(), "PROVIDER_CHANGE", "ProviderChange"), (Self::PROVIDER_PROPERTY.0.into(), "PROVIDER_PROPERTY", "ProviderProperty"), (Self::RESOURCE_CHANGE.0.into(), "RESOURCE_CHANGE", "ResourceChange"), (Self::LEASE.0.into(), "LEASE", "Lease"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CrtcChange { pub timestamp: xproto::Timestamp, pub window: xproto::Window, pub crtc: Crtc, pub mode: Mode, pub rotation: u16, pub x: i16, pub y: i16, pub width: u16, pub height: u16, } impl TryParse for CrtcChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (crtc, remaining) = Crtc::try_parse(remaining)?; let (mode, remaining) = Mode::try_parse(remaining)?; let (rotation, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let result = CrtcChange { timestamp, window, crtc, mode, rotation, x, y, width, height }; Ok((result, remaining)) } } impl Serialize for CrtcChange { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let timestamp_bytes = self.timestamp.serialize(); let window_bytes = self.window.serialize(); let crtc_bytes = self.crtc.serialize(); let mode_bytes = self.mode.serialize(); let rotation_bytes = self.rotation.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); [ timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], rotation_bytes[0], rotation_bytes[1], 0, 0, x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.timestamp.serialize_into(bytes); self.window.serialize_into(bytes); self.crtc.serialize_into(bytes); self.mode.serialize_into(bytes); self.rotation.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.x.serialize_into(bytes); self.y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OutputChange { pub timestamp: xproto::Timestamp, pub config_timestamp: xproto::Timestamp, pub window: xproto::Window, pub output: Output, pub crtc: Crtc, pub mode: Mode, pub rotation: u16, pub connection: Connection, pub subpixel_order: render::SubPixel, } impl TryParse for OutputChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (output, remaining) = Output::try_parse(remaining)?; let (crtc, remaining) = Crtc::try_parse(remaining)?; let (mode, remaining) = Mode::try_parse(remaining)?; let (rotation, remaining) = u16::try_parse(remaining)?; let (connection, remaining) = u8::try_parse(remaining)?; let (subpixel_order, remaining) = u8::try_parse(remaining)?; let connection = connection.into(); let subpixel_order = subpixel_order.into(); let result = OutputChange { timestamp, config_timestamp, window, output, crtc, mode, rotation, connection, subpixel_order }; Ok((result, remaining)) } } impl Serialize for OutputChange { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let timestamp_bytes = self.timestamp.serialize(); let config_timestamp_bytes = self.config_timestamp.serialize(); let window_bytes = self.window.serialize(); let output_bytes = self.output.serialize(); let crtc_bytes = self.crtc.serialize(); let mode_bytes = self.mode.serialize(); let rotation_bytes = self.rotation.serialize(); let connection_bytes = u8::from(self.connection).serialize(); let subpixel_order_bytes = (u32::from(self.subpixel_order) as u8).serialize(); [ timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], config_timestamp_bytes[0], config_timestamp_bytes[1], config_timestamp_bytes[2], config_timestamp_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], crtc_bytes[0], crtc_bytes[1], crtc_bytes[2], crtc_bytes[3], mode_bytes[0], mode_bytes[1], mode_bytes[2], mode_bytes[3], rotation_bytes[0], rotation_bytes[1], connection_bytes[0], subpixel_order_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.timestamp.serialize_into(bytes); self.config_timestamp.serialize_into(bytes); self.window.serialize_into(bytes); self.output.serialize_into(bytes); self.crtc.serialize_into(bytes); self.mode.serialize_into(bytes); self.rotation.serialize_into(bytes); u8::from(self.connection).serialize_into(bytes); (u32::from(self.subpixel_order) as u8).serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OutputProperty { pub window: xproto::Window, pub output: Output, pub atom: xproto::Atom, pub timestamp: xproto::Timestamp, pub status: xproto::Property, } impl TryParse for OutputProperty { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (window, remaining) = xproto::Window::try_parse(remaining)?; let (output, remaining) = Output::try_parse(remaining)?; let (atom, remaining) = xproto::Atom::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(11..).ok_or(ParseError::InsufficientData)?; let status = status.into(); let result = OutputProperty { window, output, atom, timestamp, status }; Ok((result, remaining)) } } impl Serialize for OutputProperty { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let window_bytes = self.window.serialize(); let output_bytes = self.output.serialize(); let atom_bytes = self.atom.serialize(); let timestamp_bytes = self.timestamp.serialize(); let status_bytes = u8::from(self.status).serialize(); [ window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], output_bytes[0], output_bytes[1], output_bytes[2], output_bytes[3], atom_bytes[0], atom_bytes[1], atom_bytes[2], atom_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], status_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.window.serialize_into(bytes); self.output.serialize_into(bytes); self.atom.serialize_into(bytes); self.timestamp.serialize_into(bytes); u8::from(self.status).serialize_into(bytes); bytes.extend_from_slice(&[0; 11]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ProviderChange { pub timestamp: xproto::Timestamp, pub window: xproto::Window, pub provider: Provider, } impl TryParse for ProviderChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (provider, remaining) = Provider::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let result = ProviderChange { timestamp, window, provider }; Ok((result, remaining)) } } impl Serialize for ProviderChange { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let timestamp_bytes = self.timestamp.serialize(); let window_bytes = self.window.serialize(); let provider_bytes = self.provider.serialize(); [ timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.timestamp.serialize_into(bytes); self.window.serialize_into(bytes); self.provider.serialize_into(bytes); bytes.extend_from_slice(&[0; 16]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ProviderProperty { pub window: xproto::Window, pub provider: Provider, pub atom: xproto::Atom, pub timestamp: xproto::Timestamp, pub state: u8, } impl TryParse for ProviderProperty { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (window, remaining) = xproto::Window::try_parse(remaining)?; let (provider, remaining) = Provider::try_parse(remaining)?; let (atom, remaining) = xproto::Atom::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(11..).ok_or(ParseError::InsufficientData)?; let result = ProviderProperty { window, provider, atom, timestamp, state }; Ok((result, remaining)) } } impl Serialize for ProviderProperty { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let window_bytes = self.window.serialize(); let provider_bytes = self.provider.serialize(); let atom_bytes = self.atom.serialize(); let timestamp_bytes = self.timestamp.serialize(); let state_bytes = self.state.serialize(); [ window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], provider_bytes[0], provider_bytes[1], provider_bytes[2], provider_bytes[3], atom_bytes[0], atom_bytes[1], atom_bytes[2], atom_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], state_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.window.serialize_into(bytes); self.provider.serialize_into(bytes); self.atom.serialize_into(bytes); self.timestamp.serialize_into(bytes); self.state.serialize_into(bytes); bytes.extend_from_slice(&[0; 11]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ResourceChange { pub timestamp: xproto::Timestamp, pub window: xproto::Window, } impl TryParse for ResourceChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let result = ResourceChange { timestamp, window }; Ok((result, remaining)) } } impl Serialize for ResourceChange { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let timestamp_bytes = self.timestamp.serialize(); let window_bytes = self.window.serialize(); [ timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.timestamp.serialize_into(bytes); self.window.serialize_into(bytes); bytes.extend_from_slice(&[0; 20]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct MonitorInfo { pub name: xproto::Atom, pub primary: bool, pub automatic: bool, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub width_in_millimeters: u32, pub height_in_millimeters: u32, pub outputs: Vec, } impl TryParse for MonitorInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (primary, remaining) = bool::try_parse(remaining)?; let (automatic, remaining) = bool::try_parse(remaining)?; let (n_output, remaining) = u16::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (width_in_millimeters, remaining) = u32::try_parse(remaining)?; let (height_in_millimeters, remaining) = u32::try_parse(remaining)?; let (outputs, remaining) = crate::x11_utils::parse_list::(remaining, n_output.try_to_usize()?)?; let result = MonitorInfo { name, primary, automatic, x, y, width, height, width_in_millimeters, height_in_millimeters, outputs }; Ok((result, remaining)) } } impl Serialize for MonitorInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.name.serialize_into(bytes); self.primary.serialize_into(bytes); self.automatic.serialize_into(bytes); let n_output = u16::try_from(self.outputs.len()).expect("`outputs` has too many elements"); n_output.serialize_into(bytes); self.x.serialize_into(bytes); self.y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.width_in_millimeters.serialize_into(bytes); self.height_in_millimeters.serialize_into(bytes); self.outputs.serialize_into(bytes); } } impl MonitorInfo { /// Get the value of the `nOutput` field. /// /// The `nOutput` field is used as the length field of the `outputs` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_output(&self) -> u16 { self.outputs.len() .try_into().unwrap() } } /// Opcode for the GetMonitors request pub const GET_MONITORS_REQUEST: u8 = 42; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMonitorsRequest { pub window: xproto::Window, pub get_active: bool, } impl GetMonitorsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let get_active_bytes = self.get_active.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MONITORS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], get_active_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MONITORS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (get_active, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(GetMonitorsRequest { window, get_active, }) } } impl Request for GetMonitorsRequest { type Reply = GetMonitorsReply; } pub fn get_monitors(conn: &Conn, window: xproto::Window, get_active: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMonitorsRequest { window, get_active, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetMonitorsReply { pub sequence: u16, pub length: u32, pub timestamp: xproto::Timestamp, pub n_outputs: u32, pub monitors: Vec, } impl TryParse for GetMonitorsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (n_monitors, remaining) = u32::try_parse(remaining)?; let (n_outputs, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (monitors, remaining) = crate::x11_utils::parse_list::(remaining, n_monitors.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMonitorsReply { sequence, length, timestamp, n_outputs, monitors }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMonitorsReply { /// Get the value of the `nMonitors` field. /// /// The `nMonitors` field is used as the length field of the `monitors` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_monitors(&self) -> u32 { self.monitors.len() .try_into().unwrap() } } /// Opcode for the SetMonitor request pub const SET_MONITOR_REQUEST: u8 = 43; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetMonitorRequest { pub window: xproto::Window, pub monitorinfo: MonitorInfo, } impl SetMonitorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_MONITOR_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let monitorinfo_bytes = self.monitorinfo.serialize(); let length_so_far = length_so_far + monitorinfo_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), monitorinfo_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_MONITOR_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (monitorinfo, remaining) = MonitorInfo::try_parse(remaining)?; let _ = remaining; Ok(SetMonitorRequest { window, monitorinfo, }) } } impl Request for SetMonitorRequest { type Reply = (); } pub fn set_monitor(conn: &Conn, window: xproto::Window, monitorinfo: MonitorInfo) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetMonitorRequest { window, monitorinfo, }; request0.send(conn) } /// Opcode for the DeleteMonitor request pub const DELETE_MONITOR_REQUEST: u8 = 44; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeleteMonitorRequest { pub window: xproto::Window, pub name: xproto::Atom, } impl DeleteMonitorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let name_bytes = self.name.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_MONITOR_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_MONITOR_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (name, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(DeleteMonitorRequest { window, name, }) } } impl Request for DeleteMonitorRequest { type Reply = (); } pub fn delete_monitor(conn: &Conn, window: xproto::Window, name: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteMonitorRequest { window, name, }; request0.send(conn) } /// Opcode for the CreateLease request pub const CREATE_LEASE_REQUEST: u8 = 45; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateLeaseRequest<'input> { pub window: xproto::Window, pub lid: Lease, pub crtcs: Cow<'input, [Crtc]>, pub outputs: Cow<'input, [Output]>, } impl<'input> CreateLeaseRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let lid_bytes = self.lid.serialize(); let num_crtcs = u16::try_from(self.crtcs.len()).expect("`crtcs` has too many elements"); let num_crtcs_bytes = num_crtcs.serialize(); let num_outputs = u16::try_from(self.outputs.len()).expect("`outputs` has too many elements"); let num_outputs_bytes = num_outputs.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_LEASE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], lid_bytes[0], lid_bytes[1], lid_bytes[2], lid_bytes[3], num_crtcs_bytes[0], num_crtcs_bytes[1], num_outputs_bytes[0], num_outputs_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let crtcs_bytes = self.crtcs.serialize(); let length_so_far = length_so_far + crtcs_bytes.len(); let outputs_bytes = self.outputs.serialize(); let length_so_far = length_so_far + outputs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), crtcs_bytes.into(), outputs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply_with_fds(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_LEASE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (lid, remaining) = Lease::try_parse(remaining)?; let (num_crtcs, remaining) = u16::try_parse(remaining)?; let (num_outputs, remaining) = u16::try_parse(remaining)?; let (crtcs, remaining) = crate::x11_utils::parse_list::(remaining, num_crtcs.try_to_usize()?)?; let (outputs, remaining) = crate::x11_utils::parse_list::(remaining, num_outputs.try_to_usize()?)?; let _ = remaining; Ok(CreateLeaseRequest { window, lid, crtcs: Cow::Owned(crtcs), outputs: Cow::Owned(outputs), }) } /// Clone all borrowed data in this CreateLeaseRequest. pub fn into_owned(self) -> CreateLeaseRequest<'static> { CreateLeaseRequest { window: self.window, lid: self.lid, crtcs: Cow::Owned(self.crtcs.into_owned()), outputs: Cow::Owned(self.outputs.into_owned()), } } } impl<'input> Request for CreateLeaseRequest<'input> { type Reply = CreateLeaseReply; } pub fn create_lease<'c, 'input, Conn>(conn: &'c Conn, window: xproto::Window, lid: Lease, crtcs: &'input [Crtc], outputs: &'input [Output]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateLeaseRequest { window, lid, crtcs: Cow::Borrowed(crtcs), outputs: Cow::Borrowed(outputs), }; request0.send(conn) } #[derive(Debug, PartialEq, Eq)] pub struct CreateLeaseReply { pub nfd: u8, pub sequence: u16, pub length: u32, pub master_fd: RawFdContainer, } impl TryParseFd for CreateLeaseReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let master_fd = fds.remove(0); let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateLeaseReply { nfd, sequence, length, master_fd }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the FreeLease request pub const FREE_LEASE_REQUEST: u8 = 46; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FreeLeaseRequest { pub lid: Lease, pub terminate: u8, } impl FreeLeaseRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let lid_bytes = self.lid.serialize(); let terminate_bytes = self.terminate.serialize(); let mut request0 = vec![ extension_information.major_opcode, FREE_LEASE_REQUEST, 0, 0, lid_bytes[0], lid_bytes[1], lid_bytes[2], lid_bytes[3], terminate_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FREE_LEASE_REQUEST { return Err(ParseError::InvalidValue); } let (lid, remaining) = Lease::try_parse(value)?; let (terminate, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(FreeLeaseRequest { lid, terminate, }) } } impl Request for FreeLeaseRequest { type Reply = (); } pub fn free_lease(conn: &Conn, lid: Lease, terminate: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FreeLeaseRequest { lid, terminate, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct LeaseNotify { pub timestamp: xproto::Timestamp, pub window: xproto::Window, pub lease: Lease, pub created: u8, } impl TryParse for LeaseNotify { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (lease, remaining) = Lease::try_parse(remaining)?; let (created, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(15..).ok_or(ParseError::InsufficientData)?; let result = LeaseNotify { timestamp, window, lease, created }; Ok((result, remaining)) } } impl Serialize for LeaseNotify { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let timestamp_bytes = self.timestamp.serialize(); let window_bytes = self.window.serialize(); let lease_bytes = self.lease.serialize(); let created_bytes = self.created.serialize(); [ timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], lease_bytes[0], lease_bytes[1], lease_bytes[2], lease_bytes[3], created_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.timestamp.serialize_into(bytes); self.window.serialize_into(bytes); self.lease.serialize_into(bytes); self.created.serialize_into(bytes); bytes.extend_from_slice(&[0; 15]); } } #[derive(Debug, Copy, Clone)] pub struct NotifyData([u8; 28]); impl NotifyData { pub fn as_cc(&self) -> CrtcChange { fn do_the_parse(remaining: &[u8]) -> Result { let (cc, remaining) = CrtcChange::try_parse(remaining)?; let _ = remaining; Ok(cc) } do_the_parse(&self.0).unwrap() } pub fn as_oc(&self) -> OutputChange { fn do_the_parse(remaining: &[u8]) -> Result { let (oc, remaining) = OutputChange::try_parse(remaining)?; let _ = remaining; Ok(oc) } do_the_parse(&self.0).unwrap() } pub fn as_op(&self) -> OutputProperty { fn do_the_parse(remaining: &[u8]) -> Result { let (op, remaining) = OutputProperty::try_parse(remaining)?; let _ = remaining; Ok(op) } do_the_parse(&self.0).unwrap() } pub fn as_pc(&self) -> ProviderChange { fn do_the_parse(remaining: &[u8]) -> Result { let (pc, remaining) = ProviderChange::try_parse(remaining)?; let _ = remaining; Ok(pc) } do_the_parse(&self.0).unwrap() } pub fn as_pp(&self) -> ProviderProperty { fn do_the_parse(remaining: &[u8]) -> Result { let (pp, remaining) = ProviderProperty::try_parse(remaining)?; let _ = remaining; Ok(pp) } do_the_parse(&self.0).unwrap() } pub fn as_rc(&self) -> ResourceChange { fn do_the_parse(remaining: &[u8]) -> Result { let (rc, remaining) = ResourceChange::try_parse(remaining)?; let _ = remaining; Ok(rc) } do_the_parse(&self.0).unwrap() } pub fn as_lc(&self) -> LeaseNotify { fn do_the_parse(remaining: &[u8]) -> Result { let (lc, remaining) = LeaseNotify::try_parse(remaining)?; let _ = remaining; Ok(lc) } do_the_parse(&self.0).unwrap() } } impl Serialize for NotifyData { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { self.0 } fn serialize_into(&self, bytes: &mut Vec) { bytes.extend_from_slice(&self.0); } } impl TryParse for NotifyData { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let inner: [u8; 28] = value.get(..28) .ok_or(ParseError::InsufficientData)? .try_into() .unwrap(); let result = NotifyData(inner); Ok((result, &value[28..])) } } impl From for NotifyData { fn from(cc: CrtcChange) -> Self { let cc_bytes = cc.serialize(); Self(cc_bytes) } } impl From for NotifyData { fn from(oc: OutputChange) -> Self { let oc_bytes = oc.serialize(); Self(oc_bytes) } } impl From for NotifyData { fn from(op: OutputProperty) -> Self { let op_bytes = op.serialize(); Self(op_bytes) } } impl From for NotifyData { fn from(pc: ProviderChange) -> Self { let pc_bytes = pc.serialize(); Self(pc_bytes) } } impl From for NotifyData { fn from(pp: ProviderProperty) -> Self { let pp_bytes = pp.serialize(); Self(pp_bytes) } } impl From for NotifyData { fn from(rc: ResourceChange) -> Self { let rc_bytes = rc.serialize(); Self(rc_bytes) } } impl From for NotifyData { fn from(lc: LeaseNotify) -> Self { let lc_bytes = lc.serialize(); Self(lc_bytes) } } /// Opcode for the Notify event pub const NOTIFY_EVENT: u8 = 1; #[derive(Debug, Clone, Copy)] pub struct NotifyEvent { pub response_type: u8, pub sub_code: Notify, pub sequence: u16, pub u: NotifyData, } impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (sub_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (u, remaining) = NotifyData::try_parse(remaining)?; let sub_code = sub_code.into(); let result = NotifyEvent { response_type, sub_code, sequence, u }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NotifyEvent> for [u8; 32] { fn from(input: &NotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sub_code_bytes = u8::from(input.sub_code).serialize(); let sequence_bytes = input.sequence.serialize(); let u_bytes = input.u.serialize(); [ response_type_bytes[0], sub_code_bytes[0], sequence_bytes[0], sequence_bytes[1], u_bytes[0], u_bytes[1], u_bytes[2], u_bytes[3], u_bytes[4], u_bytes[5], u_bytes[6], u_bytes[7], u_bytes[8], u_bytes[9], u_bytes[10], u_bytes[11], u_bytes[12], u_bytes[13], u_bytes[14], u_bytes[15], u_bytes[16], u_bytes[17], u_bytes[18], u_bytes[19], u_bytes[20], u_bytes[21], u_bytes[22], u_bytes[23], u_bytes[24], u_bytes[25], u_bytes[26], u_bytes[27], ] } } impl From for [u8; 32] { fn from(input: NotifyEvent) -> Self { Self::from(&input) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn randr_query_version(&self, major_version: u32, minor_version: u32) -> Result, ConnectionError> { query_version(self, major_version, minor_version) } fn randr_set_screen_config(&self, window: xproto::Window, timestamp: xproto::Timestamp, config_timestamp: xproto::Timestamp, size_id: u16, rotation: A, rate: u16) -> Result, ConnectionError> where A: Into, { set_screen_config(self, window, timestamp, config_timestamp, size_id, rotation, rate) } fn randr_select_input(&self, window: xproto::Window, enable: A) -> Result, ConnectionError> where A: Into, { select_input(self, window, enable) } fn randr_get_screen_info(&self, window: xproto::Window) -> Result, ConnectionError> { get_screen_info(self, window) } fn randr_get_screen_size_range(&self, window: xproto::Window) -> Result, ConnectionError> { get_screen_size_range(self, window) } fn randr_set_screen_size(&self, window: xproto::Window, width: u16, height: u16, mm_width: u32, mm_height: u32) -> Result, ConnectionError> { set_screen_size(self, window, width, height, mm_width, mm_height) } fn randr_get_screen_resources(&self, window: xproto::Window) -> Result, ConnectionError> { get_screen_resources(self, window) } fn randr_get_output_info(&self, output: Output, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> { get_output_info(self, output, config_timestamp) } fn randr_list_output_properties(&self, output: Output) -> Result, ConnectionError> { list_output_properties(self, output) } fn randr_query_output_property(&self, output: Output, property: xproto::Atom) -> Result, ConnectionError> { query_output_property(self, output, property) } fn randr_configure_output_property<'c, 'input>(&'c self, output: Output, property: xproto::Atom, pending: bool, range: bool, values: &'input [i32]) -> Result, ConnectionError> { configure_output_property(self, output, property, pending, range, values) } fn randr_change_output_property<'c, 'input>(&'c self, output: Output, property: xproto::Atom, type_: xproto::Atom, format: u8, mode: xproto::PropMode, num_units: u32, data: &'input [u8]) -> Result, ConnectionError> { change_output_property(self, output, property, type_, format, mode, num_units, data) } fn randr_delete_output_property(&self, output: Output, property: xproto::Atom) -> Result, ConnectionError> { delete_output_property(self, output, property) } fn randr_get_output_property(&self, output: Output, property: xproto::Atom, type_: A, long_offset: u32, long_length: u32, delete: bool, pending: bool) -> Result, ConnectionError> where A: Into, { get_output_property(self, output, property, type_, long_offset, long_length, delete, pending) } fn randr_create_mode<'c, 'input>(&'c self, window: xproto::Window, mode_info: ModeInfo, name: &'input [u8]) -> Result, ConnectionError> { create_mode(self, window, mode_info, name) } fn randr_destroy_mode(&self, mode: Mode) -> Result, ConnectionError> { destroy_mode(self, mode) } fn randr_add_output_mode(&self, output: Output, mode: Mode) -> Result, ConnectionError> { add_output_mode(self, output, mode) } fn randr_delete_output_mode(&self, output: Output, mode: Mode) -> Result, ConnectionError> { delete_output_mode(self, output, mode) } fn randr_get_crtc_info(&self, crtc: Crtc, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> { get_crtc_info(self, crtc, config_timestamp) } fn randr_set_crtc_config<'c, 'input, A>(&'c self, crtc: Crtc, timestamp: xproto::Timestamp, config_timestamp: xproto::Timestamp, x: i16, y: i16, mode: Mode, rotation: A, outputs: &'input [Output]) -> Result, ConnectionError> where A: Into, { set_crtc_config(self, crtc, timestamp, config_timestamp, x, y, mode, rotation, outputs) } fn randr_get_crtc_gamma_size(&self, crtc: Crtc) -> Result, ConnectionError> { get_crtc_gamma_size(self, crtc) } fn randr_get_crtc_gamma(&self, crtc: Crtc) -> Result, ConnectionError> { get_crtc_gamma(self, crtc) } fn randr_set_crtc_gamma<'c, 'input>(&'c self, crtc: Crtc, red: &'input [u16], green: &'input [u16], blue: &'input [u16]) -> Result, ConnectionError> { set_crtc_gamma(self, crtc, red, green, blue) } fn randr_get_screen_resources_current(&self, window: xproto::Window) -> Result, ConnectionError> { get_screen_resources_current(self, window) } fn randr_set_crtc_transform<'c, 'input>(&'c self, crtc: Crtc, transform: render::Transform, filter_name: &'input [u8], filter_params: &'input [render::Fixed]) -> Result, ConnectionError> { set_crtc_transform(self, crtc, transform, filter_name, filter_params) } fn randr_get_crtc_transform(&self, crtc: Crtc) -> Result, ConnectionError> { get_crtc_transform(self, crtc) } fn randr_get_panning(&self, crtc: Crtc) -> Result, ConnectionError> { get_panning(self, crtc) } fn randr_set_panning(&self, crtc: Crtc, timestamp: xproto::Timestamp, left: u16, top: u16, width: u16, height: u16, track_left: u16, track_top: u16, track_width: u16, track_height: u16, border_left: i16, border_top: i16, border_right: i16, border_bottom: i16) -> Result, ConnectionError> { set_panning(self, crtc, timestamp, left, top, width, height, track_left, track_top, track_width, track_height, border_left, border_top, border_right, border_bottom) } fn randr_set_output_primary(&self, window: xproto::Window, output: Output) -> Result, ConnectionError> { set_output_primary(self, window, output) } fn randr_get_output_primary(&self, window: xproto::Window) -> Result, ConnectionError> { get_output_primary(self, window) } fn randr_get_providers(&self, window: xproto::Window) -> Result, ConnectionError> { get_providers(self, window) } fn randr_get_provider_info(&self, provider: Provider, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> { get_provider_info(self, provider, config_timestamp) } fn randr_set_provider_offload_sink(&self, provider: Provider, sink_provider: Provider, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> { set_provider_offload_sink(self, provider, sink_provider, config_timestamp) } fn randr_set_provider_output_source(&self, provider: Provider, source_provider: Provider, config_timestamp: xproto::Timestamp) -> Result, ConnectionError> { set_provider_output_source(self, provider, source_provider, config_timestamp) } fn randr_list_provider_properties(&self, provider: Provider) -> Result, ConnectionError> { list_provider_properties(self, provider) } fn randr_query_provider_property(&self, provider: Provider, property: xproto::Atom) -> Result, ConnectionError> { query_provider_property(self, provider, property) } fn randr_configure_provider_property<'c, 'input>(&'c self, provider: Provider, property: xproto::Atom, pending: bool, range: bool, values: &'input [i32]) -> Result, ConnectionError> { configure_provider_property(self, provider, property, pending, range, values) } fn randr_change_provider_property<'c, 'input>(&'c self, provider: Provider, property: xproto::Atom, type_: xproto::Atom, format: u8, mode: u8, num_items: u32, data: &'input [u8]) -> Result, ConnectionError> { change_provider_property(self, provider, property, type_, format, mode, num_items, data) } fn randr_delete_provider_property(&self, provider: Provider, property: xproto::Atom) -> Result, ConnectionError> { delete_provider_property(self, provider, property) } fn randr_get_provider_property(&self, provider: Provider, property: xproto::Atom, type_: xproto::Atom, long_offset: u32, long_length: u32, delete: bool, pending: bool) -> Result, ConnectionError> { get_provider_property(self, provider, property, type_, long_offset, long_length, delete, pending) } fn randr_get_monitors(&self, window: xproto::Window, get_active: bool) -> Result, ConnectionError> { get_monitors(self, window, get_active) } fn randr_set_monitor(&self, window: xproto::Window, monitorinfo: MonitorInfo) -> Result, ConnectionError> { set_monitor(self, window, monitorinfo) } fn randr_delete_monitor(&self, window: xproto::Window, name: xproto::Atom) -> Result, ConnectionError> { delete_monitor(self, window, name) } fn randr_create_lease<'c, 'input>(&'c self, window: xproto::Window, lid: Lease, crtcs: &'input [Crtc], outputs: &'input [Output]) -> Result, ConnectionError> { create_lease(self, window, lid, crtcs, outputs) } fn randr_free_lease(&self, lid: Lease, terminate: u8) -> Result, ConnectionError> { free_lease(self, lid, terminate) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/record.rs010064400017500001750000001311151402220031600151020ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Record` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::cookie::RecordEnableContextCookie; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "RECORD"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 13); pub type Context = u32; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Range8 { pub first: u8, pub last: u8, } impl TryParse for Range8 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (first, remaining) = u8::try_parse(remaining)?; let (last, remaining) = u8::try_parse(remaining)?; let result = Range8 { first, last }; Ok((result, remaining)) } } impl Serialize for Range8 { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let first_bytes = self.first.serialize(); let last_bytes = self.last.serialize(); [ first_bytes[0], last_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.first.serialize_into(bytes); self.last.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Range16 { pub first: u16, pub last: u16, } impl TryParse for Range16 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (first, remaining) = u16::try_parse(remaining)?; let (last, remaining) = u16::try_parse(remaining)?; let result = Range16 { first, last }; Ok((result, remaining)) } } impl Serialize for Range16 { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let first_bytes = self.first.serialize(); let last_bytes = self.last.serialize(); [ first_bytes[0], first_bytes[1], last_bytes[0], last_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.first.serialize_into(bytes); self.last.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ExtRange { pub major: Range8, pub minor: Range16, } impl TryParse for ExtRange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (major, remaining) = Range8::try_parse(remaining)?; let (minor, remaining) = Range16::try_parse(remaining)?; let result = ExtRange { major, minor }; Ok((result, remaining)) } } impl Serialize for ExtRange { type Bytes = [u8; 6]; fn serialize(&self) -> [u8; 6] { let major_bytes = self.major.serialize(); let minor_bytes = self.minor.serialize(); [ major_bytes[0], major_bytes[1], minor_bytes[0], minor_bytes[1], minor_bytes[2], minor_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(6); self.major.serialize_into(bytes); self.minor.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Range { pub core_requests: Range8, pub core_replies: Range8, pub ext_requests: ExtRange, pub ext_replies: ExtRange, pub delivered_events: Range8, pub device_events: Range8, pub errors: Range8, pub client_started: bool, pub client_died: bool, } impl TryParse for Range { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (core_requests, remaining) = Range8::try_parse(remaining)?; let (core_replies, remaining) = Range8::try_parse(remaining)?; let (ext_requests, remaining) = ExtRange::try_parse(remaining)?; let (ext_replies, remaining) = ExtRange::try_parse(remaining)?; let (delivered_events, remaining) = Range8::try_parse(remaining)?; let (device_events, remaining) = Range8::try_parse(remaining)?; let (errors, remaining) = Range8::try_parse(remaining)?; let (client_started, remaining) = bool::try_parse(remaining)?; let (client_died, remaining) = bool::try_parse(remaining)?; let result = Range { core_requests, core_replies, ext_requests, ext_replies, delivered_events, device_events, errors, client_started, client_died }; Ok((result, remaining)) } } impl Serialize for Range { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let core_requests_bytes = self.core_requests.serialize(); let core_replies_bytes = self.core_replies.serialize(); let ext_requests_bytes = self.ext_requests.serialize(); let ext_replies_bytes = self.ext_replies.serialize(); let delivered_events_bytes = self.delivered_events.serialize(); let device_events_bytes = self.device_events.serialize(); let errors_bytes = self.errors.serialize(); let client_started_bytes = self.client_started.serialize(); let client_died_bytes = self.client_died.serialize(); [ core_requests_bytes[0], core_requests_bytes[1], core_replies_bytes[0], core_replies_bytes[1], ext_requests_bytes[0], ext_requests_bytes[1], ext_requests_bytes[2], ext_requests_bytes[3], ext_requests_bytes[4], ext_requests_bytes[5], ext_replies_bytes[0], ext_replies_bytes[1], ext_replies_bytes[2], ext_replies_bytes[3], ext_replies_bytes[4], ext_replies_bytes[5], delivered_events_bytes[0], delivered_events_bytes[1], device_events_bytes[0], device_events_bytes[1], errors_bytes[0], errors_bytes[1], client_started_bytes[0], client_died_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.core_requests.serialize_into(bytes); self.core_replies.serialize_into(bytes); self.ext_requests.serialize_into(bytes); self.ext_replies.serialize_into(bytes); self.delivered_events.serialize_into(bytes); self.device_events.serialize_into(bytes); self.errors.serialize_into(bytes); self.client_started.serialize_into(bytes); self.client_died.serialize_into(bytes); } } pub type ElementHeader = u8; #[derive(Clone, Copy, PartialEq, Eq)] pub struct HType(u8); impl HType { pub const FROM_SERVER_TIME: Self = Self(1 << 0); pub const FROM_CLIENT_TIME: Self = Self(1 << 1); pub const FROM_CLIENT_SEQUENCE: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: HType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: HType) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: HType) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: HType) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: HType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: HType) -> Self { Some(u32::from(input.0)) } } impl From for HType { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for HType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::FROM_SERVER_TIME.0.into(), "FROM_SERVER_TIME", "FromServerTime"), (Self::FROM_CLIENT_TIME.0.into(), "FROM_CLIENT_TIME", "FromClientTime"), (Self::FROM_CLIENT_SEQUENCE.0.into(), "FROM_CLIENT_SEQUENCE", "FromClientSequence"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(HType, u8); pub type ClientSpec = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct CS(u8); impl CS { pub const CURRENT_CLIENTS: Self = Self(1); pub const FUTURE_CLIENTS: Self = Self(2); pub const ALL_CLIENTS: Self = Self(3); } impl From for u8 { #[inline] fn from(input: CS) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: CS) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: CS) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: CS) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: CS) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: CS) -> Self { Some(u32::from(input.0)) } } impl From for CS { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for CS { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CURRENT_CLIENTS.0.into(), "CURRENT_CLIENTS", "CurrentClients"), (Self::FUTURE_CLIENTS.0.into(), "FUTURE_CLIENTS", "FutureClients"), (Self::ALL_CLIENTS.0.into(), "ALL_CLIENTS", "AllClients"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ClientInfo { pub client_resource: ClientSpec, pub ranges: Vec, } impl TryParse for ClientInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (client_resource, remaining) = ClientSpec::try_parse(remaining)?; let (num_ranges, remaining) = u32::try_parse(remaining)?; let (ranges, remaining) = crate::x11_utils::parse_list::(remaining, num_ranges.try_to_usize()?)?; let result = ClientInfo { client_resource, ranges }; Ok((result, remaining)) } } impl Serialize for ClientInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.client_resource.serialize_into(bytes); let num_ranges = u32::try_from(self.ranges.len()).expect("`ranges` has too many elements"); num_ranges.serialize_into(bytes); self.ranges.serialize_into(bytes); } } impl ClientInfo { /// Get the value of the `num_ranges` field. /// /// The `num_ranges` field is used as the length field of the `ranges` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_ranges(&self) -> u32 { self.ranges.len() .try_into().unwrap() } } /// Opcode for the BadContext error pub const BAD_CONTEXT_ERROR: u8 = 0; /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub major_version: u16, pub minor_version: u16, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], minor_version_bytes[0], minor_version_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u16::try_parse(value)?; let (minor_version, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { major_version, minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, major_version: u16, minor_version: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { major_version, minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u16, pub minor_version: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u16::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the CreateContext request pub const CREATE_CONTEXT_REQUEST: u8 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateContextRequest<'input> { pub context: Context, pub element_header: ElementHeader, pub client_specs: Cow<'input, [ClientSpec]>, pub ranges: Cow<'input, [Range]>, } impl<'input> CreateContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let element_header_bytes = self.element_header.serialize(); let num_client_specs = u32::try_from(self.client_specs.len()).expect("`client_specs` has too many elements"); let num_client_specs_bytes = num_client_specs.serialize(); let num_ranges = u32::try_from(self.ranges.len()).expect("`ranges` has too many elements"); let num_ranges_bytes = num_ranges.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], element_header_bytes[0], 0, 0, 0, num_client_specs_bytes[0], num_client_specs_bytes[1], num_client_specs_bytes[2], num_client_specs_bytes[3], num_ranges_bytes[0], num_ranges_bytes[1], num_ranges_bytes[2], num_ranges_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let client_specs_bytes = self.client_specs.serialize(); let length_so_far = length_so_far + client_specs_bytes.len(); let ranges_bytes = self.ranges.serialize(); let length_so_far = length_so_far + ranges_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), client_specs_bytes.into(), ranges_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let (element_header, remaining) = ElementHeader::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (num_client_specs, remaining) = u32::try_parse(remaining)?; let (num_ranges, remaining) = u32::try_parse(remaining)?; let (client_specs, remaining) = crate::x11_utils::parse_list::(remaining, num_client_specs.try_to_usize()?)?; let (ranges, remaining) = crate::x11_utils::parse_list::(remaining, num_ranges.try_to_usize()?)?; let _ = remaining; Ok(CreateContextRequest { context, element_header, client_specs: Cow::Owned(client_specs), ranges: Cow::Owned(ranges), }) } /// Clone all borrowed data in this CreateContextRequest. pub fn into_owned(self) -> CreateContextRequest<'static> { CreateContextRequest { context: self.context, element_header: self.element_header, client_specs: Cow::Owned(self.client_specs.into_owned()), ranges: Cow::Owned(self.ranges.into_owned()), } } } impl<'input> Request for CreateContextRequest<'input> { type Reply = (); } pub fn create_context<'c, 'input, Conn>(conn: &'c Conn, context: Context, element_header: ElementHeader, client_specs: &'input [ClientSpec], ranges: &'input [Range]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateContextRequest { context, element_header, client_specs: Cow::Borrowed(client_specs), ranges: Cow::Borrowed(ranges), }; request0.send(conn) } /// Opcode for the RegisterClients request pub const REGISTER_CLIENTS_REQUEST: u8 = 2; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RegisterClientsRequest<'input> { pub context: Context, pub element_header: ElementHeader, pub client_specs: Cow<'input, [ClientSpec]>, pub ranges: Cow<'input, [Range]>, } impl<'input> RegisterClientsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let element_header_bytes = self.element_header.serialize(); let num_client_specs = u32::try_from(self.client_specs.len()).expect("`client_specs` has too many elements"); let num_client_specs_bytes = num_client_specs.serialize(); let num_ranges = u32::try_from(self.ranges.len()).expect("`ranges` has too many elements"); let num_ranges_bytes = num_ranges.serialize(); let mut request0 = vec![ extension_information.major_opcode, REGISTER_CLIENTS_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], element_header_bytes[0], 0, 0, 0, num_client_specs_bytes[0], num_client_specs_bytes[1], num_client_specs_bytes[2], num_client_specs_bytes[3], num_ranges_bytes[0], num_ranges_bytes[1], num_ranges_bytes[2], num_ranges_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let client_specs_bytes = self.client_specs.serialize(); let length_so_far = length_so_far + client_specs_bytes.len(); let ranges_bytes = self.ranges.serialize(); let length_so_far = length_so_far + ranges_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), client_specs_bytes.into(), ranges_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != REGISTER_CLIENTS_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let (element_header, remaining) = ElementHeader::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (num_client_specs, remaining) = u32::try_parse(remaining)?; let (num_ranges, remaining) = u32::try_parse(remaining)?; let (client_specs, remaining) = crate::x11_utils::parse_list::(remaining, num_client_specs.try_to_usize()?)?; let (ranges, remaining) = crate::x11_utils::parse_list::(remaining, num_ranges.try_to_usize()?)?; let _ = remaining; Ok(RegisterClientsRequest { context, element_header, client_specs: Cow::Owned(client_specs), ranges: Cow::Owned(ranges), }) } /// Clone all borrowed data in this RegisterClientsRequest. pub fn into_owned(self) -> RegisterClientsRequest<'static> { RegisterClientsRequest { context: self.context, element_header: self.element_header, client_specs: Cow::Owned(self.client_specs.into_owned()), ranges: Cow::Owned(self.ranges.into_owned()), } } } impl<'input> Request for RegisterClientsRequest<'input> { type Reply = (); } pub fn register_clients<'c, 'input, Conn>(conn: &'c Conn, context: Context, element_header: ElementHeader, client_specs: &'input [ClientSpec], ranges: &'input [Range]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RegisterClientsRequest { context, element_header, client_specs: Cow::Borrowed(client_specs), ranges: Cow::Borrowed(ranges), }; request0.send(conn) } /// Opcode for the UnregisterClients request pub const UNREGISTER_CLIENTS_REQUEST: u8 = 3; #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnregisterClientsRequest<'input> { pub context: Context, pub client_specs: Cow<'input, [ClientSpec]>, } impl<'input> UnregisterClientsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let num_client_specs = u32::try_from(self.client_specs.len()).expect("`client_specs` has too many elements"); let num_client_specs_bytes = num_client_specs.serialize(); let mut request0 = vec![ extension_information.major_opcode, UNREGISTER_CLIENTS_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], num_client_specs_bytes[0], num_client_specs_bytes[1], num_client_specs_bytes[2], num_client_specs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let client_specs_bytes = self.client_specs.serialize(); let length_so_far = length_so_far + client_specs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), client_specs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != UNREGISTER_CLIENTS_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let (num_client_specs, remaining) = u32::try_parse(remaining)?; let (client_specs, remaining) = crate::x11_utils::parse_list::(remaining, num_client_specs.try_to_usize()?)?; let _ = remaining; Ok(UnregisterClientsRequest { context, client_specs: Cow::Owned(client_specs), }) } /// Clone all borrowed data in this UnregisterClientsRequest. pub fn into_owned(self) -> UnregisterClientsRequest<'static> { UnregisterClientsRequest { context: self.context, client_specs: Cow::Owned(self.client_specs.into_owned()), } } } impl<'input> Request for UnregisterClientsRequest<'input> { type Reply = (); } pub fn unregister_clients<'c, 'input, Conn>(conn: &'c Conn, context: Context, client_specs: &'input [ClientSpec]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = UnregisterClientsRequest { context, client_specs: Cow::Borrowed(client_specs), }; request0.send(conn) } /// Opcode for the GetContext request pub const GET_CONTEXT_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetContextRequest { pub context: Context, } impl GetContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(GetContextRequest { context, }) } } impl Request for GetContextRequest { type Reply = GetContextReply; } pub fn get_context(conn: &Conn, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetContextRequest { context, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetContextReply { pub enabled: bool, pub sequence: u16, pub length: u32, pub element_header: ElementHeader, pub intercepted_clients: Vec, } impl TryParse for GetContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (enabled, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (element_header, remaining) = ElementHeader::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (num_intercepted_clients, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (intercepted_clients, remaining) = crate::x11_utils::parse_list::(remaining, num_intercepted_clients.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetContextReply { enabled, sequence, length, element_header, intercepted_clients }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetContextReply { /// Get the value of the `num_intercepted_clients` field. /// /// The `num_intercepted_clients` field is used as the length field of the `intercepted_clients` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_intercepted_clients(&self) -> u32 { self.intercepted_clients.len() .try_into().unwrap() } } /// Opcode for the EnableContext request pub const ENABLE_CONTEXT_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EnableContextRequest { pub context: Context, } impl EnableContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, ENABLE_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); Ok(RecordEnableContextCookie::new(conn.send_request_with_reply(&slices, fds)?)) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != ENABLE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(EnableContextRequest { context, }) } } impl Request for EnableContextRequest { type Reply = EnableContextReply; } pub fn enable_context(conn: &Conn, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = EnableContextRequest { context, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnableContextReply { pub category: u8, pub sequence: u16, pub element_header: ElementHeader, pub client_swapped: bool, pub xid_base: u32, pub server_time: u32, pub rec_sequence_num: u32, pub data: Vec, } impl TryParse for EnableContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (category, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (element_header, remaining) = ElementHeader::try_parse(remaining)?; let (client_swapped, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (xid_base, remaining) = u32::try_parse(remaining)?; let (server_time, remaining) = u32::try_parse(remaining)?; let (rec_sequence_num, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, length.checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = EnableContextReply { category, sequence, element_header, client_swapped, xid_base, server_time, rec_sequence_num, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl EnableContextReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.data.len() .checked_div(4).unwrap() .try_into().unwrap() } } /// Opcode for the DisableContext request pub const DISABLE_CONTEXT_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DisableContextRequest { pub context: Context, } impl DisableContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, DISABLE_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DISABLE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(DisableContextRequest { context, }) } } impl Request for DisableContextRequest { type Reply = (); } pub fn disable_context(conn: &Conn, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DisableContextRequest { context, }; request0.send(conn) } /// Opcode for the FreeContext request pub const FREE_CONTEXT_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FreeContextRequest { pub context: Context, } impl FreeContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, FREE_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FREE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(FreeContextRequest { context, }) } } impl Request for FreeContextRequest { type Reply = (); } pub fn free_context(conn: &Conn, context: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FreeContextRequest { context, }; request0.send(conn) } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn record_query_version(&self, major_version: u16, minor_version: u16) -> Result, ConnectionError> { query_version(self, major_version, minor_version) } fn record_create_context<'c, 'input>(&'c self, context: Context, element_header: ElementHeader, client_specs: &'input [ClientSpec], ranges: &'input [Range]) -> Result, ConnectionError> { create_context(self, context, element_header, client_specs, ranges) } fn record_register_clients<'c, 'input>(&'c self, context: Context, element_header: ElementHeader, client_specs: &'input [ClientSpec], ranges: &'input [Range]) -> Result, ConnectionError> { register_clients(self, context, element_header, client_specs, ranges) } fn record_unregister_clients<'c, 'input>(&'c self, context: Context, client_specs: &'input [ClientSpec]) -> Result, ConnectionError> { unregister_clients(self, context, client_specs) } fn record_get_context(&self, context: Context) -> Result, ConnectionError> { get_context(self, context) } fn record_enable_context(&self, context: Context) -> Result, ConnectionError> { enable_context(self, context) } fn record_disable_context(&self, context: Context) -> Result, ConnectionError> { disable_context(self, context) } fn record_free_context(&self, context: Context) -> Result, ConnectionError> { free_context(self, context) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/render.rs010064400017500001750000006271251402220031600151160ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Render` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "RENDER"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (0, 11); #[derive(Clone, Copy, PartialEq, Eq)] pub struct PictType(u8); impl PictType { pub const INDEXED: Self = Self(0); pub const DIRECT: Self = Self(1); } impl From for u8 { #[inline] fn from(input: PictType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PictType) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: PictType) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: PictType) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: PictType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PictType) -> Self { Some(u32::from(input.0)) } } impl From for PictType { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for PictType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::INDEXED.0.into(), "INDEXED", "Indexed"), (Self::DIRECT.0.into(), "DIRECT", "Direct"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PictureEnum(u8); impl PictureEnum { pub const NONE: Self = Self(0); } impl From for u8 { #[inline] fn from(input: PictureEnum) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PictureEnum) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: PictureEnum) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: PictureEnum) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: PictureEnum) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PictureEnum) -> Self { Some(u32::from(input.0)) } } impl From for PictureEnum { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for PictureEnum { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NONE.0.into(), "NONE", "None"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PictOp(u8); impl PictOp { pub const CLEAR: Self = Self(0); pub const SRC: Self = Self(1); pub const DST: Self = Self(2); pub const OVER: Self = Self(3); pub const OVER_REVERSE: Self = Self(4); pub const IN: Self = Self(5); pub const IN_REVERSE: Self = Self(6); pub const OUT: Self = Self(7); pub const OUT_REVERSE: Self = Self(8); pub const ATOP: Self = Self(9); pub const ATOP_REVERSE: Self = Self(10); pub const XOR: Self = Self(11); pub const ADD: Self = Self(12); pub const SATURATE: Self = Self(13); pub const DISJOINT_CLEAR: Self = Self(16); pub const DISJOINT_SRC: Self = Self(17); pub const DISJOINT_DST: Self = Self(18); pub const DISJOINT_OVER: Self = Self(19); pub const DISJOINT_OVER_REVERSE: Self = Self(20); pub const DISJOINT_IN: Self = Self(21); pub const DISJOINT_IN_REVERSE: Self = Self(22); pub const DISJOINT_OUT: Self = Self(23); pub const DISJOINT_OUT_REVERSE: Self = Self(24); pub const DISJOINT_ATOP: Self = Self(25); pub const DISJOINT_ATOP_REVERSE: Self = Self(26); pub const DISJOINT_XOR: Self = Self(27); pub const CONJOINT_CLEAR: Self = Self(32); pub const CONJOINT_SRC: Self = Self(33); pub const CONJOINT_DST: Self = Self(34); pub const CONJOINT_OVER: Self = Self(35); pub const CONJOINT_OVER_REVERSE: Self = Self(36); pub const CONJOINT_IN: Self = Self(37); pub const CONJOINT_IN_REVERSE: Self = Self(38); pub const CONJOINT_OUT: Self = Self(39); pub const CONJOINT_OUT_REVERSE: Self = Self(40); pub const CONJOINT_ATOP: Self = Self(41); pub const CONJOINT_ATOP_REVERSE: Self = Self(42); pub const CONJOINT_XOR: Self = Self(43); pub const MULTIPLY: Self = Self(48); pub const SCREEN: Self = Self(49); pub const OVERLAY: Self = Self(50); pub const DARKEN: Self = Self(51); pub const LIGHTEN: Self = Self(52); pub const COLOR_DODGE: Self = Self(53); pub const COLOR_BURN: Self = Self(54); pub const HARD_LIGHT: Self = Self(55); pub const SOFT_LIGHT: Self = Self(56); pub const DIFFERENCE: Self = Self(57); pub const EXCLUSION: Self = Self(58); pub const HSL_HUE: Self = Self(59); pub const HSL_SATURATION: Self = Self(60); pub const HSL_COLOR: Self = Self(61); pub const HSL_LUMINOSITY: Self = Self(62); } impl From for u8 { #[inline] fn from(input: PictOp) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PictOp) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: PictOp) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: PictOp) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: PictOp) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PictOp) -> Self { Some(u32::from(input.0)) } } impl From for PictOp { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for PictOp { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CLEAR.0.into(), "CLEAR", "Clear"), (Self::SRC.0.into(), "SRC", "Src"), (Self::DST.0.into(), "DST", "Dst"), (Self::OVER.0.into(), "OVER", "Over"), (Self::OVER_REVERSE.0.into(), "OVER_REVERSE", "OverReverse"), (Self::IN.0.into(), "IN", "In"), (Self::IN_REVERSE.0.into(), "IN_REVERSE", "InReverse"), (Self::OUT.0.into(), "OUT", "Out"), (Self::OUT_REVERSE.0.into(), "OUT_REVERSE", "OutReverse"), (Self::ATOP.0.into(), "ATOP", "Atop"), (Self::ATOP_REVERSE.0.into(), "ATOP_REVERSE", "AtopReverse"), (Self::XOR.0.into(), "XOR", "Xor"), (Self::ADD.0.into(), "ADD", "Add"), (Self::SATURATE.0.into(), "SATURATE", "Saturate"), (Self::DISJOINT_CLEAR.0.into(), "DISJOINT_CLEAR", "DisjointClear"), (Self::DISJOINT_SRC.0.into(), "DISJOINT_SRC", "DisjointSrc"), (Self::DISJOINT_DST.0.into(), "DISJOINT_DST", "DisjointDst"), (Self::DISJOINT_OVER.0.into(), "DISJOINT_OVER", "DisjointOver"), (Self::DISJOINT_OVER_REVERSE.0.into(), "DISJOINT_OVER_REVERSE", "DisjointOverReverse"), (Self::DISJOINT_IN.0.into(), "DISJOINT_IN", "DisjointIn"), (Self::DISJOINT_IN_REVERSE.0.into(), "DISJOINT_IN_REVERSE", "DisjointInReverse"), (Self::DISJOINT_OUT.0.into(), "DISJOINT_OUT", "DisjointOut"), (Self::DISJOINT_OUT_REVERSE.0.into(), "DISJOINT_OUT_REVERSE", "DisjointOutReverse"), (Self::DISJOINT_ATOP.0.into(), "DISJOINT_ATOP", "DisjointAtop"), (Self::DISJOINT_ATOP_REVERSE.0.into(), "DISJOINT_ATOP_REVERSE", "DisjointAtopReverse"), (Self::DISJOINT_XOR.0.into(), "DISJOINT_XOR", "DisjointXor"), (Self::CONJOINT_CLEAR.0.into(), "CONJOINT_CLEAR", "ConjointClear"), (Self::CONJOINT_SRC.0.into(), "CONJOINT_SRC", "ConjointSrc"), (Self::CONJOINT_DST.0.into(), "CONJOINT_DST", "ConjointDst"), (Self::CONJOINT_OVER.0.into(), "CONJOINT_OVER", "ConjointOver"), (Self::CONJOINT_OVER_REVERSE.0.into(), "CONJOINT_OVER_REVERSE", "ConjointOverReverse"), (Self::CONJOINT_IN.0.into(), "CONJOINT_IN", "ConjointIn"), (Self::CONJOINT_IN_REVERSE.0.into(), "CONJOINT_IN_REVERSE", "ConjointInReverse"), (Self::CONJOINT_OUT.0.into(), "CONJOINT_OUT", "ConjointOut"), (Self::CONJOINT_OUT_REVERSE.0.into(), "CONJOINT_OUT_REVERSE", "ConjointOutReverse"), (Self::CONJOINT_ATOP.0.into(), "CONJOINT_ATOP", "ConjointAtop"), (Self::CONJOINT_ATOP_REVERSE.0.into(), "CONJOINT_ATOP_REVERSE", "ConjointAtopReverse"), (Self::CONJOINT_XOR.0.into(), "CONJOINT_XOR", "ConjointXor"), (Self::MULTIPLY.0.into(), "MULTIPLY", "Multiply"), (Self::SCREEN.0.into(), "SCREEN", "Screen"), (Self::OVERLAY.0.into(), "OVERLAY", "Overlay"), (Self::DARKEN.0.into(), "DARKEN", "Darken"), (Self::LIGHTEN.0.into(), "LIGHTEN", "Lighten"), (Self::COLOR_DODGE.0.into(), "COLOR_DODGE", "ColorDodge"), (Self::COLOR_BURN.0.into(), "COLOR_BURN", "ColorBurn"), (Self::HARD_LIGHT.0.into(), "HARD_LIGHT", "HardLight"), (Self::SOFT_LIGHT.0.into(), "SOFT_LIGHT", "SoftLight"), (Self::DIFFERENCE.0.into(), "DIFFERENCE", "Difference"), (Self::EXCLUSION.0.into(), "EXCLUSION", "Exclusion"), (Self::HSL_HUE.0.into(), "HSL_HUE", "HSLHue"), (Self::HSL_SATURATION.0.into(), "HSL_SATURATION", "HSLSaturation"), (Self::HSL_COLOR.0.into(), "HSL_COLOR", "HSLColor"), (Self::HSL_LUMINOSITY.0.into(), "HSL_LUMINOSITY", "HSLLuminosity"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PolyEdge(u32); impl PolyEdge { pub const SHARP: Self = Self(0); pub const SMOOTH: Self = Self(1); } impl From for u32 { #[inline] fn from(input: PolyEdge) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PolyEdge) -> Self { Some(input.0) } } impl From for PolyEdge { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for PolyEdge { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for PolyEdge { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for PolyEdge { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SHARP.0, "SHARP", "Sharp"), (Self::SMOOTH.0, "SMOOTH", "Smooth"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PolyMode(u32); impl PolyMode { pub const PRECISE: Self = Self(0); pub const IMPRECISE: Self = Self(1); } impl From for u32 { #[inline] fn from(input: PolyMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PolyMode) -> Self { Some(input.0) } } impl From for PolyMode { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for PolyMode { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for PolyMode { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for PolyMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::PRECISE.0, "PRECISE", "Precise"), (Self::IMPRECISE.0, "IMPRECISE", "Imprecise"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct CP(u16); impl CP { pub const REPEAT: Self = Self(1 << 0); pub const ALPHA_MAP: Self = Self(1 << 1); pub const ALPHA_X_ORIGIN: Self = Self(1 << 2); pub const ALPHA_Y_ORIGIN: Self = Self(1 << 3); pub const CLIP_X_ORIGIN: Self = Self(1 << 4); pub const CLIP_Y_ORIGIN: Self = Self(1 << 5); pub const CLIP_MASK: Self = Self(1 << 6); pub const GRAPHICS_EXPOSURE: Self = Self(1 << 7); pub const SUBWINDOW_MODE: Self = Self(1 << 8); pub const POLY_EDGE: Self = Self(1 << 9); pub const POLY_MODE: Self = Self(1 << 10); pub const DITHER: Self = Self(1 << 11); pub const COMPONENT_ALPHA: Self = Self(1 << 12); } impl From for u16 { #[inline] fn from(input: CP) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: CP) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: CP) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: CP) -> Self { Some(u32::from(input.0)) } } impl From for CP { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for CP { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for CP { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::REPEAT.0.into(), "REPEAT", "Repeat"), (Self::ALPHA_MAP.0.into(), "ALPHA_MAP", "AlphaMap"), (Self::ALPHA_X_ORIGIN.0.into(), "ALPHA_X_ORIGIN", "AlphaXOrigin"), (Self::ALPHA_Y_ORIGIN.0.into(), "ALPHA_Y_ORIGIN", "AlphaYOrigin"), (Self::CLIP_X_ORIGIN.0.into(), "CLIP_X_ORIGIN", "ClipXOrigin"), (Self::CLIP_Y_ORIGIN.0.into(), "CLIP_Y_ORIGIN", "ClipYOrigin"), (Self::CLIP_MASK.0.into(), "CLIP_MASK", "ClipMask"), (Self::GRAPHICS_EXPOSURE.0.into(), "GRAPHICS_EXPOSURE", "GraphicsExposure"), (Self::SUBWINDOW_MODE.0.into(), "SUBWINDOW_MODE", "SubwindowMode"), (Self::POLY_EDGE.0.into(), "POLY_EDGE", "PolyEdge"), (Self::POLY_MODE.0.into(), "POLY_MODE", "PolyMode"), (Self::DITHER.0.into(), "DITHER", "Dither"), (Self::COMPONENT_ALPHA.0.into(), "COMPONENT_ALPHA", "ComponentAlpha"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(CP, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct SubPixel(u32); impl SubPixel { pub const UNKNOWN: Self = Self(0); pub const HORIZONTAL_RGB: Self = Self(1); pub const HORIZONTAL_BGR: Self = Self(2); pub const VERTICAL_RGB: Self = Self(3); pub const VERTICAL_BGR: Self = Self(4); pub const NONE: Self = Self(5); } impl From for u32 { #[inline] fn from(input: SubPixel) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SubPixel) -> Self { Some(input.0) } } impl From for SubPixel { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for SubPixel { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for SubPixel { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for SubPixel { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::UNKNOWN.0, "UNKNOWN", "Unknown"), (Self::HORIZONTAL_RGB.0, "HORIZONTAL_RGB", "HorizontalRGB"), (Self::HORIZONTAL_BGR.0, "HORIZONTAL_BGR", "HorizontalBGR"), (Self::VERTICAL_RGB.0, "VERTICAL_RGB", "VerticalRGB"), (Self::VERTICAL_BGR.0, "VERTICAL_BGR", "VerticalBGR"), (Self::NONE.0, "NONE", "None"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Repeat(u32); impl Repeat { pub const NONE: Self = Self(0); pub const NORMAL: Self = Self(1); pub const PAD: Self = Self(2); pub const REFLECT: Self = Self(3); } impl From for u32 { #[inline] fn from(input: Repeat) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Repeat) -> Self { Some(input.0) } } impl From for Repeat { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for Repeat { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for Repeat { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for Repeat { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NONE.0, "NONE", "None"), (Self::NORMAL.0, "NORMAL", "Normal"), (Self::PAD.0, "PAD", "Pad"), (Self::REFLECT.0, "REFLECT", "Reflect"), ]; pretty_print_enum(fmt, self.0, &variants) } } pub type Glyph = u32; pub type Glyphset = u32; pub type Picture = u32; pub type Pictformat = u32; pub type Fixed = i32; /// Opcode for the PictFormat error pub const PICT_FORMAT_ERROR: u8 = 0; /// Opcode for the Picture error pub const PICTURE_ERROR: u8 = 1; /// Opcode for the PictOp error pub const PICT_OP_ERROR: u8 = 2; /// Opcode for the GlyphSet error pub const GLYPH_SET_ERROR: u8 = 3; /// Opcode for the Glyph error pub const GLYPH_ERROR: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Directformat { pub red_shift: u16, pub red_mask: u16, pub green_shift: u16, pub green_mask: u16, pub blue_shift: u16, pub blue_mask: u16, pub alpha_shift: u16, pub alpha_mask: u16, } impl TryParse for Directformat { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (red_shift, remaining) = u16::try_parse(remaining)?; let (red_mask, remaining) = u16::try_parse(remaining)?; let (green_shift, remaining) = u16::try_parse(remaining)?; let (green_mask, remaining) = u16::try_parse(remaining)?; let (blue_shift, remaining) = u16::try_parse(remaining)?; let (blue_mask, remaining) = u16::try_parse(remaining)?; let (alpha_shift, remaining) = u16::try_parse(remaining)?; let (alpha_mask, remaining) = u16::try_parse(remaining)?; let result = Directformat { red_shift, red_mask, green_shift, green_mask, blue_shift, blue_mask, alpha_shift, alpha_mask }; Ok((result, remaining)) } } impl Serialize for Directformat { type Bytes = [u8; 16]; fn serialize(&self) -> [u8; 16] { let red_shift_bytes = self.red_shift.serialize(); let red_mask_bytes = self.red_mask.serialize(); let green_shift_bytes = self.green_shift.serialize(); let green_mask_bytes = self.green_mask.serialize(); let blue_shift_bytes = self.blue_shift.serialize(); let blue_mask_bytes = self.blue_mask.serialize(); let alpha_shift_bytes = self.alpha_shift.serialize(); let alpha_mask_bytes = self.alpha_mask.serialize(); [ red_shift_bytes[0], red_shift_bytes[1], red_mask_bytes[0], red_mask_bytes[1], green_shift_bytes[0], green_shift_bytes[1], green_mask_bytes[0], green_mask_bytes[1], blue_shift_bytes[0], blue_shift_bytes[1], blue_mask_bytes[0], blue_mask_bytes[1], alpha_shift_bytes[0], alpha_shift_bytes[1], alpha_mask_bytes[0], alpha_mask_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); self.red_shift.serialize_into(bytes); self.red_mask.serialize_into(bytes); self.green_shift.serialize_into(bytes); self.green_mask.serialize_into(bytes); self.blue_shift.serialize_into(bytes); self.blue_mask.serialize_into(bytes); self.alpha_shift.serialize_into(bytes); self.alpha_mask.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Pictforminfo { pub id: Pictformat, pub type_: PictType, pub depth: u8, pub direct: Directformat, pub colormap: xproto::Colormap, } impl TryParse for Pictforminfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (id, remaining) = Pictformat::try_parse(remaining)?; let (type_, remaining) = u8::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (direct, remaining) = Directformat::try_parse(remaining)?; let (colormap, remaining) = xproto::Colormap::try_parse(remaining)?; let type_ = type_.into(); let result = Pictforminfo { id, type_, depth, direct, colormap }; Ok((result, remaining)) } } impl Serialize for Pictforminfo { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let id_bytes = self.id.serialize(); let type_bytes = u8::from(self.type_).serialize(); let depth_bytes = self.depth.serialize(); let direct_bytes = self.direct.serialize(); let colormap_bytes = self.colormap.serialize(); [ id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], type_bytes[0], depth_bytes[0], 0, 0, direct_bytes[0], direct_bytes[1], direct_bytes[2], direct_bytes[3], direct_bytes[4], direct_bytes[5], direct_bytes[6], direct_bytes[7], direct_bytes[8], direct_bytes[9], direct_bytes[10], direct_bytes[11], direct_bytes[12], direct_bytes[13], direct_bytes[14], direct_bytes[15], colormap_bytes[0], colormap_bytes[1], colormap_bytes[2], colormap_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.id.serialize_into(bytes); u8::from(self.type_).serialize_into(bytes); self.depth.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.direct.serialize_into(bytes); self.colormap.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Pictvisual { pub visual: xproto::Visualid, pub format: Pictformat, } impl TryParse for Pictvisual { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (format, remaining) = Pictformat::try_parse(remaining)?; let result = Pictvisual { visual, format }; Ok((result, remaining)) } } impl Serialize for Pictvisual { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let visual_bytes = self.visual.serialize(); let format_bytes = self.format.serialize(); [ visual_bytes[0], visual_bytes[1], visual_bytes[2], visual_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.visual.serialize_into(bytes); self.format.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pictdepth { pub depth: u8, pub visuals: Vec, } impl TryParse for Pictdepth { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (num_visuals, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (visuals, remaining) = crate::x11_utils::parse_list::(remaining, num_visuals.try_to_usize()?)?; let result = Pictdepth { depth, visuals }; Ok((result, remaining)) } } impl Serialize for Pictdepth { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.depth.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); let num_visuals = u16::try_from(self.visuals.len()).expect("`visuals` has too many elements"); num_visuals.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); self.visuals.serialize_into(bytes); } } impl Pictdepth { /// Get the value of the `num_visuals` field. /// /// The `num_visuals` field is used as the length field of the `visuals` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_visuals(&self) -> u16 { self.visuals.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Pictscreen { pub fallback: Pictformat, pub depths: Vec, } impl TryParse for Pictscreen { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_depths, remaining) = u32::try_parse(remaining)?; let (fallback, remaining) = Pictformat::try_parse(remaining)?; let (depths, remaining) = crate::x11_utils::parse_list::(remaining, num_depths.try_to_usize()?)?; let result = Pictscreen { fallback, depths }; Ok((result, remaining)) } } impl Serialize for Pictscreen { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); let num_depths = u32::try_from(self.depths.len()).expect("`depths` has too many elements"); num_depths.serialize_into(bytes); self.fallback.serialize_into(bytes); self.depths.serialize_into(bytes); } } impl Pictscreen { /// Get the value of the `num_depths` field. /// /// The `num_depths` field is used as the length field of the `depths` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_depths(&self) -> u32 { self.depths.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Indexvalue { pub pixel: u32, pub red: u16, pub green: u16, pub blue: u16, pub alpha: u16, } impl TryParse for Indexvalue { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (pixel, remaining) = u32::try_parse(remaining)?; let (red, remaining) = u16::try_parse(remaining)?; let (green, remaining) = u16::try_parse(remaining)?; let (blue, remaining) = u16::try_parse(remaining)?; let (alpha, remaining) = u16::try_parse(remaining)?; let result = Indexvalue { pixel, red, green, blue, alpha }; Ok((result, remaining)) } } impl Serialize for Indexvalue { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let pixel_bytes = self.pixel.serialize(); let red_bytes = self.red.serialize(); let green_bytes = self.green.serialize(); let blue_bytes = self.blue.serialize(); let alpha_bytes = self.alpha.serialize(); [ pixel_bytes[0], pixel_bytes[1], pixel_bytes[2], pixel_bytes[3], red_bytes[0], red_bytes[1], green_bytes[0], green_bytes[1], blue_bytes[0], blue_bytes[1], alpha_bytes[0], alpha_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.pixel.serialize_into(bytes); self.red.serialize_into(bytes); self.green.serialize_into(bytes); self.blue.serialize_into(bytes); self.alpha.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Color { pub red: u16, pub green: u16, pub blue: u16, pub alpha: u16, } impl TryParse for Color { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (red, remaining) = u16::try_parse(remaining)?; let (green, remaining) = u16::try_parse(remaining)?; let (blue, remaining) = u16::try_parse(remaining)?; let (alpha, remaining) = u16::try_parse(remaining)?; let result = Color { red, green, blue, alpha }; Ok((result, remaining)) } } impl Serialize for Color { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let red_bytes = self.red.serialize(); let green_bytes = self.green.serialize(); let blue_bytes = self.blue.serialize(); let alpha_bytes = self.alpha.serialize(); [ red_bytes[0], red_bytes[1], green_bytes[0], green_bytes[1], blue_bytes[0], blue_bytes[1], alpha_bytes[0], alpha_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.red.serialize_into(bytes); self.green.serialize_into(bytes); self.blue.serialize_into(bytes); self.alpha.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Pointfix { pub x: Fixed, pub y: Fixed, } impl TryParse for Pointfix { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (x, remaining) = Fixed::try_parse(remaining)?; let (y, remaining) = Fixed::try_parse(remaining)?; let result = Pointfix { x, y }; Ok((result, remaining)) } } impl Serialize for Pointfix { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); [ x_bytes[0], x_bytes[1], x_bytes[2], x_bytes[3], y_bytes[0], y_bytes[1], y_bytes[2], y_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.x.serialize_into(bytes); self.y.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Linefix { pub p1: Pointfix, pub p2: Pointfix, } impl TryParse for Linefix { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (p1, remaining) = Pointfix::try_parse(remaining)?; let (p2, remaining) = Pointfix::try_parse(remaining)?; let result = Linefix { p1, p2 }; Ok((result, remaining)) } } impl Serialize for Linefix { type Bytes = [u8; 16]; fn serialize(&self) -> [u8; 16] { let p1_bytes = self.p1.serialize(); let p2_bytes = self.p2.serialize(); [ p1_bytes[0], p1_bytes[1], p1_bytes[2], p1_bytes[3], p1_bytes[4], p1_bytes[5], p1_bytes[6], p1_bytes[7], p2_bytes[0], p2_bytes[1], p2_bytes[2], p2_bytes[3], p2_bytes[4], p2_bytes[5], p2_bytes[6], p2_bytes[7], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); self.p1.serialize_into(bytes); self.p2.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Triangle { pub p1: Pointfix, pub p2: Pointfix, pub p3: Pointfix, } impl TryParse for Triangle { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (p1, remaining) = Pointfix::try_parse(remaining)?; let (p2, remaining) = Pointfix::try_parse(remaining)?; let (p3, remaining) = Pointfix::try_parse(remaining)?; let result = Triangle { p1, p2, p3 }; Ok((result, remaining)) } } impl Serialize for Triangle { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let p1_bytes = self.p1.serialize(); let p2_bytes = self.p2.serialize(); let p3_bytes = self.p3.serialize(); [ p1_bytes[0], p1_bytes[1], p1_bytes[2], p1_bytes[3], p1_bytes[4], p1_bytes[5], p1_bytes[6], p1_bytes[7], p2_bytes[0], p2_bytes[1], p2_bytes[2], p2_bytes[3], p2_bytes[4], p2_bytes[5], p2_bytes[6], p2_bytes[7], p3_bytes[0], p3_bytes[1], p3_bytes[2], p3_bytes[3], p3_bytes[4], p3_bytes[5], p3_bytes[6], p3_bytes[7], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.p1.serialize_into(bytes); self.p2.serialize_into(bytes); self.p3.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Trapezoid { pub top: Fixed, pub bottom: Fixed, pub left: Linefix, pub right: Linefix, } impl TryParse for Trapezoid { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (top, remaining) = Fixed::try_parse(remaining)?; let (bottom, remaining) = Fixed::try_parse(remaining)?; let (left, remaining) = Linefix::try_parse(remaining)?; let (right, remaining) = Linefix::try_parse(remaining)?; let result = Trapezoid { top, bottom, left, right }; Ok((result, remaining)) } } impl Serialize for Trapezoid { type Bytes = [u8; 40]; fn serialize(&self) -> [u8; 40] { let top_bytes = self.top.serialize(); let bottom_bytes = self.bottom.serialize(); let left_bytes = self.left.serialize(); let right_bytes = self.right.serialize(); [ top_bytes[0], top_bytes[1], top_bytes[2], top_bytes[3], bottom_bytes[0], bottom_bytes[1], bottom_bytes[2], bottom_bytes[3], left_bytes[0], left_bytes[1], left_bytes[2], left_bytes[3], left_bytes[4], left_bytes[5], left_bytes[6], left_bytes[7], left_bytes[8], left_bytes[9], left_bytes[10], left_bytes[11], left_bytes[12], left_bytes[13], left_bytes[14], left_bytes[15], right_bytes[0], right_bytes[1], right_bytes[2], right_bytes[3], right_bytes[4], right_bytes[5], right_bytes[6], right_bytes[7], right_bytes[8], right_bytes[9], right_bytes[10], right_bytes[11], right_bytes[12], right_bytes[13], right_bytes[14], right_bytes[15], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(40); self.top.serialize_into(bytes); self.bottom.serialize_into(bytes); self.left.serialize_into(bytes); self.right.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Glyphinfo { pub width: u16, pub height: u16, pub x: i16, pub y: i16, pub x_off: i16, pub y_off: i16, } impl TryParse for Glyphinfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (x_off, remaining) = i16::try_parse(remaining)?; let (y_off, remaining) = i16::try_parse(remaining)?; let result = Glyphinfo { width, height, x, y, x_off, y_off }; Ok((result, remaining)) } } impl Serialize for Glyphinfo { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let x_off_bytes = self.x_off.serialize(); let y_off_bytes = self.y_off.serialize(); [ width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], x_off_bytes[0], x_off_bytes[1], y_off_bytes[0], y_off_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.x.serialize_into(bytes); self.y.serialize_into(bytes); self.x_off.serialize_into(bytes); self.y_off.serialize_into(bytes); } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major_version: u32, pub client_minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_major_version_bytes[2], client_major_version_bytes[3], client_minor_version_bytes[0], client_minor_version_bytes[1], client_minor_version_bytes[2], client_minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u32::try_parse(value)?; let (client_minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major_version, client_minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryPictFormats request pub const QUERY_PICT_FORMATS_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryPictFormatsRequest; impl QueryPictFormatsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_PICT_FORMATS_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_PICT_FORMATS_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryPictFormatsRequest ) } } impl Request for QueryPictFormatsRequest { type Reply = QueryPictFormatsReply; } pub fn query_pict_formats(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryPictFormatsRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryPictFormatsReply { pub sequence: u16, pub length: u32, pub num_depths: u32, pub num_visuals: u32, pub formats: Vec, pub screens: Vec, pub subpixels: Vec, } impl TryParse for QueryPictFormatsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_formats, remaining) = u32::try_parse(remaining)?; let (num_screens, remaining) = u32::try_parse(remaining)?; let (num_depths, remaining) = u32::try_parse(remaining)?; let (num_visuals, remaining) = u32::try_parse(remaining)?; let (num_subpixel, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (formats, remaining) = crate::x11_utils::parse_list::(remaining, num_formats.try_to_usize()?)?; let (screens, remaining) = crate::x11_utils::parse_list::(remaining, num_screens.try_to_usize()?)?; let mut remaining = remaining; let list_length = num_subpixel.try_to_usize()?; let mut subpixels = Vec::with_capacity(list_length); for _ in 0..list_length { let (v, new_remaining) = u32::try_parse(remaining)?; let v = v.into(); remaining = new_remaining; subpixels.push(v); } if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryPictFormatsReply { sequence, length, num_depths, num_visuals, formats, screens, subpixels }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryPictFormatsReply { /// Get the value of the `num_formats` field. /// /// The `num_formats` field is used as the length field of the `formats` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_formats(&self) -> u32 { self.formats.len() .try_into().unwrap() } /// Get the value of the `num_screens` field. /// /// The `num_screens` field is used as the length field of the `screens` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_screens(&self) -> u32 { self.screens.len() .try_into().unwrap() } /// Get the value of the `num_subpixel` field. /// /// The `num_subpixel` field is used as the length field of the `subpixels` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_subpixel(&self) -> u32 { self.subpixels.len() .try_into().unwrap() } } /// Opcode for the QueryPictIndexValues request pub const QUERY_PICT_INDEX_VALUES_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryPictIndexValuesRequest { pub format: Pictformat, } impl QueryPictIndexValuesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let format_bytes = self.format.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_PICT_INDEX_VALUES_REQUEST, 0, 0, format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_PICT_INDEX_VALUES_REQUEST { return Err(ParseError::InvalidValue); } let (format, remaining) = Pictformat::try_parse(value)?; let _ = remaining; Ok(QueryPictIndexValuesRequest { format, }) } } impl Request for QueryPictIndexValuesRequest { type Reply = QueryPictIndexValuesReply; } pub fn query_pict_index_values(conn: &Conn, format: Pictformat) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryPictIndexValuesRequest { format, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryPictIndexValuesReply { pub sequence: u16, pub length: u32, pub values: Vec, } impl TryParse for QueryPictIndexValuesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_values, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (values, remaining) = crate::x11_utils::parse_list::(remaining, num_values.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryPictIndexValuesReply { sequence, length, values }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryPictIndexValuesReply { /// Get the value of the `num_values` field. /// /// The `num_values` field is used as the length field of the `values` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_values(&self) -> u32 { self.values.len() .try_into().unwrap() } } /// Auxiliary and optional information for the `create_picture` function #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct CreatePictureAux { pub repeat: Option, pub alphamap: Option, pub alphaxorigin: Option, pub alphayorigin: Option, pub clipxorigin: Option, pub clipyorigin: Option, pub clipmask: Option, pub graphicsexposure: Option, pub subwindowmode: Option, pub polyedge: Option, pub polymode: Option, pub dither: Option, pub componentalpha: Option, } impl CreatePictureAux { fn try_parse(value: &[u8], value_mask: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = value_mask; let mut outer_remaining = value; let repeat = if switch_expr & u32::from(CP::REPEAT) != 0 { let remaining = outer_remaining; let (repeat, remaining) = u32::try_parse(remaining)?; let repeat = repeat.into(); outer_remaining = remaining; Some(repeat) } else { None }; let alphamap = if switch_expr & u32::from(CP::ALPHA_MAP) != 0 { let remaining = outer_remaining; let (alphamap, remaining) = Picture::try_parse(remaining)?; outer_remaining = remaining; Some(alphamap) } else { None }; let alphaxorigin = if switch_expr & u32::from(CP::ALPHA_X_ORIGIN) != 0 { let remaining = outer_remaining; let (alphaxorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(alphaxorigin) } else { None }; let alphayorigin = if switch_expr & u32::from(CP::ALPHA_Y_ORIGIN) != 0 { let remaining = outer_remaining; let (alphayorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(alphayorigin) } else { None }; let clipxorigin = if switch_expr & u32::from(CP::CLIP_X_ORIGIN) != 0 { let remaining = outer_remaining; let (clipxorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(clipxorigin) } else { None }; let clipyorigin = if switch_expr & u32::from(CP::CLIP_Y_ORIGIN) != 0 { let remaining = outer_remaining; let (clipyorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(clipyorigin) } else { None }; let clipmask = if switch_expr & u32::from(CP::CLIP_MASK) != 0 { let remaining = outer_remaining; let (clipmask, remaining) = xproto::Pixmap::try_parse(remaining)?; outer_remaining = remaining; Some(clipmask) } else { None }; let graphicsexposure = if switch_expr & u32::from(CP::GRAPHICS_EXPOSURE) != 0 { let remaining = outer_remaining; let (graphicsexposure, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(graphicsexposure) } else { None }; let subwindowmode = if switch_expr & u32::from(CP::SUBWINDOW_MODE) != 0 { let remaining = outer_remaining; let (subwindowmode, remaining) = u32::try_parse(remaining)?; let subwindowmode = subwindowmode.into(); outer_remaining = remaining; Some(subwindowmode) } else { None }; let polyedge = if switch_expr & u32::from(CP::POLY_EDGE) != 0 { let remaining = outer_remaining; let (polyedge, remaining) = u32::try_parse(remaining)?; let polyedge = polyedge.into(); outer_remaining = remaining; Some(polyedge) } else { None }; let polymode = if switch_expr & u32::from(CP::POLY_MODE) != 0 { let remaining = outer_remaining; let (polymode, remaining) = u32::try_parse(remaining)?; let polymode = polymode.into(); outer_remaining = remaining; Some(polymode) } else { None }; let dither = if switch_expr & u32::from(CP::DITHER) != 0 { let remaining = outer_remaining; let (dither, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(dither) } else { None }; let componentalpha = if switch_expr & u32::from(CP::COMPONENT_ALPHA) != 0 { let remaining = outer_remaining; let (componentalpha, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(componentalpha) } else { None }; let result = CreatePictureAux { repeat, alphamap, alphaxorigin, alphayorigin, clipxorigin, clipyorigin, clipmask, graphicsexposure, subwindowmode, polyedge, polymode, dither, componentalpha }; Ok((result, outer_remaining)) } } impl CreatePictureAux { #[allow(dead_code)] fn serialize(&self, value_mask: u32) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, value_mask); result } fn serialize_into(&self, bytes: &mut Vec, value_mask: u32) { assert_eq!(self.switch_expr(), value_mask, "switch `value_list` has an inconsistent discriminant"); if let Some(repeat) = self.repeat { u32::from(repeat).serialize_into(bytes); } if let Some(alphamap) = self.alphamap { alphamap.serialize_into(bytes); } if let Some(alphaxorigin) = self.alphaxorigin { alphaxorigin.serialize_into(bytes); } if let Some(alphayorigin) = self.alphayorigin { alphayorigin.serialize_into(bytes); } if let Some(clipxorigin) = self.clipxorigin { clipxorigin.serialize_into(bytes); } if let Some(clipyorigin) = self.clipyorigin { clipyorigin.serialize_into(bytes); } if let Some(clipmask) = self.clipmask { clipmask.serialize_into(bytes); } if let Some(graphicsexposure) = self.graphicsexposure { graphicsexposure.serialize_into(bytes); } if let Some(subwindowmode) = self.subwindowmode { u32::from(subwindowmode).serialize_into(bytes); } if let Some(polyedge) = self.polyedge { u32::from(polyedge).serialize_into(bytes); } if let Some(polymode) = self.polymode { u32::from(polymode).serialize_into(bytes); } if let Some(dither) = self.dither { dither.serialize_into(bytes); } if let Some(componentalpha) = self.componentalpha { componentalpha.serialize_into(bytes); } } } impl CreatePictureAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.repeat.is_some() { expr_value |= u32::from(CP::REPEAT); } if self.alphamap.is_some() { expr_value |= u32::from(CP::ALPHA_MAP); } if self.alphaxorigin.is_some() { expr_value |= u32::from(CP::ALPHA_X_ORIGIN); } if self.alphayorigin.is_some() { expr_value |= u32::from(CP::ALPHA_Y_ORIGIN); } if self.clipxorigin.is_some() { expr_value |= u32::from(CP::CLIP_X_ORIGIN); } if self.clipyorigin.is_some() { expr_value |= u32::from(CP::CLIP_Y_ORIGIN); } if self.clipmask.is_some() { expr_value |= u32::from(CP::CLIP_MASK); } if self.graphicsexposure.is_some() { expr_value |= u32::from(CP::GRAPHICS_EXPOSURE); } if self.subwindowmode.is_some() { expr_value |= u32::from(CP::SUBWINDOW_MODE); } if self.polyedge.is_some() { expr_value |= u32::from(CP::POLY_EDGE); } if self.polymode.is_some() { expr_value |= u32::from(CP::POLY_MODE); } if self.dither.is_some() { expr_value |= u32::from(CP::DITHER); } if self.componentalpha.is_some() { expr_value |= u32::from(CP::COMPONENT_ALPHA); } expr_value } } impl CreatePictureAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `repeat` field of this structure. pub fn repeat(mut self, value: I) -> Self where I: Into> { self.repeat = value.into(); self } /// Set the `alphamap` field of this structure. pub fn alphamap(mut self, value: I) -> Self where I: Into> { self.alphamap = value.into(); self } /// Set the `alphaxorigin` field of this structure. pub fn alphaxorigin(mut self, value: I) -> Self where I: Into> { self.alphaxorigin = value.into(); self } /// Set the `alphayorigin` field of this structure. pub fn alphayorigin(mut self, value: I) -> Self where I: Into> { self.alphayorigin = value.into(); self } /// Set the `clipxorigin` field of this structure. pub fn clipxorigin(mut self, value: I) -> Self where I: Into> { self.clipxorigin = value.into(); self } /// Set the `clipyorigin` field of this structure. pub fn clipyorigin(mut self, value: I) -> Self where I: Into> { self.clipyorigin = value.into(); self } /// Set the `clipmask` field of this structure. pub fn clipmask(mut self, value: I) -> Self where I: Into> { self.clipmask = value.into(); self } /// Set the `graphicsexposure` field of this structure. pub fn graphicsexposure(mut self, value: I) -> Self where I: Into> { self.graphicsexposure = value.into(); self } /// Set the `subwindowmode` field of this structure. pub fn subwindowmode(mut self, value: I) -> Self where I: Into> { self.subwindowmode = value.into(); self } /// Set the `polyedge` field of this structure. pub fn polyedge(mut self, value: I) -> Self where I: Into> { self.polyedge = value.into(); self } /// Set the `polymode` field of this structure. pub fn polymode(mut self, value: I) -> Self where I: Into> { self.polymode = value.into(); self } /// Set the `dither` field of this structure. pub fn dither(mut self, value: I) -> Self where I: Into> { self.dither = value.into(); self } /// Set the `componentalpha` field of this structure. pub fn componentalpha(mut self, value: I) -> Self where I: Into> { self.componentalpha = value.into(); self } } /// Opcode for the CreatePicture request pub const CREATE_PICTURE_REQUEST: u8 = 4; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreatePictureRequest<'input> { pub pid: Picture, pub drawable: xproto::Drawable, pub format: Pictformat, pub value_list: Cow<'input, CreatePictureAux>, } impl<'input> CreatePictureRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let pid_bytes = self.pid.serialize(); let drawable_bytes = self.drawable.serialize(); let format_bytes = self.format.serialize(); let value_mask = self.value_list.switch_expr(); let value_mask_bytes = value_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_PICTURE_REQUEST, 0, 0, pid_bytes[0], pid_bytes[1], pid_bytes[2], pid_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], value_mask_bytes[0], value_mask_bytes[1], value_mask_bytes[2], value_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let value_list_bytes = self.value_list.serialize(value_mask); let length_so_far = length_so_far + value_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), value_list_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_PICTURE_REQUEST { return Err(ParseError::InvalidValue); } let (pid, remaining) = Picture::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (format, remaining) = Pictformat::try_parse(remaining)?; let (value_mask, remaining) = u32::try_parse(remaining)?; let (value_list, remaining) = CreatePictureAux::try_parse(remaining, value_mask)?; let _ = remaining; Ok(CreatePictureRequest { pid, drawable, format, value_list: Cow::Owned(value_list), }) } /// Clone all borrowed data in this CreatePictureRequest. pub fn into_owned(self) -> CreatePictureRequest<'static> { CreatePictureRequest { pid: self.pid, drawable: self.drawable, format: self.format, value_list: Cow::Owned(self.value_list.into_owned()), } } } impl<'input> Request for CreatePictureRequest<'input> { type Reply = (); } pub fn create_picture<'c, 'input, Conn>(conn: &'c Conn, pid: Picture, drawable: xproto::Drawable, format: Pictformat, value_list: &'input CreatePictureAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreatePictureRequest { pid, drawable, format, value_list: Cow::Borrowed(value_list), }; request0.send(conn) } /// Auxiliary and optional information for the `change_picture` function #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct ChangePictureAux { pub repeat: Option, pub alphamap: Option, pub alphaxorigin: Option, pub alphayorigin: Option, pub clipxorigin: Option, pub clipyorigin: Option, pub clipmask: Option, pub graphicsexposure: Option, pub subwindowmode: Option, pub polyedge: Option, pub polymode: Option, pub dither: Option, pub componentalpha: Option, } impl ChangePictureAux { fn try_parse(value: &[u8], value_mask: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = value_mask; let mut outer_remaining = value; let repeat = if switch_expr & u32::from(CP::REPEAT) != 0 { let remaining = outer_remaining; let (repeat, remaining) = u32::try_parse(remaining)?; let repeat = repeat.into(); outer_remaining = remaining; Some(repeat) } else { None }; let alphamap = if switch_expr & u32::from(CP::ALPHA_MAP) != 0 { let remaining = outer_remaining; let (alphamap, remaining) = Picture::try_parse(remaining)?; outer_remaining = remaining; Some(alphamap) } else { None }; let alphaxorigin = if switch_expr & u32::from(CP::ALPHA_X_ORIGIN) != 0 { let remaining = outer_remaining; let (alphaxorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(alphaxorigin) } else { None }; let alphayorigin = if switch_expr & u32::from(CP::ALPHA_Y_ORIGIN) != 0 { let remaining = outer_remaining; let (alphayorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(alphayorigin) } else { None }; let clipxorigin = if switch_expr & u32::from(CP::CLIP_X_ORIGIN) != 0 { let remaining = outer_remaining; let (clipxorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(clipxorigin) } else { None }; let clipyorigin = if switch_expr & u32::from(CP::CLIP_Y_ORIGIN) != 0 { let remaining = outer_remaining; let (clipyorigin, remaining) = i32::try_parse(remaining)?; outer_remaining = remaining; Some(clipyorigin) } else { None }; let clipmask = if switch_expr & u32::from(CP::CLIP_MASK) != 0 { let remaining = outer_remaining; let (clipmask, remaining) = xproto::Pixmap::try_parse(remaining)?; outer_remaining = remaining; Some(clipmask) } else { None }; let graphicsexposure = if switch_expr & u32::from(CP::GRAPHICS_EXPOSURE) != 0 { let remaining = outer_remaining; let (graphicsexposure, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(graphicsexposure) } else { None }; let subwindowmode = if switch_expr & u32::from(CP::SUBWINDOW_MODE) != 0 { let remaining = outer_remaining; let (subwindowmode, remaining) = u32::try_parse(remaining)?; let subwindowmode = subwindowmode.into(); outer_remaining = remaining; Some(subwindowmode) } else { None }; let polyedge = if switch_expr & u32::from(CP::POLY_EDGE) != 0 { let remaining = outer_remaining; let (polyedge, remaining) = u32::try_parse(remaining)?; let polyedge = polyedge.into(); outer_remaining = remaining; Some(polyedge) } else { None }; let polymode = if switch_expr & u32::from(CP::POLY_MODE) != 0 { let remaining = outer_remaining; let (polymode, remaining) = u32::try_parse(remaining)?; let polymode = polymode.into(); outer_remaining = remaining; Some(polymode) } else { None }; let dither = if switch_expr & u32::from(CP::DITHER) != 0 { let remaining = outer_remaining; let (dither, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(dither) } else { None }; let componentalpha = if switch_expr & u32::from(CP::COMPONENT_ALPHA) != 0 { let remaining = outer_remaining; let (componentalpha, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(componentalpha) } else { None }; let result = ChangePictureAux { repeat, alphamap, alphaxorigin, alphayorigin, clipxorigin, clipyorigin, clipmask, graphicsexposure, subwindowmode, polyedge, polymode, dither, componentalpha }; Ok((result, outer_remaining)) } } impl ChangePictureAux { #[allow(dead_code)] fn serialize(&self, value_mask: u32) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, value_mask); result } fn serialize_into(&self, bytes: &mut Vec, value_mask: u32) { assert_eq!(self.switch_expr(), value_mask, "switch `value_list` has an inconsistent discriminant"); if let Some(repeat) = self.repeat { u32::from(repeat).serialize_into(bytes); } if let Some(alphamap) = self.alphamap { alphamap.serialize_into(bytes); } if let Some(alphaxorigin) = self.alphaxorigin { alphaxorigin.serialize_into(bytes); } if let Some(alphayorigin) = self.alphayorigin { alphayorigin.serialize_into(bytes); } if let Some(clipxorigin) = self.clipxorigin { clipxorigin.serialize_into(bytes); } if let Some(clipyorigin) = self.clipyorigin { clipyorigin.serialize_into(bytes); } if let Some(clipmask) = self.clipmask { clipmask.serialize_into(bytes); } if let Some(graphicsexposure) = self.graphicsexposure { graphicsexposure.serialize_into(bytes); } if let Some(subwindowmode) = self.subwindowmode { u32::from(subwindowmode).serialize_into(bytes); } if let Some(polyedge) = self.polyedge { u32::from(polyedge).serialize_into(bytes); } if let Some(polymode) = self.polymode { u32::from(polymode).serialize_into(bytes); } if let Some(dither) = self.dither { dither.serialize_into(bytes); } if let Some(componentalpha) = self.componentalpha { componentalpha.serialize_into(bytes); } } } impl ChangePictureAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.repeat.is_some() { expr_value |= u32::from(CP::REPEAT); } if self.alphamap.is_some() { expr_value |= u32::from(CP::ALPHA_MAP); } if self.alphaxorigin.is_some() { expr_value |= u32::from(CP::ALPHA_X_ORIGIN); } if self.alphayorigin.is_some() { expr_value |= u32::from(CP::ALPHA_Y_ORIGIN); } if self.clipxorigin.is_some() { expr_value |= u32::from(CP::CLIP_X_ORIGIN); } if self.clipyorigin.is_some() { expr_value |= u32::from(CP::CLIP_Y_ORIGIN); } if self.clipmask.is_some() { expr_value |= u32::from(CP::CLIP_MASK); } if self.graphicsexposure.is_some() { expr_value |= u32::from(CP::GRAPHICS_EXPOSURE); } if self.subwindowmode.is_some() { expr_value |= u32::from(CP::SUBWINDOW_MODE); } if self.polyedge.is_some() { expr_value |= u32::from(CP::POLY_EDGE); } if self.polymode.is_some() { expr_value |= u32::from(CP::POLY_MODE); } if self.dither.is_some() { expr_value |= u32::from(CP::DITHER); } if self.componentalpha.is_some() { expr_value |= u32::from(CP::COMPONENT_ALPHA); } expr_value } } impl ChangePictureAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `repeat` field of this structure. pub fn repeat(mut self, value: I) -> Self where I: Into> { self.repeat = value.into(); self } /// Set the `alphamap` field of this structure. pub fn alphamap(mut self, value: I) -> Self where I: Into> { self.alphamap = value.into(); self } /// Set the `alphaxorigin` field of this structure. pub fn alphaxorigin(mut self, value: I) -> Self where I: Into> { self.alphaxorigin = value.into(); self } /// Set the `alphayorigin` field of this structure. pub fn alphayorigin(mut self, value: I) -> Self where I: Into> { self.alphayorigin = value.into(); self } /// Set the `clipxorigin` field of this structure. pub fn clipxorigin(mut self, value: I) -> Self where I: Into> { self.clipxorigin = value.into(); self } /// Set the `clipyorigin` field of this structure. pub fn clipyorigin(mut self, value: I) -> Self where I: Into> { self.clipyorigin = value.into(); self } /// Set the `clipmask` field of this structure. pub fn clipmask(mut self, value: I) -> Self where I: Into> { self.clipmask = value.into(); self } /// Set the `graphicsexposure` field of this structure. pub fn graphicsexposure(mut self, value: I) -> Self where I: Into> { self.graphicsexposure = value.into(); self } /// Set the `subwindowmode` field of this structure. pub fn subwindowmode(mut self, value: I) -> Self where I: Into> { self.subwindowmode = value.into(); self } /// Set the `polyedge` field of this structure. pub fn polyedge(mut self, value: I) -> Self where I: Into> { self.polyedge = value.into(); self } /// Set the `polymode` field of this structure. pub fn polymode(mut self, value: I) -> Self where I: Into> { self.polymode = value.into(); self } /// Set the `dither` field of this structure. pub fn dither(mut self, value: I) -> Self where I: Into> { self.dither = value.into(); self } /// Set the `componentalpha` field of this structure. pub fn componentalpha(mut self, value: I) -> Self where I: Into> { self.componentalpha = value.into(); self } } /// Opcode for the ChangePicture request pub const CHANGE_PICTURE_REQUEST: u8 = 5; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangePictureRequest<'input> { pub picture: Picture, pub value_list: Cow<'input, ChangePictureAux>, } impl<'input> ChangePictureRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let value_mask = self.value_list.switch_expr(); let value_mask_bytes = value_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_PICTURE_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], value_mask_bytes[0], value_mask_bytes[1], value_mask_bytes[2], value_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let value_list_bytes = self.value_list.serialize(value_mask); let length_so_far = length_so_far + value_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), value_list_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_PICTURE_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (value_mask, remaining) = u32::try_parse(remaining)?; let (value_list, remaining) = ChangePictureAux::try_parse(remaining, value_mask)?; let _ = remaining; Ok(ChangePictureRequest { picture, value_list: Cow::Owned(value_list), }) } /// Clone all borrowed data in this ChangePictureRequest. pub fn into_owned(self) -> ChangePictureRequest<'static> { ChangePictureRequest { picture: self.picture, value_list: Cow::Owned(self.value_list.into_owned()), } } } impl<'input> Request for ChangePictureRequest<'input> { type Reply = (); } pub fn change_picture<'c, 'input, Conn>(conn: &'c Conn, picture: Picture, value_list: &'input ChangePictureAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangePictureRequest { picture, value_list: Cow::Borrowed(value_list), }; request0.send(conn) } /// Opcode for the SetPictureClipRectangles request pub const SET_PICTURE_CLIP_RECTANGLES_REQUEST: u8 = 6; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetPictureClipRectanglesRequest<'input> { pub picture: Picture, pub clip_x_origin: i16, pub clip_y_origin: i16, pub rectangles: Cow<'input, [xproto::Rectangle]>, } impl<'input> SetPictureClipRectanglesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let clip_x_origin_bytes = self.clip_x_origin.serialize(); let clip_y_origin_bytes = self.clip_y_origin.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PICTURE_CLIP_RECTANGLES_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], clip_x_origin_bytes[0], clip_x_origin_bytes[1], clip_y_origin_bytes[0], clip_y_origin_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let rectangles_bytes = self.rectangles.serialize(); let length_so_far = length_so_far + rectangles_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), rectangles_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_PICTURE_CLIP_RECTANGLES_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (clip_x_origin, remaining) = i16::try_parse(remaining)?; let (clip_y_origin, remaining) = i16::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut rectangles = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = xproto::Rectangle::try_parse(remaining)?; remaining = new_remaining; rectangles.push(v); } let _ = remaining; Ok(SetPictureClipRectanglesRequest { picture, clip_x_origin, clip_y_origin, rectangles: Cow::Owned(rectangles), }) } /// Clone all borrowed data in this SetPictureClipRectanglesRequest. pub fn into_owned(self) -> SetPictureClipRectanglesRequest<'static> { SetPictureClipRectanglesRequest { picture: self.picture, clip_x_origin: self.clip_x_origin, clip_y_origin: self.clip_y_origin, rectangles: Cow::Owned(self.rectangles.into_owned()), } } } impl<'input> Request for SetPictureClipRectanglesRequest<'input> { type Reply = (); } pub fn set_picture_clip_rectangles<'c, 'input, Conn>(conn: &'c Conn, picture: Picture, clip_x_origin: i16, clip_y_origin: i16, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPictureClipRectanglesRequest { picture, clip_x_origin, clip_y_origin, rectangles: Cow::Borrowed(rectangles), }; request0.send(conn) } /// Opcode for the FreePicture request pub const FREE_PICTURE_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FreePictureRequest { pub picture: Picture, } impl FreePictureRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let mut request0 = vec![ extension_information.major_opcode, FREE_PICTURE_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FREE_PICTURE_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let _ = remaining; Ok(FreePictureRequest { picture, }) } } impl Request for FreePictureRequest { type Reply = (); } pub fn free_picture(conn: &Conn, picture: Picture) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FreePictureRequest { picture, }; request0.send(conn) } /// Opcode for the Composite request pub const COMPOSITE_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CompositeRequest { pub op: PictOp, pub src: Picture, pub mask: Picture, pub dst: Picture, pub src_x: i16, pub src_y: i16, pub mask_x: i16, pub mask_y: i16, pub dst_x: i16, pub dst_y: i16, pub width: u16, pub height: u16, } impl CompositeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let mask_bytes = self.mask.serialize(); let dst_bytes = self.dst.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mask_x_bytes = self.mask_x.serialize(); let mask_y_bytes = self.mask_y.serialize(); let dst_x_bytes = self.dst_x.serialize(); let dst_y_bytes = self.dst_y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let mut request0 = vec![ extension_information.major_opcode, COMPOSITE_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], mask_bytes[0], mask_bytes[1], mask_bytes[2], mask_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], mask_x_bytes[0], mask_x_bytes[1], mask_y_bytes[0], mask_y_bytes[1], dst_x_bytes[0], dst_x_bytes[1], dst_y_bytes[0], dst_y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != COMPOSITE_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (mask, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let (mask_x, remaining) = i16::try_parse(remaining)?; let (mask_y, remaining) = i16::try_parse(remaining)?; let (dst_x, remaining) = i16::try_parse(remaining)?; let (dst_y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(CompositeRequest { op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height, }) } } impl Request for CompositeRequest { type Reply = (); } pub fn composite(conn: &Conn, op: PictOp, src: Picture, mask: A, dst: Picture, src_x: i16, src_y: i16, mask_x: i16, mask_y: i16, dst_x: i16, dst_y: i16, width: u16, height: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let mask: Picture = mask.into(); let request0 = CompositeRequest { op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height, }; request0.send(conn) } /// Opcode for the Trapezoids request pub const TRAPEZOIDS_REQUEST: u8 = 10; #[derive(Debug, Clone, PartialEq, Eq)] pub struct TrapezoidsRequest<'input> { pub op: PictOp, pub src: Picture, pub dst: Picture, pub mask_format: Pictformat, pub src_x: i16, pub src_y: i16, pub traps: Cow<'input, [Trapezoid]>, } impl<'input> TrapezoidsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let dst_bytes = self.dst.serialize(); let mask_format_bytes = self.mask_format.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mut request0 = vec![ extension_information.major_opcode, TRAPEZOIDS_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], mask_format_bytes[0], mask_format_bytes[1], mask_format_bytes[2], mask_format_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let traps_bytes = self.traps.serialize(); let length_so_far = length_so_far + traps_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), traps_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != TRAPEZOIDS_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (mask_format, remaining) = Pictformat::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut traps = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Trapezoid::try_parse(remaining)?; remaining = new_remaining; traps.push(v); } let _ = remaining; Ok(TrapezoidsRequest { op, src, dst, mask_format, src_x, src_y, traps: Cow::Owned(traps), }) } /// Clone all borrowed data in this TrapezoidsRequest. pub fn into_owned(self) -> TrapezoidsRequest<'static> { TrapezoidsRequest { op: self.op, src: self.src, dst: self.dst, mask_format: self.mask_format, src_x: self.src_x, src_y: self.src_y, traps: Cow::Owned(self.traps.into_owned()), } } } impl<'input> Request for TrapezoidsRequest<'input> { type Reply = (); } pub fn trapezoids<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, traps: &'input [Trapezoid]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = TrapezoidsRequest { op, src, dst, mask_format, src_x, src_y, traps: Cow::Borrowed(traps), }; request0.send(conn) } /// Opcode for the Triangles request pub const TRIANGLES_REQUEST: u8 = 11; #[derive(Debug, Clone, PartialEq, Eq)] pub struct TrianglesRequest<'input> { pub op: PictOp, pub src: Picture, pub dst: Picture, pub mask_format: Pictformat, pub src_x: i16, pub src_y: i16, pub triangles: Cow<'input, [Triangle]>, } impl<'input> TrianglesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let dst_bytes = self.dst.serialize(); let mask_format_bytes = self.mask_format.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mut request0 = vec![ extension_information.major_opcode, TRIANGLES_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], mask_format_bytes[0], mask_format_bytes[1], mask_format_bytes[2], mask_format_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let triangles_bytes = self.triangles.serialize(); let length_so_far = length_so_far + triangles_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), triangles_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != TRIANGLES_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (mask_format, remaining) = Pictformat::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut triangles = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Triangle::try_parse(remaining)?; remaining = new_remaining; triangles.push(v); } let _ = remaining; Ok(TrianglesRequest { op, src, dst, mask_format, src_x, src_y, triangles: Cow::Owned(triangles), }) } /// Clone all borrowed data in this TrianglesRequest. pub fn into_owned(self) -> TrianglesRequest<'static> { TrianglesRequest { op: self.op, src: self.src, dst: self.dst, mask_format: self.mask_format, src_x: self.src_x, src_y: self.src_y, triangles: Cow::Owned(self.triangles.into_owned()), } } } impl<'input> Request for TrianglesRequest<'input> { type Reply = (); } pub fn triangles<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, triangles: &'input [Triangle]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = TrianglesRequest { op, src, dst, mask_format, src_x, src_y, triangles: Cow::Borrowed(triangles), }; request0.send(conn) } /// Opcode for the TriStrip request pub const TRI_STRIP_REQUEST: u8 = 12; #[derive(Debug, Clone, PartialEq, Eq)] pub struct TriStripRequest<'input> { pub op: PictOp, pub src: Picture, pub dst: Picture, pub mask_format: Pictformat, pub src_x: i16, pub src_y: i16, pub points: Cow<'input, [Pointfix]>, } impl<'input> TriStripRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let dst_bytes = self.dst.serialize(); let mask_format_bytes = self.mask_format.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mut request0 = vec![ extension_information.major_opcode, TRI_STRIP_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], mask_format_bytes[0], mask_format_bytes[1], mask_format_bytes[2], mask_format_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let points_bytes = self.points.serialize(); let length_so_far = length_so_far + points_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), points_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != TRI_STRIP_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (mask_format, remaining) = Pictformat::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut points = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Pointfix::try_parse(remaining)?; remaining = new_remaining; points.push(v); } let _ = remaining; Ok(TriStripRequest { op, src, dst, mask_format, src_x, src_y, points: Cow::Owned(points), }) } /// Clone all borrowed data in this TriStripRequest. pub fn into_owned(self) -> TriStripRequest<'static> { TriStripRequest { op: self.op, src: self.src, dst: self.dst, mask_format: self.mask_format, src_x: self.src_x, src_y: self.src_y, points: Cow::Owned(self.points.into_owned()), } } } impl<'input> Request for TriStripRequest<'input> { type Reply = (); } pub fn tri_strip<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, points: &'input [Pointfix]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = TriStripRequest { op, src, dst, mask_format, src_x, src_y, points: Cow::Borrowed(points), }; request0.send(conn) } /// Opcode for the TriFan request pub const TRI_FAN_REQUEST: u8 = 13; #[derive(Debug, Clone, PartialEq, Eq)] pub struct TriFanRequest<'input> { pub op: PictOp, pub src: Picture, pub dst: Picture, pub mask_format: Pictformat, pub src_x: i16, pub src_y: i16, pub points: Cow<'input, [Pointfix]>, } impl<'input> TriFanRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let dst_bytes = self.dst.serialize(); let mask_format_bytes = self.mask_format.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mut request0 = vec![ extension_information.major_opcode, TRI_FAN_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], mask_format_bytes[0], mask_format_bytes[1], mask_format_bytes[2], mask_format_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let points_bytes = self.points.serialize(); let length_so_far = length_so_far + points_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), points_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != TRI_FAN_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (mask_format, remaining) = Pictformat::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut points = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Pointfix::try_parse(remaining)?; remaining = new_remaining; points.push(v); } let _ = remaining; Ok(TriFanRequest { op, src, dst, mask_format, src_x, src_y, points: Cow::Owned(points), }) } /// Clone all borrowed data in this TriFanRequest. pub fn into_owned(self) -> TriFanRequest<'static> { TriFanRequest { op: self.op, src: self.src, dst: self.dst, mask_format: self.mask_format, src_x: self.src_x, src_y: self.src_y, points: Cow::Owned(self.points.into_owned()), } } } impl<'input> Request for TriFanRequest<'input> { type Reply = (); } pub fn tri_fan<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, points: &'input [Pointfix]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = TriFanRequest { op, src, dst, mask_format, src_x, src_y, points: Cow::Borrowed(points), }; request0.send(conn) } /// Opcode for the CreateGlyphSet request pub const CREATE_GLYPH_SET_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateGlyphSetRequest { pub gsid: Glyphset, pub format: Pictformat, } impl CreateGlyphSetRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let gsid_bytes = self.gsid.serialize(); let format_bytes = self.format.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_GLYPH_SET_REQUEST, 0, 0, gsid_bytes[0], gsid_bytes[1], gsid_bytes[2], gsid_bytes[3], format_bytes[0], format_bytes[1], format_bytes[2], format_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_GLYPH_SET_REQUEST { return Err(ParseError::InvalidValue); } let (gsid, remaining) = Glyphset::try_parse(value)?; let (format, remaining) = Pictformat::try_parse(remaining)?; let _ = remaining; Ok(CreateGlyphSetRequest { gsid, format, }) } } impl Request for CreateGlyphSetRequest { type Reply = (); } pub fn create_glyph_set(conn: &Conn, gsid: Glyphset, format: Pictformat) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateGlyphSetRequest { gsid, format, }; request0.send(conn) } /// Opcode for the ReferenceGlyphSet request pub const REFERENCE_GLYPH_SET_REQUEST: u8 = 18; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ReferenceGlyphSetRequest { pub gsid: Glyphset, pub existing: Glyphset, } impl ReferenceGlyphSetRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let gsid_bytes = self.gsid.serialize(); let existing_bytes = self.existing.serialize(); let mut request0 = vec![ extension_information.major_opcode, REFERENCE_GLYPH_SET_REQUEST, 0, 0, gsid_bytes[0], gsid_bytes[1], gsid_bytes[2], gsid_bytes[3], existing_bytes[0], existing_bytes[1], existing_bytes[2], existing_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != REFERENCE_GLYPH_SET_REQUEST { return Err(ParseError::InvalidValue); } let (gsid, remaining) = Glyphset::try_parse(value)?; let (existing, remaining) = Glyphset::try_parse(remaining)?; let _ = remaining; Ok(ReferenceGlyphSetRequest { gsid, existing, }) } } impl Request for ReferenceGlyphSetRequest { type Reply = (); } pub fn reference_glyph_set(conn: &Conn, gsid: Glyphset, existing: Glyphset) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ReferenceGlyphSetRequest { gsid, existing, }; request0.send(conn) } /// Opcode for the FreeGlyphSet request pub const FREE_GLYPH_SET_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FreeGlyphSetRequest { pub glyphset: Glyphset, } impl FreeGlyphSetRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let glyphset_bytes = self.glyphset.serialize(); let mut request0 = vec![ extension_information.major_opcode, FREE_GLYPH_SET_REQUEST, 0, 0, glyphset_bytes[0], glyphset_bytes[1], glyphset_bytes[2], glyphset_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FREE_GLYPH_SET_REQUEST { return Err(ParseError::InvalidValue); } let (glyphset, remaining) = Glyphset::try_parse(value)?; let _ = remaining; Ok(FreeGlyphSetRequest { glyphset, }) } } impl Request for FreeGlyphSetRequest { type Reply = (); } pub fn free_glyph_set(conn: &Conn, glyphset: Glyphset) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FreeGlyphSetRequest { glyphset, }; request0.send(conn) } /// Opcode for the AddGlyphs request pub const ADD_GLYPHS_REQUEST: u8 = 20; #[derive(Debug, Clone, PartialEq, Eq)] pub struct AddGlyphsRequest<'input> { pub glyphset: Glyphset, pub glyphids: Cow<'input, [u32]>, pub glyphs: Cow<'input, [Glyphinfo]>, pub data: Cow<'input, [u8]>, } impl<'input> AddGlyphsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let glyphset_bytes = self.glyphset.serialize(); let glyphs_len = u32::try_from(self.glyphids.len()).expect("`glyphids` has too many elements"); let glyphs_len_bytes = glyphs_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, ADD_GLYPHS_REQUEST, 0, 0, glyphset_bytes[0], glyphset_bytes[1], glyphset_bytes[2], glyphset_bytes[3], glyphs_len_bytes[0], glyphs_len_bytes[1], glyphs_len_bytes[2], glyphs_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let glyphids_bytes = self.glyphids.serialize(); let length_so_far = length_so_far + glyphids_bytes.len(); assert_eq!(self.glyphs.len(), usize::try_from(glyphs_len).unwrap(), "`glyphs` has an incorrect length"); let glyphs_bytes = self.glyphs.serialize(); let length_so_far = length_so_far + glyphs_bytes.len(); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), glyphids_bytes.into(), glyphs_bytes.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != ADD_GLYPHS_REQUEST { return Err(ParseError::InvalidValue); } let (glyphset, remaining) = Glyphset::try_parse(value)?; let (glyphs_len, remaining) = u32::try_parse(remaining)?; let (glyphids, remaining) = crate::x11_utils::parse_list::(remaining, glyphs_len.try_to_usize()?)?; let (glyphs, remaining) = crate::x11_utils::parse_list::(remaining, glyphs_len.try_to_usize()?)?; let (data, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(AddGlyphsRequest { glyphset, glyphids: Cow::Owned(glyphids), glyphs: Cow::Owned(glyphs), data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this AddGlyphsRequest. pub fn into_owned(self) -> AddGlyphsRequest<'static> { AddGlyphsRequest { glyphset: self.glyphset, glyphids: Cow::Owned(self.glyphids.into_owned()), glyphs: Cow::Owned(self.glyphs.into_owned()), data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for AddGlyphsRequest<'input> { type Reply = (); } pub fn add_glyphs<'c, 'input, Conn>(conn: &'c Conn, glyphset: Glyphset, glyphids: &'input [u32], glyphs: &'input [Glyphinfo], data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AddGlyphsRequest { glyphset, glyphids: Cow::Borrowed(glyphids), glyphs: Cow::Borrowed(glyphs), data: Cow::Borrowed(data), }; request0.send(conn) } /// Opcode for the FreeGlyphs request pub const FREE_GLYPHS_REQUEST: u8 = 22; #[derive(Debug, Clone, PartialEq, Eq)] pub struct FreeGlyphsRequest<'input> { pub glyphset: Glyphset, pub glyphs: Cow<'input, [Glyph]>, } impl<'input> FreeGlyphsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let glyphset_bytes = self.glyphset.serialize(); let mut request0 = vec![ extension_information.major_opcode, FREE_GLYPHS_REQUEST, 0, 0, glyphset_bytes[0], glyphset_bytes[1], glyphset_bytes[2], glyphset_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let glyphs_bytes = self.glyphs.serialize(); let length_so_far = length_so_far + glyphs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), glyphs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != FREE_GLYPHS_REQUEST { return Err(ParseError::InvalidValue); } let (glyphset, remaining) = Glyphset::try_parse(value)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut glyphs = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Glyph::try_parse(remaining)?; remaining = new_remaining; glyphs.push(v); } let _ = remaining; Ok(FreeGlyphsRequest { glyphset, glyphs: Cow::Owned(glyphs), }) } /// Clone all borrowed data in this FreeGlyphsRequest. pub fn into_owned(self) -> FreeGlyphsRequest<'static> { FreeGlyphsRequest { glyphset: self.glyphset, glyphs: Cow::Owned(self.glyphs.into_owned()), } } } impl<'input> Request for FreeGlyphsRequest<'input> { type Reply = (); } pub fn free_glyphs<'c, 'input, Conn>(conn: &'c Conn, glyphset: Glyphset, glyphs: &'input [Glyph]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FreeGlyphsRequest { glyphset, glyphs: Cow::Borrowed(glyphs), }; request0.send(conn) } /// Opcode for the CompositeGlyphs8 request pub const COMPOSITE_GLYPHS8_REQUEST: u8 = 23; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CompositeGlyphs8Request<'input> { pub op: PictOp, pub src: Picture, pub dst: Picture, pub mask_format: Pictformat, pub glyphset: Glyphset, pub src_x: i16, pub src_y: i16, pub glyphcmds: Cow<'input, [u8]>, } impl<'input> CompositeGlyphs8Request<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let dst_bytes = self.dst.serialize(); let mask_format_bytes = self.mask_format.serialize(); let glyphset_bytes = self.glyphset.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mut request0 = vec![ extension_information.major_opcode, COMPOSITE_GLYPHS8_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], mask_format_bytes[0], mask_format_bytes[1], mask_format_bytes[2], mask_format_bytes[3], glyphset_bytes[0], glyphset_bytes[1], glyphset_bytes[2], glyphset_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.glyphcmds.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.glyphcmds, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != COMPOSITE_GLYPHS8_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (mask_format, remaining) = Pictformat::try_parse(remaining)?; let (glyphset, remaining) = Glyphset::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let (glyphcmds, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(CompositeGlyphs8Request { op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds: Cow::Borrowed(glyphcmds), }) } /// Clone all borrowed data in this CompositeGlyphs8Request. pub fn into_owned(self) -> CompositeGlyphs8Request<'static> { CompositeGlyphs8Request { op: self.op, src: self.src, dst: self.dst, mask_format: self.mask_format, glyphset: self.glyphset, src_x: self.src_x, src_y: self.src_y, glyphcmds: Cow::Owned(self.glyphcmds.into_owned()), } } } impl<'input> Request for CompositeGlyphs8Request<'input> { type Reply = (); } pub fn composite_glyphs8<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, glyphset: Glyphset, src_x: i16, src_y: i16, glyphcmds: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CompositeGlyphs8Request { op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds: Cow::Borrowed(glyphcmds), }; request0.send(conn) } /// Opcode for the CompositeGlyphs16 request pub const COMPOSITE_GLYPHS16_REQUEST: u8 = 24; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CompositeGlyphs16Request<'input> { pub op: PictOp, pub src: Picture, pub dst: Picture, pub mask_format: Pictformat, pub glyphset: Glyphset, pub src_x: i16, pub src_y: i16, pub glyphcmds: Cow<'input, [u8]>, } impl<'input> CompositeGlyphs16Request<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let dst_bytes = self.dst.serialize(); let mask_format_bytes = self.mask_format.serialize(); let glyphset_bytes = self.glyphset.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mut request0 = vec![ extension_information.major_opcode, COMPOSITE_GLYPHS16_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], mask_format_bytes[0], mask_format_bytes[1], mask_format_bytes[2], mask_format_bytes[3], glyphset_bytes[0], glyphset_bytes[1], glyphset_bytes[2], glyphset_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.glyphcmds.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.glyphcmds, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != COMPOSITE_GLYPHS16_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (mask_format, remaining) = Pictformat::try_parse(remaining)?; let (glyphset, remaining) = Glyphset::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let (glyphcmds, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(CompositeGlyphs16Request { op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds: Cow::Borrowed(glyphcmds), }) } /// Clone all borrowed data in this CompositeGlyphs16Request. pub fn into_owned(self) -> CompositeGlyphs16Request<'static> { CompositeGlyphs16Request { op: self.op, src: self.src, dst: self.dst, mask_format: self.mask_format, glyphset: self.glyphset, src_x: self.src_x, src_y: self.src_y, glyphcmds: Cow::Owned(self.glyphcmds.into_owned()), } } } impl<'input> Request for CompositeGlyphs16Request<'input> { type Reply = (); } pub fn composite_glyphs16<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, glyphset: Glyphset, src_x: i16, src_y: i16, glyphcmds: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CompositeGlyphs16Request { op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds: Cow::Borrowed(glyphcmds), }; request0.send(conn) } /// Opcode for the CompositeGlyphs32 request pub const COMPOSITE_GLYPHS32_REQUEST: u8 = 25; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CompositeGlyphs32Request<'input> { pub op: PictOp, pub src: Picture, pub dst: Picture, pub mask_format: Pictformat, pub glyphset: Glyphset, pub src_x: i16, pub src_y: i16, pub glyphcmds: Cow<'input, [u8]>, } impl<'input> CompositeGlyphs32Request<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let src_bytes = self.src.serialize(); let dst_bytes = self.dst.serialize(); let mask_format_bytes = self.mask_format.serialize(); let glyphset_bytes = self.glyphset.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let mut request0 = vec![ extension_information.major_opcode, COMPOSITE_GLYPHS32_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], mask_format_bytes[0], mask_format_bytes[1], mask_format_bytes[2], mask_format_bytes[3], glyphset_bytes[0], glyphset_bytes[1], glyphset_bytes[2], glyphset_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.glyphcmds.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.glyphcmds, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != COMPOSITE_GLYPHS32_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (src, remaining) = Picture::try_parse(remaining)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (mask_format, remaining) = Pictformat::try_parse(remaining)?; let (glyphset, remaining) = Glyphset::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let (glyphcmds, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(CompositeGlyphs32Request { op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds: Cow::Borrowed(glyphcmds), }) } /// Clone all borrowed data in this CompositeGlyphs32Request. pub fn into_owned(self) -> CompositeGlyphs32Request<'static> { CompositeGlyphs32Request { op: self.op, src: self.src, dst: self.dst, mask_format: self.mask_format, glyphset: self.glyphset, src_x: self.src_x, src_y: self.src_y, glyphcmds: Cow::Owned(self.glyphcmds.into_owned()), } } } impl<'input> Request for CompositeGlyphs32Request<'input> { type Reply = (); } pub fn composite_glyphs32<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, glyphset: Glyphset, src_x: i16, src_y: i16, glyphcmds: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CompositeGlyphs32Request { op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds: Cow::Borrowed(glyphcmds), }; request0.send(conn) } /// Opcode for the FillRectangles request pub const FILL_RECTANGLES_REQUEST: u8 = 26; #[derive(Debug, Clone, PartialEq, Eq)] pub struct FillRectanglesRequest<'input> { pub op: PictOp, pub dst: Picture, pub color: Color, pub rects: Cow<'input, [xproto::Rectangle]>, } impl<'input> FillRectanglesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let op_bytes = u8::from(self.op).serialize(); let dst_bytes = self.dst.serialize(); let color_bytes = self.color.serialize(); let mut request0 = vec![ extension_information.major_opcode, FILL_RECTANGLES_REQUEST, 0, 0, op_bytes[0], 0, 0, 0, dst_bytes[0], dst_bytes[1], dst_bytes[2], dst_bytes[3], color_bytes[0], color_bytes[1], color_bytes[2], color_bytes[3], color_bytes[4], color_bytes[5], color_bytes[6], color_bytes[7], ]; let length_so_far = length_so_far + request0.len(); let rects_bytes = self.rects.serialize(); let length_so_far = length_so_far + rects_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), rects_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != FILL_RECTANGLES_REQUEST { return Err(ParseError::InvalidValue); } let (op, remaining) = u8::try_parse(value)?; let op = op.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (dst, remaining) = Picture::try_parse(remaining)?; let (color, remaining) = Color::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut rects = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = xproto::Rectangle::try_parse(remaining)?; remaining = new_remaining; rects.push(v); } let _ = remaining; Ok(FillRectanglesRequest { op, dst, color, rects: Cow::Owned(rects), }) } /// Clone all borrowed data in this FillRectanglesRequest. pub fn into_owned(self) -> FillRectanglesRequest<'static> { FillRectanglesRequest { op: self.op, dst: self.dst, color: self.color, rects: Cow::Owned(self.rects.into_owned()), } } } impl<'input> Request for FillRectanglesRequest<'input> { type Reply = (); } pub fn fill_rectangles<'c, 'input, Conn>(conn: &'c Conn, op: PictOp, dst: Picture, color: Color, rects: &'input [xproto::Rectangle]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FillRectanglesRequest { op, dst, color, rects: Cow::Borrowed(rects), }; request0.send(conn) } /// Opcode for the CreateCursor request pub const CREATE_CURSOR_REQUEST: u8 = 27; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateCursorRequest { pub cid: xproto::Cursor, pub source: Picture, pub x: u16, pub y: u16, } impl CreateCursorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cid_bytes = self.cid.serialize(); let source_bytes = self.source.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CURSOR_REQUEST, 0, 0, cid_bytes[0], cid_bytes[1], cid_bytes[2], cid_bytes[3], source_bytes[0], source_bytes[1], source_bytes[2], source_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_CURSOR_REQUEST { return Err(ParseError::InvalidValue); } let (cid, remaining) = xproto::Cursor::try_parse(value)?; let (source, remaining) = Picture::try_parse(remaining)?; let (x, remaining) = u16::try_parse(remaining)?; let (y, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(CreateCursorRequest { cid, source, x, y, }) } } impl Request for CreateCursorRequest { type Reply = (); } pub fn create_cursor(conn: &Conn, cid: xproto::Cursor, source: Picture, x: u16, y: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateCursorRequest { cid, source, x, y, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Transform { pub matrix11: Fixed, pub matrix12: Fixed, pub matrix13: Fixed, pub matrix21: Fixed, pub matrix22: Fixed, pub matrix23: Fixed, pub matrix31: Fixed, pub matrix32: Fixed, pub matrix33: Fixed, } impl TryParse for Transform { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (matrix11, remaining) = Fixed::try_parse(remaining)?; let (matrix12, remaining) = Fixed::try_parse(remaining)?; let (matrix13, remaining) = Fixed::try_parse(remaining)?; let (matrix21, remaining) = Fixed::try_parse(remaining)?; let (matrix22, remaining) = Fixed::try_parse(remaining)?; let (matrix23, remaining) = Fixed::try_parse(remaining)?; let (matrix31, remaining) = Fixed::try_parse(remaining)?; let (matrix32, remaining) = Fixed::try_parse(remaining)?; let (matrix33, remaining) = Fixed::try_parse(remaining)?; let result = Transform { matrix11, matrix12, matrix13, matrix21, matrix22, matrix23, matrix31, matrix32, matrix33 }; Ok((result, remaining)) } } impl Serialize for Transform { type Bytes = [u8; 36]; fn serialize(&self) -> [u8; 36] { let matrix11_bytes = self.matrix11.serialize(); let matrix12_bytes = self.matrix12.serialize(); let matrix13_bytes = self.matrix13.serialize(); let matrix21_bytes = self.matrix21.serialize(); let matrix22_bytes = self.matrix22.serialize(); let matrix23_bytes = self.matrix23.serialize(); let matrix31_bytes = self.matrix31.serialize(); let matrix32_bytes = self.matrix32.serialize(); let matrix33_bytes = self.matrix33.serialize(); [ matrix11_bytes[0], matrix11_bytes[1], matrix11_bytes[2], matrix11_bytes[3], matrix12_bytes[0], matrix12_bytes[1], matrix12_bytes[2], matrix12_bytes[3], matrix13_bytes[0], matrix13_bytes[1], matrix13_bytes[2], matrix13_bytes[3], matrix21_bytes[0], matrix21_bytes[1], matrix21_bytes[2], matrix21_bytes[3], matrix22_bytes[0], matrix22_bytes[1], matrix22_bytes[2], matrix22_bytes[3], matrix23_bytes[0], matrix23_bytes[1], matrix23_bytes[2], matrix23_bytes[3], matrix31_bytes[0], matrix31_bytes[1], matrix31_bytes[2], matrix31_bytes[3], matrix32_bytes[0], matrix32_bytes[1], matrix32_bytes[2], matrix32_bytes[3], matrix33_bytes[0], matrix33_bytes[1], matrix33_bytes[2], matrix33_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(36); self.matrix11.serialize_into(bytes); self.matrix12.serialize_into(bytes); self.matrix13.serialize_into(bytes); self.matrix21.serialize_into(bytes); self.matrix22.serialize_into(bytes); self.matrix23.serialize_into(bytes); self.matrix31.serialize_into(bytes); self.matrix32.serialize_into(bytes); self.matrix33.serialize_into(bytes); } } /// Opcode for the SetPictureTransform request pub const SET_PICTURE_TRANSFORM_REQUEST: u8 = 28; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetPictureTransformRequest { pub picture: Picture, pub transform: Transform, } impl SetPictureTransformRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let transform_bytes = self.transform.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PICTURE_TRANSFORM_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], transform_bytes[0], transform_bytes[1], transform_bytes[2], transform_bytes[3], transform_bytes[4], transform_bytes[5], transform_bytes[6], transform_bytes[7], transform_bytes[8], transform_bytes[9], transform_bytes[10], transform_bytes[11], transform_bytes[12], transform_bytes[13], transform_bytes[14], transform_bytes[15], transform_bytes[16], transform_bytes[17], transform_bytes[18], transform_bytes[19], transform_bytes[20], transform_bytes[21], transform_bytes[22], transform_bytes[23], transform_bytes[24], transform_bytes[25], transform_bytes[26], transform_bytes[27], transform_bytes[28], transform_bytes[29], transform_bytes[30], transform_bytes[31], transform_bytes[32], transform_bytes[33], transform_bytes[34], transform_bytes[35], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_PICTURE_TRANSFORM_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (transform, remaining) = Transform::try_parse(remaining)?; let _ = remaining; Ok(SetPictureTransformRequest { picture, transform, }) } } impl Request for SetPictureTransformRequest { type Reply = (); } pub fn set_picture_transform(conn: &Conn, picture: Picture, transform: Transform) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPictureTransformRequest { picture, transform, }; request0.send(conn) } /// Opcode for the QueryFilters request pub const QUERY_FILTERS_REQUEST: u8 = 29; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryFiltersRequest { pub drawable: xproto::Drawable, } impl QueryFiltersRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_FILTERS_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_FILTERS_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let _ = remaining; Ok(QueryFiltersRequest { drawable, }) } } impl Request for QueryFiltersRequest { type Reply = QueryFiltersReply; } pub fn query_filters(conn: &Conn, drawable: xproto::Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryFiltersRequest { drawable, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryFiltersReply { pub sequence: u16, pub length: u32, pub aliases: Vec, pub filters: Vec, } impl TryParse for QueryFiltersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_aliases, remaining) = u32::try_parse(remaining)?; let (num_filters, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (aliases, remaining) = crate::x11_utils::parse_list::(remaining, num_aliases.try_to_usize()?)?; let (filters, remaining) = crate::x11_utils::parse_list::(remaining, num_filters.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryFiltersReply { sequence, length, aliases, filters }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryFiltersReply { /// Get the value of the `num_aliases` field. /// /// The `num_aliases` field is used as the length field of the `aliases` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_aliases(&self) -> u32 { self.aliases.len() .try_into().unwrap() } /// Get the value of the `num_filters` field. /// /// The `num_filters` field is used as the length field of the `filters` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_filters(&self) -> u32 { self.filters.len() .try_into().unwrap() } } /// Opcode for the SetPictureFilter request pub const SET_PICTURE_FILTER_REQUEST: u8 = 30; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetPictureFilterRequest<'input> { pub picture: Picture, pub filter: Cow<'input, [u8]>, pub values: Cow<'input, [Fixed]>, } impl<'input> SetPictureFilterRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let filter_len = u16::try_from(self.filter.len()).expect("`filter` has too many elements"); let filter_len_bytes = filter_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PICTURE_FILTER_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], filter_len_bytes[0], filter_len_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.filter.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); let values_bytes = self.values.serialize(); let length_so_far = length_so_far + values_bytes.len(); let padding1 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding1.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.filter, padding0.into(), values_bytes.into(), padding1.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_PICTURE_FILTER_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (filter_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (filter, remaining) = crate::x11_utils::parse_u8_list(remaining, filter_len.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut values = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Fixed::try_parse(remaining)?; remaining = new_remaining; values.push(v); } let _ = remaining; Ok(SetPictureFilterRequest { picture, filter: Cow::Borrowed(filter), values: Cow::Owned(values), }) } /// Clone all borrowed data in this SetPictureFilterRequest. pub fn into_owned(self) -> SetPictureFilterRequest<'static> { SetPictureFilterRequest { picture: self.picture, filter: Cow::Owned(self.filter.into_owned()), values: Cow::Owned(self.values.into_owned()), } } } impl<'input> Request for SetPictureFilterRequest<'input> { type Reply = (); } pub fn set_picture_filter<'c, 'input, Conn>(conn: &'c Conn, picture: Picture, filter: &'input [u8], values: &'input [Fixed]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPictureFilterRequest { picture, filter: Cow::Borrowed(filter), values: Cow::Borrowed(values), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Animcursorelt { pub cursor: xproto::Cursor, pub delay: u32, } impl TryParse for Animcursorelt { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?; let (delay, remaining) = u32::try_parse(remaining)?; let result = Animcursorelt { cursor, delay }; Ok((result, remaining)) } } impl Serialize for Animcursorelt { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let cursor_bytes = self.cursor.serialize(); let delay_bytes = self.delay.serialize(); [ cursor_bytes[0], cursor_bytes[1], cursor_bytes[2], cursor_bytes[3], delay_bytes[0], delay_bytes[1], delay_bytes[2], delay_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.cursor.serialize_into(bytes); self.delay.serialize_into(bytes); } } /// Opcode for the CreateAnimCursor request pub const CREATE_ANIM_CURSOR_REQUEST: u8 = 31; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateAnimCursorRequest<'input> { pub cid: xproto::Cursor, pub cursors: Cow<'input, [Animcursorelt]>, } impl<'input> CreateAnimCursorRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cid_bytes = self.cid.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_ANIM_CURSOR_REQUEST, 0, 0, cid_bytes[0], cid_bytes[1], cid_bytes[2], cid_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let cursors_bytes = self.cursors.serialize(); let length_so_far = length_so_far + cursors_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), cursors_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_ANIM_CURSOR_REQUEST { return Err(ParseError::InvalidValue); } let (cid, remaining) = xproto::Cursor::try_parse(value)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut cursors = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Animcursorelt::try_parse(remaining)?; remaining = new_remaining; cursors.push(v); } let _ = remaining; Ok(CreateAnimCursorRequest { cid, cursors: Cow::Owned(cursors), }) } /// Clone all borrowed data in this CreateAnimCursorRequest. pub fn into_owned(self) -> CreateAnimCursorRequest<'static> { CreateAnimCursorRequest { cid: self.cid, cursors: Cow::Owned(self.cursors.into_owned()), } } } impl<'input> Request for CreateAnimCursorRequest<'input> { type Reply = (); } pub fn create_anim_cursor<'c, 'input, Conn>(conn: &'c Conn, cid: xproto::Cursor, cursors: &'input [Animcursorelt]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateAnimCursorRequest { cid, cursors: Cow::Borrowed(cursors), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Spanfix { pub l: Fixed, pub r: Fixed, pub y: Fixed, } impl TryParse for Spanfix { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (l, remaining) = Fixed::try_parse(remaining)?; let (r, remaining) = Fixed::try_parse(remaining)?; let (y, remaining) = Fixed::try_parse(remaining)?; let result = Spanfix { l, r, y }; Ok((result, remaining)) } } impl Serialize for Spanfix { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let l_bytes = self.l.serialize(); let r_bytes = self.r.serialize(); let y_bytes = self.y.serialize(); [ l_bytes[0], l_bytes[1], l_bytes[2], l_bytes[3], r_bytes[0], r_bytes[1], r_bytes[2], r_bytes[3], y_bytes[0], y_bytes[1], y_bytes[2], y_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.l.serialize_into(bytes); self.r.serialize_into(bytes); self.y.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Trap { pub top: Spanfix, pub bot: Spanfix, } impl TryParse for Trap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (top, remaining) = Spanfix::try_parse(remaining)?; let (bot, remaining) = Spanfix::try_parse(remaining)?; let result = Trap { top, bot }; Ok((result, remaining)) } } impl Serialize for Trap { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let top_bytes = self.top.serialize(); let bot_bytes = self.bot.serialize(); [ top_bytes[0], top_bytes[1], top_bytes[2], top_bytes[3], top_bytes[4], top_bytes[5], top_bytes[6], top_bytes[7], top_bytes[8], top_bytes[9], top_bytes[10], top_bytes[11], bot_bytes[0], bot_bytes[1], bot_bytes[2], bot_bytes[3], bot_bytes[4], bot_bytes[5], bot_bytes[6], bot_bytes[7], bot_bytes[8], bot_bytes[9], bot_bytes[10], bot_bytes[11], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.top.serialize_into(bytes); self.bot.serialize_into(bytes); } } /// Opcode for the AddTraps request pub const ADD_TRAPS_REQUEST: u8 = 32; #[derive(Debug, Clone, PartialEq, Eq)] pub struct AddTrapsRequest<'input> { pub picture: Picture, pub x_off: i16, pub y_off: i16, pub traps: Cow<'input, [Trap]>, } impl<'input> AddTrapsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let x_off_bytes = self.x_off.serialize(); let y_off_bytes = self.y_off.serialize(); let mut request0 = vec![ extension_information.major_opcode, ADD_TRAPS_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], x_off_bytes[0], x_off_bytes[1], y_off_bytes[0], y_off_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let traps_bytes = self.traps.serialize(); let length_so_far = length_so_far + traps_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), traps_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != ADD_TRAPS_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (x_off, remaining) = i16::try_parse(remaining)?; let (y_off, remaining) = i16::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut traps = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Trap::try_parse(remaining)?; remaining = new_remaining; traps.push(v); } let _ = remaining; Ok(AddTrapsRequest { picture, x_off, y_off, traps: Cow::Owned(traps), }) } /// Clone all borrowed data in this AddTrapsRequest. pub fn into_owned(self) -> AddTrapsRequest<'static> { AddTrapsRequest { picture: self.picture, x_off: self.x_off, y_off: self.y_off, traps: Cow::Owned(self.traps.into_owned()), } } } impl<'input> Request for AddTrapsRequest<'input> { type Reply = (); } pub fn add_traps<'c, 'input, Conn>(conn: &'c Conn, picture: Picture, x_off: i16, y_off: i16, traps: &'input [Trap]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AddTrapsRequest { picture, x_off, y_off, traps: Cow::Borrowed(traps), }; request0.send(conn) } /// Opcode for the CreateSolidFill request pub const CREATE_SOLID_FILL_REQUEST: u8 = 33; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateSolidFillRequest { pub picture: Picture, pub color: Color, } impl CreateSolidFillRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let color_bytes = self.color.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_SOLID_FILL_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], color_bytes[0], color_bytes[1], color_bytes[2], color_bytes[3], color_bytes[4], color_bytes[5], color_bytes[6], color_bytes[7], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_SOLID_FILL_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (color, remaining) = Color::try_parse(remaining)?; let _ = remaining; Ok(CreateSolidFillRequest { picture, color, }) } } impl Request for CreateSolidFillRequest { type Reply = (); } pub fn create_solid_fill(conn: &Conn, picture: Picture, color: Color) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateSolidFillRequest { picture, color, }; request0.send(conn) } /// Opcode for the CreateLinearGradient request pub const CREATE_LINEAR_GRADIENT_REQUEST: u8 = 34; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateLinearGradientRequest<'input> { pub picture: Picture, pub p1: Pointfix, pub p2: Pointfix, pub stops: Cow<'input, [Fixed]>, pub colors: Cow<'input, [Color]>, } impl<'input> CreateLinearGradientRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let p1_bytes = self.p1.serialize(); let p2_bytes = self.p2.serialize(); let num_stops = u32::try_from(self.stops.len()).expect("`stops` has too many elements"); let num_stops_bytes = num_stops.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_LINEAR_GRADIENT_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], p1_bytes[0], p1_bytes[1], p1_bytes[2], p1_bytes[3], p1_bytes[4], p1_bytes[5], p1_bytes[6], p1_bytes[7], p2_bytes[0], p2_bytes[1], p2_bytes[2], p2_bytes[3], p2_bytes[4], p2_bytes[5], p2_bytes[6], p2_bytes[7], num_stops_bytes[0], num_stops_bytes[1], num_stops_bytes[2], num_stops_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let stops_bytes = self.stops.serialize(); let length_so_far = length_so_far + stops_bytes.len(); assert_eq!(self.colors.len(), usize::try_from(num_stops).unwrap(), "`colors` has an incorrect length"); let colors_bytes = self.colors.serialize(); let length_so_far = length_so_far + colors_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), stops_bytes.into(), colors_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_LINEAR_GRADIENT_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (p1, remaining) = Pointfix::try_parse(remaining)?; let (p2, remaining) = Pointfix::try_parse(remaining)?; let (num_stops, remaining) = u32::try_parse(remaining)?; let (stops, remaining) = crate::x11_utils::parse_list::(remaining, num_stops.try_to_usize()?)?; let (colors, remaining) = crate::x11_utils::parse_list::(remaining, num_stops.try_to_usize()?)?; let _ = remaining; Ok(CreateLinearGradientRequest { picture, p1, p2, stops: Cow::Owned(stops), colors: Cow::Owned(colors), }) } /// Clone all borrowed data in this CreateLinearGradientRequest. pub fn into_owned(self) -> CreateLinearGradientRequest<'static> { CreateLinearGradientRequest { picture: self.picture, p1: self.p1, p2: self.p2, stops: Cow::Owned(self.stops.into_owned()), colors: Cow::Owned(self.colors.into_owned()), } } } impl<'input> Request for CreateLinearGradientRequest<'input> { type Reply = (); } pub fn create_linear_gradient<'c, 'input, Conn>(conn: &'c Conn, picture: Picture, p1: Pointfix, p2: Pointfix, stops: &'input [Fixed], colors: &'input [Color]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateLinearGradientRequest { picture, p1, p2, stops: Cow::Borrowed(stops), colors: Cow::Borrowed(colors), }; request0.send(conn) } /// Opcode for the CreateRadialGradient request pub const CREATE_RADIAL_GRADIENT_REQUEST: u8 = 35; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateRadialGradientRequest<'input> { pub picture: Picture, pub inner: Pointfix, pub outer: Pointfix, pub inner_radius: Fixed, pub outer_radius: Fixed, pub stops: Cow<'input, [Fixed]>, pub colors: Cow<'input, [Color]>, } impl<'input> CreateRadialGradientRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let inner_bytes = self.inner.serialize(); let outer_bytes = self.outer.serialize(); let inner_radius_bytes = self.inner_radius.serialize(); let outer_radius_bytes = self.outer_radius.serialize(); let num_stops = u32::try_from(self.stops.len()).expect("`stops` has too many elements"); let num_stops_bytes = num_stops.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_RADIAL_GRADIENT_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], inner_bytes[0], inner_bytes[1], inner_bytes[2], inner_bytes[3], inner_bytes[4], inner_bytes[5], inner_bytes[6], inner_bytes[7], outer_bytes[0], outer_bytes[1], outer_bytes[2], outer_bytes[3], outer_bytes[4], outer_bytes[5], outer_bytes[6], outer_bytes[7], inner_radius_bytes[0], inner_radius_bytes[1], inner_radius_bytes[2], inner_radius_bytes[3], outer_radius_bytes[0], outer_radius_bytes[1], outer_radius_bytes[2], outer_radius_bytes[3], num_stops_bytes[0], num_stops_bytes[1], num_stops_bytes[2], num_stops_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let stops_bytes = self.stops.serialize(); let length_so_far = length_so_far + stops_bytes.len(); assert_eq!(self.colors.len(), usize::try_from(num_stops).unwrap(), "`colors` has an incorrect length"); let colors_bytes = self.colors.serialize(); let length_so_far = length_so_far + colors_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), stops_bytes.into(), colors_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_RADIAL_GRADIENT_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (inner, remaining) = Pointfix::try_parse(remaining)?; let (outer, remaining) = Pointfix::try_parse(remaining)?; let (inner_radius, remaining) = Fixed::try_parse(remaining)?; let (outer_radius, remaining) = Fixed::try_parse(remaining)?; let (num_stops, remaining) = u32::try_parse(remaining)?; let (stops, remaining) = crate::x11_utils::parse_list::(remaining, num_stops.try_to_usize()?)?; let (colors, remaining) = crate::x11_utils::parse_list::(remaining, num_stops.try_to_usize()?)?; let _ = remaining; Ok(CreateRadialGradientRequest { picture, inner, outer, inner_radius, outer_radius, stops: Cow::Owned(stops), colors: Cow::Owned(colors), }) } /// Clone all borrowed data in this CreateRadialGradientRequest. pub fn into_owned(self) -> CreateRadialGradientRequest<'static> { CreateRadialGradientRequest { picture: self.picture, inner: self.inner, outer: self.outer, inner_radius: self.inner_radius, outer_radius: self.outer_radius, stops: Cow::Owned(self.stops.into_owned()), colors: Cow::Owned(self.colors.into_owned()), } } } impl<'input> Request for CreateRadialGradientRequest<'input> { type Reply = (); } pub fn create_radial_gradient<'c, 'input, Conn>(conn: &'c Conn, picture: Picture, inner: Pointfix, outer: Pointfix, inner_radius: Fixed, outer_radius: Fixed, stops: &'input [Fixed], colors: &'input [Color]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRadialGradientRequest { picture, inner, outer, inner_radius, outer_radius, stops: Cow::Borrowed(stops), colors: Cow::Borrowed(colors), }; request0.send(conn) } /// Opcode for the CreateConicalGradient request pub const CREATE_CONICAL_GRADIENT_REQUEST: u8 = 36; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateConicalGradientRequest<'input> { pub picture: Picture, pub center: Pointfix, pub angle: Fixed, pub stops: Cow<'input, [Fixed]>, pub colors: Cow<'input, [Color]>, } impl<'input> CreateConicalGradientRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let center_bytes = self.center.serialize(); let angle_bytes = self.angle.serialize(); let num_stops = u32::try_from(self.stops.len()).expect("`stops` has too many elements"); let num_stops_bytes = num_stops.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CONICAL_GRADIENT_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], center_bytes[0], center_bytes[1], center_bytes[2], center_bytes[3], center_bytes[4], center_bytes[5], center_bytes[6], center_bytes[7], angle_bytes[0], angle_bytes[1], angle_bytes[2], angle_bytes[3], num_stops_bytes[0], num_stops_bytes[1], num_stops_bytes[2], num_stops_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let stops_bytes = self.stops.serialize(); let length_so_far = length_so_far + stops_bytes.len(); assert_eq!(self.colors.len(), usize::try_from(num_stops).unwrap(), "`colors` has an incorrect length"); let colors_bytes = self.colors.serialize(); let length_so_far = length_so_far + colors_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), stops_bytes.into(), colors_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_CONICAL_GRADIENT_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = Picture::try_parse(value)?; let (center, remaining) = Pointfix::try_parse(remaining)?; let (angle, remaining) = Fixed::try_parse(remaining)?; let (num_stops, remaining) = u32::try_parse(remaining)?; let (stops, remaining) = crate::x11_utils::parse_list::(remaining, num_stops.try_to_usize()?)?; let (colors, remaining) = crate::x11_utils::parse_list::(remaining, num_stops.try_to_usize()?)?; let _ = remaining; Ok(CreateConicalGradientRequest { picture, center, angle, stops: Cow::Owned(stops), colors: Cow::Owned(colors), }) } /// Clone all borrowed data in this CreateConicalGradientRequest. pub fn into_owned(self) -> CreateConicalGradientRequest<'static> { CreateConicalGradientRequest { picture: self.picture, center: self.center, angle: self.angle, stops: Cow::Owned(self.stops.into_owned()), colors: Cow::Owned(self.colors.into_owned()), } } } impl<'input> Request for CreateConicalGradientRequest<'input> { type Reply = (); } pub fn create_conical_gradient<'c, 'input, Conn>(conn: &'c Conn, picture: Picture, center: Pointfix, angle: Fixed, stops: &'input [Fixed], colors: &'input [Color]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateConicalGradientRequest { picture, center, angle, stops: Cow::Borrowed(stops), colors: Cow::Borrowed(colors), }; request0.send(conn) } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn render_query_version(&self, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> { query_version(self, client_major_version, client_minor_version) } fn render_query_pict_formats(&self) -> Result, ConnectionError> { query_pict_formats(self) } fn render_query_pict_index_values(&self, format: Pictformat) -> Result, ConnectionError> { query_pict_index_values(self, format) } fn render_create_picture<'c, 'input>(&'c self, pid: Picture, drawable: xproto::Drawable, format: Pictformat, value_list: &'input CreatePictureAux) -> Result, ConnectionError> { create_picture(self, pid, drawable, format, value_list) } fn render_change_picture<'c, 'input>(&'c self, picture: Picture, value_list: &'input ChangePictureAux) -> Result, ConnectionError> { change_picture(self, picture, value_list) } fn render_set_picture_clip_rectangles<'c, 'input>(&'c self, picture: Picture, clip_x_origin: i16, clip_y_origin: i16, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> { set_picture_clip_rectangles(self, picture, clip_x_origin, clip_y_origin, rectangles) } fn render_free_picture(&self, picture: Picture) -> Result, ConnectionError> { free_picture(self, picture) } fn render_composite(&self, op: PictOp, src: Picture, mask: A, dst: Picture, src_x: i16, src_y: i16, mask_x: i16, mask_y: i16, dst_x: i16, dst_y: i16, width: u16, height: u16) -> Result, ConnectionError> where A: Into, { composite(self, op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height) } fn render_trapezoids<'c, 'input>(&'c self, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, traps: &'input [Trapezoid]) -> Result, ConnectionError> { trapezoids(self, op, src, dst, mask_format, src_x, src_y, traps) } fn render_triangles<'c, 'input>(&'c self, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, triangles: &'input [Triangle]) -> Result, ConnectionError> { self::triangles(self, op, src, dst, mask_format, src_x, src_y, triangles) } fn render_tri_strip<'c, 'input>(&'c self, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, points: &'input [Pointfix]) -> Result, ConnectionError> { tri_strip(self, op, src, dst, mask_format, src_x, src_y, points) } fn render_tri_fan<'c, 'input>(&'c self, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, src_x: i16, src_y: i16, points: &'input [Pointfix]) -> Result, ConnectionError> { tri_fan(self, op, src, dst, mask_format, src_x, src_y, points) } fn render_create_glyph_set(&self, gsid: Glyphset, format: Pictformat) -> Result, ConnectionError> { create_glyph_set(self, gsid, format) } fn render_reference_glyph_set(&self, gsid: Glyphset, existing: Glyphset) -> Result, ConnectionError> { reference_glyph_set(self, gsid, existing) } fn render_free_glyph_set(&self, glyphset: Glyphset) -> Result, ConnectionError> { free_glyph_set(self, glyphset) } fn render_add_glyphs<'c, 'input>(&'c self, glyphset: Glyphset, glyphids: &'input [u32], glyphs: &'input [Glyphinfo], data: &'input [u8]) -> Result, ConnectionError> { add_glyphs(self, glyphset, glyphids, glyphs, data) } fn render_free_glyphs<'c, 'input>(&'c self, glyphset: Glyphset, glyphs: &'input [Glyph]) -> Result, ConnectionError> { free_glyphs(self, glyphset, glyphs) } fn render_composite_glyphs8<'c, 'input>(&'c self, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, glyphset: Glyphset, src_x: i16, src_y: i16, glyphcmds: &'input [u8]) -> Result, ConnectionError> { composite_glyphs8(self, op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds) } fn render_composite_glyphs16<'c, 'input>(&'c self, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, glyphset: Glyphset, src_x: i16, src_y: i16, glyphcmds: &'input [u8]) -> Result, ConnectionError> { composite_glyphs16(self, op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds) } fn render_composite_glyphs32<'c, 'input>(&'c self, op: PictOp, src: Picture, dst: Picture, mask_format: Pictformat, glyphset: Glyphset, src_x: i16, src_y: i16, glyphcmds: &'input [u8]) -> Result, ConnectionError> { composite_glyphs32(self, op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds) } fn render_fill_rectangles<'c, 'input>(&'c self, op: PictOp, dst: Picture, color: Color, rects: &'input [xproto::Rectangle]) -> Result, ConnectionError> { fill_rectangles(self, op, dst, color, rects) } fn render_create_cursor(&self, cid: xproto::Cursor, source: Picture, x: u16, y: u16) -> Result, ConnectionError> { create_cursor(self, cid, source, x, y) } fn render_set_picture_transform(&self, picture: Picture, transform: Transform) -> Result, ConnectionError> { set_picture_transform(self, picture, transform) } fn render_query_filters(&self, drawable: xproto::Drawable) -> Result, ConnectionError> { query_filters(self, drawable) } fn render_set_picture_filter<'c, 'input>(&'c self, picture: Picture, filter: &'input [u8], values: &'input [Fixed]) -> Result, ConnectionError> { set_picture_filter(self, picture, filter, values) } fn render_create_anim_cursor<'c, 'input>(&'c self, cid: xproto::Cursor, cursors: &'input [Animcursorelt]) -> Result, ConnectionError> { create_anim_cursor(self, cid, cursors) } fn render_add_traps<'c, 'input>(&'c self, picture: Picture, x_off: i16, y_off: i16, traps: &'input [Trap]) -> Result, ConnectionError> { add_traps(self, picture, x_off, y_off, traps) } fn render_create_solid_fill(&self, picture: Picture, color: Color) -> Result, ConnectionError> { create_solid_fill(self, picture, color) } fn render_create_linear_gradient<'c, 'input>(&'c self, picture: Picture, p1: Pointfix, p2: Pointfix, stops: &'input [Fixed], colors: &'input [Color]) -> Result, ConnectionError> { create_linear_gradient(self, picture, p1, p2, stops, colors) } fn render_create_radial_gradient<'c, 'input>(&'c self, picture: Picture, inner: Pointfix, outer: Pointfix, inner_radius: Fixed, outer_radius: Fixed, stops: &'input [Fixed], colors: &'input [Color]) -> Result, ConnectionError> { create_radial_gradient(self, picture, inner, outer, inner_radius, outer_radius, stops, colors) } fn render_create_conical_gradient<'c, 'input>(&'c self, picture: Picture, center: Pointfix, angle: Fixed, stops: &'input [Fixed], colors: &'input [Color]) -> Result, ConnectionError> { create_conical_gradient(self, picture, center, angle, stops, colors) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/res.rs010064400017500001750000001154061402220031600144220ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Res` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "X-Resource"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 2); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Client { pub resource_base: u32, pub resource_mask: u32, } impl TryParse for Client { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (resource_base, remaining) = u32::try_parse(remaining)?; let (resource_mask, remaining) = u32::try_parse(remaining)?; let result = Client { resource_base, resource_mask }; Ok((result, remaining)) } } impl Serialize for Client { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let resource_base_bytes = self.resource_base.serialize(); let resource_mask_bytes = self.resource_mask.serialize(); [ resource_base_bytes[0], resource_base_bytes[1], resource_base_bytes[2], resource_base_bytes[3], resource_mask_bytes[0], resource_mask_bytes[1], resource_mask_bytes[2], resource_mask_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.resource_base.serialize_into(bytes); self.resource_mask.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Type { pub resource_type: xproto::Atom, pub count: u32, } impl TryParse for Type { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (resource_type, remaining) = xproto::Atom::try_parse(remaining)?; let (count, remaining) = u32::try_parse(remaining)?; let result = Type { resource_type, count }; Ok((result, remaining)) } } impl Serialize for Type { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let resource_type_bytes = self.resource_type.serialize(); let count_bytes = self.count.serialize(); [ resource_type_bytes[0], resource_type_bytes[1], resource_type_bytes[2], resource_type_bytes[3], count_bytes[0], count_bytes[1], count_bytes[2], count_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.resource_type.serialize_into(bytes); self.count.serialize_into(bytes); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ClientIdMask(u8); impl ClientIdMask { pub const CLIENT_XID: Self = Self(1 << 0); pub const LOCAL_CLIENT_PID: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: ClientIdMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ClientIdMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ClientIdMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ClientIdMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ClientIdMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ClientIdMask) -> Self { Some(u32::from(input.0)) } } impl From for ClientIdMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ClientIdMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CLIENT_XID.0.into(), "CLIENT_XID", "ClientXID"), (Self::LOCAL_CLIENT_PID.0.into(), "LOCAL_CLIENT_PID", "LocalClientPID"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ClientIdMask, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ClientIdSpec { pub client: u32, pub mask: u32, } impl TryParse for ClientIdSpec { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (client, remaining) = u32::try_parse(remaining)?; let (mask, remaining) = u32::try_parse(remaining)?; let result = ClientIdSpec { client, mask }; Ok((result, remaining)) } } impl Serialize for ClientIdSpec { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let client_bytes = self.client.serialize(); let mask_bytes = self.mask.serialize(); [ client_bytes[0], client_bytes[1], client_bytes[2], client_bytes[3], mask_bytes[0], mask_bytes[1], mask_bytes[2], mask_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.client.serialize_into(bytes); self.mask.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ClientIdValue { pub spec: ClientIdSpec, pub value: Vec, } impl TryParse for ClientIdValue { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (spec, remaining) = ClientIdSpec::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (value, remaining) = crate::x11_utils::parse_list::(remaining, length.checked_div(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let result = ClientIdValue { spec, value }; Ok((result, remaining)) } } impl Serialize for ClientIdValue { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.spec.serialize_into(bytes); let length = u32::try_from(self.value.len()).ok().and_then(|len| len.checked_mul(4)).expect("`value` has too many elements"); length.serialize_into(bytes); self.value.serialize_into(bytes); } } impl ClientIdValue { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `value` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.value.len() .checked_mul(4).unwrap() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ResourceIdSpec { pub resource: u32, pub type_: u32, } impl TryParse for ResourceIdSpec { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (resource, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let result = ResourceIdSpec { resource, type_ }; Ok((result, remaining)) } } impl Serialize for ResourceIdSpec { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let resource_bytes = self.resource.serialize(); let type_bytes = self.type_.serialize(); [ resource_bytes[0], resource_bytes[1], resource_bytes[2], resource_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.resource.serialize_into(bytes); self.type_.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ResourceSizeSpec { pub spec: ResourceIdSpec, pub bytes: u32, pub ref_count: u32, pub use_count: u32, } impl TryParse for ResourceSizeSpec { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (spec, remaining) = ResourceIdSpec::try_parse(remaining)?; let (bytes, remaining) = u32::try_parse(remaining)?; let (ref_count, remaining) = u32::try_parse(remaining)?; let (use_count, remaining) = u32::try_parse(remaining)?; let result = ResourceSizeSpec { spec, bytes, ref_count, use_count }; Ok((result, remaining)) } } impl Serialize for ResourceSizeSpec { type Bytes = [u8; 20]; fn serialize(&self) -> [u8; 20] { let spec_bytes = self.spec.serialize(); let bytes_bytes = self.bytes.serialize(); let ref_count_bytes = self.ref_count.serialize(); let use_count_bytes = self.use_count.serialize(); [ spec_bytes[0], spec_bytes[1], spec_bytes[2], spec_bytes[3], spec_bytes[4], spec_bytes[5], spec_bytes[6], spec_bytes[7], bytes_bytes[0], bytes_bytes[1], bytes_bytes[2], bytes_bytes[3], ref_count_bytes[0], ref_count_bytes[1], ref_count_bytes[2], ref_count_bytes[3], use_count_bytes[0], use_count_bytes[1], use_count_bytes[2], use_count_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(20); self.spec.serialize_into(bytes); self.bytes.serialize_into(bytes); self.ref_count.serialize_into(bytes); self.use_count.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ResourceSizeValue { pub size: ResourceSizeSpec, pub cross_references: Vec, } impl TryParse for ResourceSizeValue { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (size, remaining) = ResourceSizeSpec::try_parse(remaining)?; let (num_cross_references, remaining) = u32::try_parse(remaining)?; let (cross_references, remaining) = crate::x11_utils::parse_list::(remaining, num_cross_references.try_to_usize()?)?; let result = ResourceSizeValue { size, cross_references }; Ok((result, remaining)) } } impl Serialize for ResourceSizeValue { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.size.serialize_into(bytes); let num_cross_references = u32::try_from(self.cross_references.len()).expect("`cross_references` has too many elements"); num_cross_references.serialize_into(bytes); self.cross_references.serialize_into(bytes); } } impl ResourceSizeValue { /// Get the value of the `num_cross_references` field. /// /// The `num_cross_references` field is used as the length field of the `cross_references` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_cross_references(&self) -> u32 { self.cross_references.len() .try_into().unwrap() } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major: u8, pub client_minor: u8, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_bytes = self.client_major.serialize(); let client_minor_bytes = self.client_minor.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_bytes[0], client_minor_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major, remaining) = u8::try_parse(value)?; let (client_minor, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major, client_minor, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major: u8, client_minor: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major, client_minor, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub server_major: u16, pub server_minor: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major, remaining) = u16::try_parse(remaining)?; let (server_minor, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, server_major, server_minor }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryClients request pub const QUERY_CLIENTS_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryClientsRequest; impl QueryClientsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_CLIENTS_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_CLIENTS_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryClientsRequest ) } } impl Request for QueryClientsRequest { type Reply = QueryClientsReply; } pub fn query_clients(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryClientsRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryClientsReply { pub sequence: u16, pub length: u32, pub clients: Vec, } impl TryParse for QueryClientsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_clients, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (clients, remaining) = crate::x11_utils::parse_list::(remaining, num_clients.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryClientsReply { sequence, length, clients }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryClientsReply { /// Get the value of the `num_clients` field. /// /// The `num_clients` field is used as the length field of the `clients` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_clients(&self) -> u32 { self.clients.len() .try_into().unwrap() } } /// Opcode for the QueryClientResources request pub const QUERY_CLIENT_RESOURCES_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryClientResourcesRequest { pub xid: u32, } impl QueryClientResourcesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let xid_bytes = self.xid.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_CLIENT_RESOURCES_REQUEST, 0, 0, xid_bytes[0], xid_bytes[1], xid_bytes[2], xid_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_CLIENT_RESOURCES_REQUEST { return Err(ParseError::InvalidValue); } let (xid, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(QueryClientResourcesRequest { xid, }) } } impl Request for QueryClientResourcesRequest { type Reply = QueryClientResourcesReply; } pub fn query_client_resources(conn: &Conn, xid: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryClientResourcesRequest { xid, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryClientResourcesReply { pub sequence: u16, pub length: u32, pub types: Vec, } impl TryParse for QueryClientResourcesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_types, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (types, remaining) = crate::x11_utils::parse_list::(remaining, num_types.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryClientResourcesReply { sequence, length, types }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryClientResourcesReply { /// Get the value of the `num_types` field. /// /// The `num_types` field is used as the length field of the `types` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_types(&self) -> u32 { self.types.len() .try_into().unwrap() } } /// Opcode for the QueryClientPixmapBytes request pub const QUERY_CLIENT_PIXMAP_BYTES_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryClientPixmapBytesRequest { pub xid: u32, } impl QueryClientPixmapBytesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let xid_bytes = self.xid.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_CLIENT_PIXMAP_BYTES_REQUEST, 0, 0, xid_bytes[0], xid_bytes[1], xid_bytes[2], xid_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_CLIENT_PIXMAP_BYTES_REQUEST { return Err(ParseError::InvalidValue); } let (xid, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(QueryClientPixmapBytesRequest { xid, }) } } impl Request for QueryClientPixmapBytesRequest { type Reply = QueryClientPixmapBytesReply; } pub fn query_client_pixmap_bytes(conn: &Conn, xid: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryClientPixmapBytesRequest { xid, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryClientPixmapBytesReply { pub sequence: u16, pub length: u32, pub bytes: u32, pub bytes_overflow: u32, } impl TryParse for QueryClientPixmapBytesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (bytes, remaining) = u32::try_parse(remaining)?; let (bytes_overflow, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryClientPixmapBytesReply { sequence, length, bytes, bytes_overflow }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryClientIds request pub const QUERY_CLIENT_IDS_REQUEST: u8 = 4; #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryClientIdsRequest<'input> { pub specs: Cow<'input, [ClientIdSpec]>, } impl<'input> QueryClientIdsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let num_specs = u32::try_from(self.specs.len()).expect("`specs` has too many elements"); let num_specs_bytes = num_specs.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_CLIENT_IDS_REQUEST, 0, 0, num_specs_bytes[0], num_specs_bytes[1], num_specs_bytes[2], num_specs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let specs_bytes = self.specs.serialize(); let length_so_far = length_so_far + specs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), specs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != QUERY_CLIENT_IDS_REQUEST { return Err(ParseError::InvalidValue); } let (num_specs, remaining) = u32::try_parse(value)?; let (specs, remaining) = crate::x11_utils::parse_list::(remaining, num_specs.try_to_usize()?)?; let _ = remaining; Ok(QueryClientIdsRequest { specs: Cow::Owned(specs), }) } /// Clone all borrowed data in this QueryClientIdsRequest. pub fn into_owned(self) -> QueryClientIdsRequest<'static> { QueryClientIdsRequest { specs: Cow::Owned(self.specs.into_owned()), } } } impl<'input> Request for QueryClientIdsRequest<'input> { type Reply = QueryClientIdsReply; } pub fn query_client_ids<'c, 'input, Conn>(conn: &'c Conn, specs: &'input [ClientIdSpec]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryClientIdsRequest { specs: Cow::Borrowed(specs), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryClientIdsReply { pub sequence: u16, pub length: u32, pub ids: Vec, } impl TryParse for QueryClientIdsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_ids, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (ids, remaining) = crate::x11_utils::parse_list::(remaining, num_ids.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryClientIdsReply { sequence, length, ids }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryClientIdsReply { /// Get the value of the `num_ids` field. /// /// The `num_ids` field is used as the length field of the `ids` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_ids(&self) -> u32 { self.ids.len() .try_into().unwrap() } } /// Opcode for the QueryResourceBytes request pub const QUERY_RESOURCE_BYTES_REQUEST: u8 = 5; #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryResourceBytesRequest<'input> { pub client: u32, pub specs: Cow<'input, [ResourceIdSpec]>, } impl<'input> QueryResourceBytesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_bytes = self.client.serialize(); let num_specs = u32::try_from(self.specs.len()).expect("`specs` has too many elements"); let num_specs_bytes = num_specs.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_RESOURCE_BYTES_REQUEST, 0, 0, client_bytes[0], client_bytes[1], client_bytes[2], client_bytes[3], num_specs_bytes[0], num_specs_bytes[1], num_specs_bytes[2], num_specs_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let specs_bytes = self.specs.serialize(); let length_so_far = length_so_far + specs_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), specs_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != QUERY_RESOURCE_BYTES_REQUEST { return Err(ParseError::InvalidValue); } let (client, remaining) = u32::try_parse(value)?; let (num_specs, remaining) = u32::try_parse(remaining)?; let (specs, remaining) = crate::x11_utils::parse_list::(remaining, num_specs.try_to_usize()?)?; let _ = remaining; Ok(QueryResourceBytesRequest { client, specs: Cow::Owned(specs), }) } /// Clone all borrowed data in this QueryResourceBytesRequest. pub fn into_owned(self) -> QueryResourceBytesRequest<'static> { QueryResourceBytesRequest { client: self.client, specs: Cow::Owned(self.specs.into_owned()), } } } impl<'input> Request for QueryResourceBytesRequest<'input> { type Reply = QueryResourceBytesReply; } pub fn query_resource_bytes<'c, 'input, Conn>(conn: &'c Conn, client: u32, specs: &'input [ResourceIdSpec]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryResourceBytesRequest { client, specs: Cow::Borrowed(specs), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryResourceBytesReply { pub sequence: u16, pub length: u32, pub sizes: Vec, } impl TryParse for QueryResourceBytesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_sizes, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (sizes, remaining) = crate::x11_utils::parse_list::(remaining, num_sizes.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryResourceBytesReply { sequence, length, sizes }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryResourceBytesReply { /// Get the value of the `num_sizes` field. /// /// The `num_sizes` field is used as the length field of the `sizes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_sizes(&self) -> u32 { self.sizes.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn res_query_version(&self, client_major: u8, client_minor: u8) -> Result, ConnectionError> { query_version(self, client_major, client_minor) } fn res_query_clients(&self) -> Result, ConnectionError> { query_clients(self) } fn res_query_client_resources(&self, xid: u32) -> Result, ConnectionError> { query_client_resources(self, xid) } fn res_query_client_pixmap_bytes(&self, xid: u32) -> Result, ConnectionError> { query_client_pixmap_bytes(self, xid) } fn res_query_client_ids<'c, 'input>(&'c self, specs: &'input [ClientIdSpec]) -> Result, ConnectionError> { query_client_ids(self, specs) } fn res_query_resource_bytes<'c, 'input>(&'c self, client: u32, specs: &'input [ResourceIdSpec]) -> Result, ConnectionError> { query_resource_bytes(self, client, specs) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/screensaver.rs010064400017500001750000001276171402220031600161600ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `ScreenSaver` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "MIT-SCREEN-SAVER"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 1); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Kind(u8); impl Kind { pub const BLANKED: Self = Self(0); pub const INTERNAL: Self = Self(1); pub const EXTERNAL: Self = Self(2); } impl From for u8 { #[inline] fn from(input: Kind) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Kind) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Kind) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Kind) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Kind) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Kind) -> Self { Some(u32::from(input.0)) } } impl From for Kind { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Kind { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::BLANKED.0.into(), "BLANKED", "Blanked"), (Self::INTERNAL.0.into(), "INTERNAL", "Internal"), (Self::EXTERNAL.0.into(), "EXTERNAL", "External"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Event(u8); impl Event { pub const NOTIFY_MASK: Self = Self(1 << 0); pub const CYCLE_MASK: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: Event) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Event) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Event) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Event) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Event) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Event) -> Self { Some(u32::from(input.0)) } } impl From for Event { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Event { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NOTIFY_MASK.0.into(), "NOTIFY_MASK", "NotifyMask"), (Self::CYCLE_MASK.0.into(), "CYCLE_MASK", "CycleMask"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(Event, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct State(u8); impl State { pub const OFF: Self = Self(0); pub const ON: Self = Self(1); pub const CYCLE: Self = Self(2); pub const DISABLED: Self = Self(3); } impl From for u8 { #[inline] fn from(input: State) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: State) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: State) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: State) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: State) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: State) -> Self { Some(u32::from(input.0)) } } impl From for State { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for State { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::OFF.0.into(), "OFF", "Off"), (Self::ON.0.into(), "ON", "On"), (Self::CYCLE.0.into(), "CYCLE", "Cycle"), (Self::DISABLED.0.into(), "DISABLED", "Disabled"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major_version: u8, pub client_minor_version: u8, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_minor_version_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u8::try_parse(value)?; let (client_minor_version, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(QueryVersionRequest { client_major_version, client_minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major_version: u8, client_minor_version: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub server_major_version: u16, pub server_minor_version: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major_version, remaining) = u16::try_parse(remaining)?; let (server_minor_version, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, server_major_version, server_minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryInfo request pub const QUERY_INFO_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryInfoRequest { pub drawable: xproto::Drawable, } impl QueryInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_INFO_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let _ = remaining; Ok(QueryInfoRequest { drawable, }) } } impl Request for QueryInfoRequest { type Reply = QueryInfoReply; } pub fn query_info(conn: &Conn, drawable: xproto::Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryInfoRequest { drawable, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryInfoReply { pub state: u8, pub sequence: u16, pub length: u32, pub saver_window: xproto::Window, pub ms_until_server: u32, pub ms_since_user_input: u32, pub event_mask: u32, pub kind: Kind, } impl TryParse for QueryInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (saver_window, remaining) = xproto::Window::try_parse(remaining)?; let (ms_until_server, remaining) = u32::try_parse(remaining)?; let (ms_since_user_input, remaining) = u32::try_parse(remaining)?; let (event_mask, remaining) = u32::try_parse(remaining)?; let (kind, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(7..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let kind = kind.into(); let result = QueryInfoReply { state, sequence, length, saver_window, ms_until_server, ms_since_user_input, event_mask, kind }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SelectInput request pub const SELECT_INPUT_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectInputRequest { pub drawable: xproto::Drawable, pub event_mask: u32, } impl SelectInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let event_mask_bytes = self.event_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_INPUT_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], event_mask_bytes[0], event_mask_bytes[1], event_mask_bytes[2], event_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (event_mask, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SelectInputRequest { drawable, event_mask, }) } } impl Request for SelectInputRequest { type Reply = (); } pub fn select_input(conn: &Conn, drawable: xproto::Drawable, event_mask: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let event_mask: u32 = event_mask.into(); let request0 = SelectInputRequest { drawable, event_mask, }; request0.send(conn) } /// Auxiliary and optional information for the `set_attributes` function #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct SetAttributesAux { pub background_pixmap: Option, pub background_pixel: Option, pub border_pixmap: Option, pub border_pixel: Option, pub bit_gravity: Option, pub win_gravity: Option, pub backing_store: Option, pub backing_planes: Option, pub backing_pixel: Option, pub override_redirect: Option, pub save_under: Option, pub event_mask: Option, pub do_not_propogate_mask: Option, pub colormap: Option, pub cursor: Option, } impl SetAttributesAux { fn try_parse(value: &[u8], value_mask: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = value_mask; let mut outer_remaining = value; let background_pixmap = if switch_expr & u32::from(xproto::CW::BACK_PIXMAP) != 0 { let remaining = outer_remaining; let (background_pixmap, remaining) = xproto::Pixmap::try_parse(remaining)?; outer_remaining = remaining; Some(background_pixmap) } else { None }; let background_pixel = if switch_expr & u32::from(xproto::CW::BACK_PIXEL) != 0 { let remaining = outer_remaining; let (background_pixel, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(background_pixel) } else { None }; let border_pixmap = if switch_expr & u32::from(xproto::CW::BORDER_PIXMAP) != 0 { let remaining = outer_remaining; let (border_pixmap, remaining) = xproto::Pixmap::try_parse(remaining)?; outer_remaining = remaining; Some(border_pixmap) } else { None }; let border_pixel = if switch_expr & u32::from(xproto::CW::BORDER_PIXEL) != 0 { let remaining = outer_remaining; let (border_pixel, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(border_pixel) } else { None }; let bit_gravity = if switch_expr & u32::from(xproto::CW::BIT_GRAVITY) != 0 { let remaining = outer_remaining; let (bit_gravity, remaining) = u32::try_parse(remaining)?; let bit_gravity = bit_gravity.into(); outer_remaining = remaining; Some(bit_gravity) } else { None }; let win_gravity = if switch_expr & u32::from(xproto::CW::WIN_GRAVITY) != 0 { let remaining = outer_remaining; let (win_gravity, remaining) = u32::try_parse(remaining)?; let win_gravity = win_gravity.into(); outer_remaining = remaining; Some(win_gravity) } else { None }; let backing_store = if switch_expr & u32::from(xproto::CW::BACKING_STORE) != 0 { let remaining = outer_remaining; let (backing_store, remaining) = u32::try_parse(remaining)?; let backing_store = backing_store.into(); outer_remaining = remaining; Some(backing_store) } else { None }; let backing_planes = if switch_expr & u32::from(xproto::CW::BACKING_PLANES) != 0 { let remaining = outer_remaining; let (backing_planes, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(backing_planes) } else { None }; let backing_pixel = if switch_expr & u32::from(xproto::CW::BACKING_PIXEL) != 0 { let remaining = outer_remaining; let (backing_pixel, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(backing_pixel) } else { None }; let override_redirect = if switch_expr & u32::from(xproto::CW::OVERRIDE_REDIRECT) != 0 { let remaining = outer_remaining; let (override_redirect, remaining) = xproto::Bool32::try_parse(remaining)?; outer_remaining = remaining; Some(override_redirect) } else { None }; let save_under = if switch_expr & u32::from(xproto::CW::SAVE_UNDER) != 0 { let remaining = outer_remaining; let (save_under, remaining) = xproto::Bool32::try_parse(remaining)?; outer_remaining = remaining; Some(save_under) } else { None }; let event_mask = if switch_expr & u32::from(xproto::CW::EVENT_MASK) != 0 { let remaining = outer_remaining; let (event_mask, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(event_mask) } else { None }; let do_not_propogate_mask = if switch_expr & u32::from(xproto::CW::DONT_PROPAGATE) != 0 { let remaining = outer_remaining; let (do_not_propogate_mask, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(do_not_propogate_mask) } else { None }; let colormap = if switch_expr & u32::from(xproto::CW::COLORMAP) != 0 { let remaining = outer_remaining; let (colormap, remaining) = xproto::Colormap::try_parse(remaining)?; outer_remaining = remaining; Some(colormap) } else { None }; let cursor = if switch_expr & u32::from(xproto::CW::CURSOR) != 0 { let remaining = outer_remaining; let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?; outer_remaining = remaining; Some(cursor) } else { None }; let result = SetAttributesAux { background_pixmap, background_pixel, border_pixmap, border_pixel, bit_gravity, win_gravity, backing_store, backing_planes, backing_pixel, override_redirect, save_under, event_mask, do_not_propogate_mask, colormap, cursor }; Ok((result, outer_remaining)) } } impl SetAttributesAux { #[allow(dead_code)] fn serialize(&self, value_mask: u32) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, value_mask); result } fn serialize_into(&self, bytes: &mut Vec, value_mask: u32) { assert_eq!(self.switch_expr(), value_mask, "switch `value_list` has an inconsistent discriminant"); if let Some(background_pixmap) = self.background_pixmap { background_pixmap.serialize_into(bytes); } if let Some(background_pixel) = self.background_pixel { background_pixel.serialize_into(bytes); } if let Some(border_pixmap) = self.border_pixmap { border_pixmap.serialize_into(bytes); } if let Some(border_pixel) = self.border_pixel { border_pixel.serialize_into(bytes); } if let Some(bit_gravity) = self.bit_gravity { u32::from(bit_gravity).serialize_into(bytes); } if let Some(win_gravity) = self.win_gravity { u32::from(win_gravity).serialize_into(bytes); } if let Some(backing_store) = self.backing_store { u32::from(backing_store).serialize_into(bytes); } if let Some(backing_planes) = self.backing_planes { backing_planes.serialize_into(bytes); } if let Some(backing_pixel) = self.backing_pixel { backing_pixel.serialize_into(bytes); } if let Some(override_redirect) = self.override_redirect { override_redirect.serialize_into(bytes); } if let Some(save_under) = self.save_under { save_under.serialize_into(bytes); } if let Some(event_mask) = self.event_mask { event_mask.serialize_into(bytes); } if let Some(do_not_propogate_mask) = self.do_not_propogate_mask { do_not_propogate_mask.serialize_into(bytes); } if let Some(colormap) = self.colormap { colormap.serialize_into(bytes); } if let Some(cursor) = self.cursor { cursor.serialize_into(bytes); } } } impl SetAttributesAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.background_pixmap.is_some() { expr_value |= u32::from(xproto::CW::BACK_PIXMAP); } if self.background_pixel.is_some() { expr_value |= u32::from(xproto::CW::BACK_PIXEL); } if self.border_pixmap.is_some() { expr_value |= u32::from(xproto::CW::BORDER_PIXMAP); } if self.border_pixel.is_some() { expr_value |= u32::from(xproto::CW::BORDER_PIXEL); } if self.bit_gravity.is_some() { expr_value |= u32::from(xproto::CW::BIT_GRAVITY); } if self.win_gravity.is_some() { expr_value |= u32::from(xproto::CW::WIN_GRAVITY); } if self.backing_store.is_some() { expr_value |= u32::from(xproto::CW::BACKING_STORE); } if self.backing_planes.is_some() { expr_value |= u32::from(xproto::CW::BACKING_PLANES); } if self.backing_pixel.is_some() { expr_value |= u32::from(xproto::CW::BACKING_PIXEL); } if self.override_redirect.is_some() { expr_value |= u32::from(xproto::CW::OVERRIDE_REDIRECT); } if self.save_under.is_some() { expr_value |= u32::from(xproto::CW::SAVE_UNDER); } if self.event_mask.is_some() { expr_value |= u32::from(xproto::CW::EVENT_MASK); } if self.do_not_propogate_mask.is_some() { expr_value |= u32::from(xproto::CW::DONT_PROPAGATE); } if self.colormap.is_some() { expr_value |= u32::from(xproto::CW::COLORMAP); } if self.cursor.is_some() { expr_value |= u32::from(xproto::CW::CURSOR); } expr_value } } impl SetAttributesAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `background_pixmap` field of this structure. pub fn background_pixmap(mut self, value: I) -> Self where I: Into> { self.background_pixmap = value.into(); self } /// Set the `background_pixel` field of this structure. pub fn background_pixel(mut self, value: I) -> Self where I: Into> { self.background_pixel = value.into(); self } /// Set the `border_pixmap` field of this structure. pub fn border_pixmap(mut self, value: I) -> Self where I: Into> { self.border_pixmap = value.into(); self } /// Set the `border_pixel` field of this structure. pub fn border_pixel(mut self, value: I) -> Self where I: Into> { self.border_pixel = value.into(); self } /// Set the `bit_gravity` field of this structure. pub fn bit_gravity(mut self, value: I) -> Self where I: Into> { self.bit_gravity = value.into(); self } /// Set the `win_gravity` field of this structure. pub fn win_gravity(mut self, value: I) -> Self where I: Into> { self.win_gravity = value.into(); self } /// Set the `backing_store` field of this structure. pub fn backing_store(mut self, value: I) -> Self where I: Into> { self.backing_store = value.into(); self } /// Set the `backing_planes` field of this structure. pub fn backing_planes(mut self, value: I) -> Self where I: Into> { self.backing_planes = value.into(); self } /// Set the `backing_pixel` field of this structure. pub fn backing_pixel(mut self, value: I) -> Self where I: Into> { self.backing_pixel = value.into(); self } /// Set the `override_redirect` field of this structure. pub fn override_redirect(mut self, value: I) -> Self where I: Into> { self.override_redirect = value.into(); self } /// Set the `save_under` field of this structure. pub fn save_under(mut self, value: I) -> Self where I: Into> { self.save_under = value.into(); self } /// Set the `event_mask` field of this structure. pub fn event_mask(mut self, value: I) -> Self where I: Into> { self.event_mask = value.into(); self } /// Set the `do_not_propogate_mask` field of this structure. pub fn do_not_propogate_mask(mut self, value: I) -> Self where I: Into> { self.do_not_propogate_mask = value.into(); self } /// Set the `colormap` field of this structure. pub fn colormap(mut self, value: I) -> Self where I: Into> { self.colormap = value.into(); self } /// Set the `cursor` field of this structure. pub fn cursor(mut self, value: I) -> Self where I: Into> { self.cursor = value.into(); self } } /// Opcode for the SetAttributes request pub const SET_ATTRIBUTES_REQUEST: u8 = 3; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetAttributesRequest<'input> { pub drawable: xproto::Drawable, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub border_width: u16, pub class: xproto::WindowClass, pub depth: u8, pub visual: xproto::Visualid, pub value_list: Cow<'input, SetAttributesAux>, } impl<'input> SetAttributesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let border_width_bytes = self.border_width.serialize(); let class_bytes = (u16::from(self.class) as u8).serialize(); let depth_bytes = self.depth.serialize(); let visual_bytes = self.visual.serialize(); let value_mask = self.value_list.switch_expr(); let value_mask_bytes = value_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_ATTRIBUTES_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], border_width_bytes[0], border_width_bytes[1], class_bytes[0], depth_bytes[0], visual_bytes[0], visual_bytes[1], visual_bytes[2], visual_bytes[3], value_mask_bytes[0], value_mask_bytes[1], value_mask_bytes[2], value_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let value_list_bytes = self.value_list.serialize(value_mask); let length_so_far = length_so_far + value_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), value_list_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (border_width, remaining) = u16::try_parse(remaining)?; let (class, remaining) = u8::try_parse(remaining)?; let class = class.into(); let (depth, remaining) = u8::try_parse(remaining)?; let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (value_mask, remaining) = u32::try_parse(remaining)?; let (value_list, remaining) = SetAttributesAux::try_parse(remaining, value_mask)?; let _ = remaining; Ok(SetAttributesRequest { drawable, x, y, width, height, border_width, class, depth, visual, value_list: Cow::Owned(value_list), }) } /// Clone all borrowed data in this SetAttributesRequest. pub fn into_owned(self) -> SetAttributesRequest<'static> { SetAttributesRequest { drawable: self.drawable, x: self.x, y: self.y, width: self.width, height: self.height, border_width: self.border_width, class: self.class, depth: self.depth, visual: self.visual, value_list: Cow::Owned(self.value_list.into_owned()), } } } impl<'input> Request for SetAttributesRequest<'input> { type Reply = (); } pub fn set_attributes<'c, 'input, Conn>(conn: &'c Conn, drawable: xproto::Drawable, x: i16, y: i16, width: u16, height: u16, border_width: u16, class: xproto::WindowClass, depth: u8, visual: xproto::Visualid, value_list: &'input SetAttributesAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetAttributesRequest { drawable, x, y, width, height, border_width, class, depth, visual, value_list: Cow::Borrowed(value_list), }; request0.send(conn) } /// Opcode for the UnsetAttributes request pub const UNSET_ATTRIBUTES_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UnsetAttributesRequest { pub drawable: xproto::Drawable, } impl UnsetAttributesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, UNSET_ATTRIBUTES_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNSET_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let _ = remaining; Ok(UnsetAttributesRequest { drawable, }) } } impl Request for UnsetAttributesRequest { type Reply = (); } pub fn unset_attributes(conn: &Conn, drawable: xproto::Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = UnsetAttributesRequest { drawable, }; request0.send(conn) } /// Opcode for the Suspend request pub const SUSPEND_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SuspendRequest { pub suspend: u32, } impl SuspendRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let suspend_bytes = self.suspend.serialize(); let mut request0 = vec![ extension_information.major_opcode, SUSPEND_REQUEST, 0, 0, suspend_bytes[0], suspend_bytes[1], suspend_bytes[2], suspend_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SUSPEND_REQUEST { return Err(ParseError::InvalidValue); } let (suspend, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(SuspendRequest { suspend, }) } } impl Request for SuspendRequest { type Reply = (); } pub fn suspend(conn: &Conn, suspend: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SuspendRequest { suspend, }; request0.send(conn) } /// Opcode for the Notify event pub const NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NotifyEvent { pub response_type: u8, pub state: State, pub sequence: u16, pub time: xproto::Timestamp, pub root: xproto::Window, pub window: xproto::Window, pub kind: Kind, pub forced: bool, } impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (kind, remaining) = u8::try_parse(remaining)?; let (forced, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(14..).ok_or(ParseError::InsufficientData)?; let state = state.into(); let kind = kind.into(); let result = NotifyEvent { response_type, state, sequence, time, root, window, kind, forced }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NotifyEvent> for [u8; 32] { fn from(input: &NotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let state_bytes = u8::from(input.state).serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let root_bytes = input.root.serialize(); let window_bytes = input.window.serialize(); let kind_bytes = u8::from(input.kind).serialize(); let forced_bytes = input.forced.serialize(); [ response_type_bytes[0], state_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], kind_bytes[0], forced_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: NotifyEvent) -> Self { Self::from(&input) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn screensaver_query_version(&self, client_major_version: u8, client_minor_version: u8) -> Result, ConnectionError> { query_version(self, client_major_version, client_minor_version) } fn screensaver_query_info(&self, drawable: xproto::Drawable) -> Result, ConnectionError> { query_info(self, drawable) } fn screensaver_select_input(&self, drawable: xproto::Drawable, event_mask: A) -> Result, ConnectionError> where A: Into, { select_input(self, drawable, event_mask) } fn screensaver_set_attributes<'c, 'input>(&'c self, drawable: xproto::Drawable, x: i16, y: i16, width: u16, height: u16, border_width: u16, class: xproto::WindowClass, depth: u8, visual: xproto::Visualid, value_list: &'input SetAttributesAux) -> Result, ConnectionError> { set_attributes(self, drawable, x, y, width, height, border_width, class, depth, visual, value_list) } fn screensaver_unset_attributes(&self, drawable: xproto::Drawable) -> Result, ConnectionError> { unset_attributes(self, drawable) } fn screensaver_suspend(&self, suspend: u32) -> Result, ConnectionError> { self::suspend(self, suspend) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/shape.rs010064400017500001750000001330761402220031600147340ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Shape` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "SHAPE"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 1); pub type Op = u8; pub type Kind = u8; #[derive(Clone, Copy, PartialEq, Eq)] pub struct SO(u8); impl SO { pub const SET: Self = Self(0); pub const UNION: Self = Self(1); pub const INTERSECT: Self = Self(2); pub const SUBTRACT: Self = Self(3); pub const INVERT: Self = Self(4); } impl From for u8 { #[inline] fn from(input: SO) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SO) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SO) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SO) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SO) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SO) -> Self { Some(u32::from(input.0)) } } impl From for SO { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SO { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SET.0.into(), "SET", "Set"), (Self::UNION.0.into(), "UNION", "Union"), (Self::INTERSECT.0.into(), "INTERSECT", "Intersect"), (Self::SUBTRACT.0.into(), "SUBTRACT", "Subtract"), (Self::INVERT.0.into(), "INVERT", "Invert"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SK(u8); impl SK { pub const BOUNDING: Self = Self(0); pub const CLIP: Self = Self(1); pub const INPUT: Self = Self(2); } impl From for u8 { #[inline] fn from(input: SK) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SK) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SK) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SK) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SK) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SK) -> Self { Some(u32::from(input.0)) } } impl From for SK { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SK { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::BOUNDING.0.into(), "BOUNDING", "Bounding"), (Self::CLIP.0.into(), "CLIP", "Clip"), (Self::INPUT.0.into(), "INPUT", "Input"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the Notify event pub const NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NotifyEvent { pub response_type: u8, pub shape_kind: SK, pub sequence: u16, pub affected_window: xproto::Window, pub extents_x: i16, pub extents_y: i16, pub extents_width: u16, pub extents_height: u16, pub server_time: xproto::Timestamp, pub shaped: bool, } impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (shape_kind, remaining) = Kind::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (affected_window, remaining) = xproto::Window::try_parse(remaining)?; let (extents_x, remaining) = i16::try_parse(remaining)?; let (extents_y, remaining) = i16::try_parse(remaining)?; let (extents_width, remaining) = u16::try_parse(remaining)?; let (extents_height, remaining) = u16::try_parse(remaining)?; let (server_time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (shaped, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(11..).ok_or(ParseError::InsufficientData)?; let shape_kind = shape_kind.into(); let result = NotifyEvent { response_type, shape_kind, sequence, affected_window, extents_x, extents_y, extents_width, extents_height, server_time, shaped }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NotifyEvent> for [u8; 32] { fn from(input: &NotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let shape_kind_bytes = Kind::from(input.shape_kind).serialize(); let sequence_bytes = input.sequence.serialize(); let affected_window_bytes = input.affected_window.serialize(); let extents_x_bytes = input.extents_x.serialize(); let extents_y_bytes = input.extents_y.serialize(); let extents_width_bytes = input.extents_width.serialize(); let extents_height_bytes = input.extents_height.serialize(); let server_time_bytes = input.server_time.serialize(); let shaped_bytes = input.shaped.serialize(); [ response_type_bytes[0], shape_kind_bytes[0], sequence_bytes[0], sequence_bytes[1], affected_window_bytes[0], affected_window_bytes[1], affected_window_bytes[2], affected_window_bytes[3], extents_x_bytes[0], extents_x_bytes[1], extents_y_bytes[0], extents_y_bytes[1], extents_width_bytes[0], extents_width_bytes[1], extents_height_bytes[0], extents_height_bytes[1], server_time_bytes[0], server_time_bytes[1], server_time_bytes[2], server_time_bytes[3], shaped_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: NotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest; impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryVersionRequest ) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u16, pub minor_version: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u16::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Rectangles request pub const RECTANGLES_REQUEST: u8 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RectanglesRequest<'input> { pub operation: SO, pub destination_kind: SK, pub ordering: xproto::ClipOrdering, pub destination_window: xproto::Window, pub x_offset: i16, pub y_offset: i16, pub rectangles: Cow<'input, [xproto::Rectangle]>, } impl<'input> RectanglesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let operation_bytes = Op::from(self.operation).serialize(); let destination_kind_bytes = Kind::from(self.destination_kind).serialize(); let ordering_bytes = u8::from(self.ordering).serialize(); let destination_window_bytes = self.destination_window.serialize(); let x_offset_bytes = self.x_offset.serialize(); let y_offset_bytes = self.y_offset.serialize(); let mut request0 = vec![ extension_information.major_opcode, RECTANGLES_REQUEST, 0, 0, operation_bytes[0], destination_kind_bytes[0], ordering_bytes[0], 0, destination_window_bytes[0], destination_window_bytes[1], destination_window_bytes[2], destination_window_bytes[3], x_offset_bytes[0], x_offset_bytes[1], y_offset_bytes[0], y_offset_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let rectangles_bytes = self.rectangles.serialize(); let length_so_far = length_so_far + rectangles_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), rectangles_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != RECTANGLES_REQUEST { return Err(ParseError::InvalidValue); } let (operation, remaining) = Op::try_parse(value)?; let operation = operation.into(); let (destination_kind, remaining) = Kind::try_parse(remaining)?; let destination_kind = destination_kind.into(); let (ordering, remaining) = u8::try_parse(remaining)?; let ordering = ordering.into(); let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (destination_window, remaining) = xproto::Window::try_parse(remaining)?; let (x_offset, remaining) = i16::try_parse(remaining)?; let (y_offset, remaining) = i16::try_parse(remaining)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut rectangles = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = xproto::Rectangle::try_parse(remaining)?; remaining = new_remaining; rectangles.push(v); } let _ = remaining; Ok(RectanglesRequest { operation, destination_kind, ordering, destination_window, x_offset, y_offset, rectangles: Cow::Owned(rectangles), }) } /// Clone all borrowed data in this RectanglesRequest. pub fn into_owned(self) -> RectanglesRequest<'static> { RectanglesRequest { operation: self.operation, destination_kind: self.destination_kind, ordering: self.ordering, destination_window: self.destination_window, x_offset: self.x_offset, y_offset: self.y_offset, rectangles: Cow::Owned(self.rectangles.into_owned()), } } } impl<'input> Request for RectanglesRequest<'input> { type Reply = (); } pub fn rectangles<'c, 'input, Conn>(conn: &'c Conn, operation: SO, destination_kind: SK, ordering: xproto::ClipOrdering, destination_window: xproto::Window, x_offset: i16, y_offset: i16, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RectanglesRequest { operation, destination_kind, ordering, destination_window, x_offset, y_offset, rectangles: Cow::Borrowed(rectangles), }; request0.send(conn) } /// Opcode for the Mask request pub const MASK_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MaskRequest { pub operation: SO, pub destination_kind: SK, pub destination_window: xproto::Window, pub x_offset: i16, pub y_offset: i16, pub source_bitmap: xproto::Pixmap, } impl MaskRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let operation_bytes = Op::from(self.operation).serialize(); let destination_kind_bytes = Kind::from(self.destination_kind).serialize(); let destination_window_bytes = self.destination_window.serialize(); let x_offset_bytes = self.x_offset.serialize(); let y_offset_bytes = self.y_offset.serialize(); let source_bitmap_bytes = self.source_bitmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, MASK_REQUEST, 0, 0, operation_bytes[0], destination_kind_bytes[0], 0, 0, destination_window_bytes[0], destination_window_bytes[1], destination_window_bytes[2], destination_window_bytes[3], x_offset_bytes[0], x_offset_bytes[1], y_offset_bytes[0], y_offset_bytes[1], source_bitmap_bytes[0], source_bitmap_bytes[1], source_bitmap_bytes[2], source_bitmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != MASK_REQUEST { return Err(ParseError::InvalidValue); } let (operation, remaining) = Op::try_parse(value)?; let operation = operation.into(); let (destination_kind, remaining) = Kind::try_parse(remaining)?; let destination_kind = destination_kind.into(); let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (destination_window, remaining) = xproto::Window::try_parse(remaining)?; let (x_offset, remaining) = i16::try_parse(remaining)?; let (y_offset, remaining) = i16::try_parse(remaining)?; let (source_bitmap, remaining) = xproto::Pixmap::try_parse(remaining)?; let _ = remaining; Ok(MaskRequest { operation, destination_kind, destination_window, x_offset, y_offset, source_bitmap, }) } } impl Request for MaskRequest { type Reply = (); } pub fn mask(conn: &Conn, operation: SO, destination_kind: SK, destination_window: xproto::Window, x_offset: i16, y_offset: i16, source_bitmap: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let source_bitmap: xproto::Pixmap = source_bitmap.into(); let request0 = MaskRequest { operation, destination_kind, destination_window, x_offset, y_offset, source_bitmap, }; request0.send(conn) } /// Opcode for the Combine request pub const COMBINE_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CombineRequest { pub operation: SO, pub destination_kind: SK, pub source_kind: SK, pub destination_window: xproto::Window, pub x_offset: i16, pub y_offset: i16, pub source_window: xproto::Window, } impl CombineRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let operation_bytes = Op::from(self.operation).serialize(); let destination_kind_bytes = Kind::from(self.destination_kind).serialize(); let source_kind_bytes = Kind::from(self.source_kind).serialize(); let destination_window_bytes = self.destination_window.serialize(); let x_offset_bytes = self.x_offset.serialize(); let y_offset_bytes = self.y_offset.serialize(); let source_window_bytes = self.source_window.serialize(); let mut request0 = vec![ extension_information.major_opcode, COMBINE_REQUEST, 0, 0, operation_bytes[0], destination_kind_bytes[0], source_kind_bytes[0], 0, destination_window_bytes[0], destination_window_bytes[1], destination_window_bytes[2], destination_window_bytes[3], x_offset_bytes[0], x_offset_bytes[1], y_offset_bytes[0], y_offset_bytes[1], source_window_bytes[0], source_window_bytes[1], source_window_bytes[2], source_window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != COMBINE_REQUEST { return Err(ParseError::InvalidValue); } let (operation, remaining) = Op::try_parse(value)?; let operation = operation.into(); let (destination_kind, remaining) = Kind::try_parse(remaining)?; let destination_kind = destination_kind.into(); let (source_kind, remaining) = Kind::try_parse(remaining)?; let source_kind = source_kind.into(); let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (destination_window, remaining) = xproto::Window::try_parse(remaining)?; let (x_offset, remaining) = i16::try_parse(remaining)?; let (y_offset, remaining) = i16::try_parse(remaining)?; let (source_window, remaining) = xproto::Window::try_parse(remaining)?; let _ = remaining; Ok(CombineRequest { operation, destination_kind, source_kind, destination_window, x_offset, y_offset, source_window, }) } } impl Request for CombineRequest { type Reply = (); } pub fn combine(conn: &Conn, operation: SO, destination_kind: SK, source_kind: SK, destination_window: xproto::Window, x_offset: i16, y_offset: i16, source_window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CombineRequest { operation, destination_kind, source_kind, destination_window, x_offset, y_offset, source_window, }; request0.send(conn) } /// Opcode for the Offset request pub const OFFSET_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OffsetRequest { pub destination_kind: SK, pub destination_window: xproto::Window, pub x_offset: i16, pub y_offset: i16, } impl OffsetRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let destination_kind_bytes = Kind::from(self.destination_kind).serialize(); let destination_window_bytes = self.destination_window.serialize(); let x_offset_bytes = self.x_offset.serialize(); let y_offset_bytes = self.y_offset.serialize(); let mut request0 = vec![ extension_information.major_opcode, OFFSET_REQUEST, 0, 0, destination_kind_bytes[0], 0, 0, 0, destination_window_bytes[0], destination_window_bytes[1], destination_window_bytes[2], destination_window_bytes[3], x_offset_bytes[0], x_offset_bytes[1], y_offset_bytes[0], y_offset_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != OFFSET_REQUEST { return Err(ParseError::InvalidValue); } let (destination_kind, remaining) = Kind::try_parse(value)?; let destination_kind = destination_kind.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (destination_window, remaining) = xproto::Window::try_parse(remaining)?; let (x_offset, remaining) = i16::try_parse(remaining)?; let (y_offset, remaining) = i16::try_parse(remaining)?; let _ = remaining; Ok(OffsetRequest { destination_kind, destination_window, x_offset, y_offset, }) } } impl Request for OffsetRequest { type Reply = (); } pub fn offset(conn: &Conn, destination_kind: SK, destination_window: xproto::Window, x_offset: i16, y_offset: i16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = OffsetRequest { destination_kind, destination_window, x_offset, y_offset, }; request0.send(conn) } /// Opcode for the QueryExtents request pub const QUERY_EXTENTS_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryExtentsRequest { pub destination_window: xproto::Window, } impl QueryExtentsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let destination_window_bytes = self.destination_window.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_EXTENTS_REQUEST, 0, 0, destination_window_bytes[0], destination_window_bytes[1], destination_window_bytes[2], destination_window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_EXTENTS_REQUEST { return Err(ParseError::InvalidValue); } let (destination_window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(QueryExtentsRequest { destination_window, }) } } impl Request for QueryExtentsRequest { type Reply = QueryExtentsReply; } pub fn query_extents(conn: &Conn, destination_window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryExtentsRequest { destination_window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryExtentsReply { pub sequence: u16, pub length: u32, pub bounding_shaped: bool, pub clip_shaped: bool, pub bounding_shape_extents_x: i16, pub bounding_shape_extents_y: i16, pub bounding_shape_extents_width: u16, pub bounding_shape_extents_height: u16, pub clip_shape_extents_x: i16, pub clip_shape_extents_y: i16, pub clip_shape_extents_width: u16, pub clip_shape_extents_height: u16, } impl TryParse for QueryExtentsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (bounding_shaped, remaining) = bool::try_parse(remaining)?; let (clip_shaped, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (bounding_shape_extents_x, remaining) = i16::try_parse(remaining)?; let (bounding_shape_extents_y, remaining) = i16::try_parse(remaining)?; let (bounding_shape_extents_width, remaining) = u16::try_parse(remaining)?; let (bounding_shape_extents_height, remaining) = u16::try_parse(remaining)?; let (clip_shape_extents_x, remaining) = i16::try_parse(remaining)?; let (clip_shape_extents_y, remaining) = i16::try_parse(remaining)?; let (clip_shape_extents_width, remaining) = u16::try_parse(remaining)?; let (clip_shape_extents_height, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryExtentsReply { sequence, length, bounding_shaped, clip_shaped, bounding_shape_extents_x, bounding_shape_extents_y, bounding_shape_extents_width, bounding_shape_extents_height, clip_shape_extents_x, clip_shape_extents_y, clip_shape_extents_width, clip_shape_extents_height }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SelectInput request pub const SELECT_INPUT_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectInputRequest { pub destination_window: xproto::Window, pub enable: bool, } impl SelectInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let destination_window_bytes = self.destination_window.serialize(); let enable_bytes = self.enable.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_INPUT_REQUEST, 0, 0, destination_window_bytes[0], destination_window_bytes[1], destination_window_bytes[2], destination_window_bytes[3], enable_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (destination_window, remaining) = xproto::Window::try_parse(value)?; let (enable, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SelectInputRequest { destination_window, enable, }) } } impl Request for SelectInputRequest { type Reply = (); } pub fn select_input(conn: &Conn, destination_window: xproto::Window, enable: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SelectInputRequest { destination_window, enable, }; request0.send(conn) } /// Opcode for the InputSelected request pub const INPUT_SELECTED_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InputSelectedRequest { pub destination_window: xproto::Window, } impl InputSelectedRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let destination_window_bytes = self.destination_window.serialize(); let mut request0 = vec![ extension_information.major_opcode, INPUT_SELECTED_REQUEST, 0, 0, destination_window_bytes[0], destination_window_bytes[1], destination_window_bytes[2], destination_window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != INPUT_SELECTED_REQUEST { return Err(ParseError::InvalidValue); } let (destination_window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(InputSelectedRequest { destination_window, }) } } impl Request for InputSelectedRequest { type Reply = InputSelectedReply; } pub fn input_selected(conn: &Conn, destination_window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = InputSelectedRequest { destination_window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InputSelectedReply { pub enabled: bool, pub sequence: u16, pub length: u32, } impl TryParse for InputSelectedReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (enabled, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = InputSelectedReply { enabled, sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetRectangles request pub const GET_RECTANGLES_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetRectanglesRequest { pub window: xproto::Window, pub source_kind: SK, } impl GetRectanglesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let source_kind_bytes = Kind::from(self.source_kind).serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_RECTANGLES_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], source_kind_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_RECTANGLES_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (source_kind, remaining) = Kind::try_parse(remaining)?; let source_kind = source_kind.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetRectanglesRequest { window, source_kind, }) } } impl Request for GetRectanglesRequest { type Reply = GetRectanglesReply; } pub fn get_rectangles(conn: &Conn, window: xproto::Window, source_kind: SK) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetRectanglesRequest { window, source_kind, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetRectanglesReply { pub ordering: xproto::ClipOrdering, pub sequence: u16, pub length: u32, pub rectangles: Vec, } impl TryParse for GetRectanglesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (ordering, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (rectangles_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (rectangles, remaining) = crate::x11_utils::parse_list::(remaining, rectangles_len.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let ordering = ordering.into(); let result = GetRectanglesReply { ordering, sequence, length, rectangles }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetRectanglesReply { /// Get the value of the `rectangles_len` field. /// /// The `rectangles_len` field is used as the length field of the `rectangles` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn rectangles_len(&self) -> u32 { self.rectangles.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn shape_query_version(&self) -> Result, ConnectionError> { query_version(self) } fn shape_rectangles<'c, 'input>(&'c self, operation: SO, destination_kind: SK, ordering: xproto::ClipOrdering, destination_window: xproto::Window, x_offset: i16, y_offset: i16, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> { self::rectangles(self, operation, destination_kind, ordering, destination_window, x_offset, y_offset, rectangles) } fn shape_mask(&self, operation: SO, destination_kind: SK, destination_window: xproto::Window, x_offset: i16, y_offset: i16, source_bitmap: A) -> Result, ConnectionError> where A: Into, { mask(self, operation, destination_kind, destination_window, x_offset, y_offset, source_bitmap) } fn shape_combine(&self, operation: SO, destination_kind: SK, source_kind: SK, destination_window: xproto::Window, x_offset: i16, y_offset: i16, source_window: xproto::Window) -> Result, ConnectionError> { combine(self, operation, destination_kind, source_kind, destination_window, x_offset, y_offset, source_window) } fn shape_offset(&self, destination_kind: SK, destination_window: xproto::Window, x_offset: i16, y_offset: i16) -> Result, ConnectionError> { offset(self, destination_kind, destination_window, x_offset, y_offset) } fn shape_query_extents(&self, destination_window: xproto::Window) -> Result, ConnectionError> { query_extents(self, destination_window) } fn shape_select_input(&self, destination_window: xproto::Window, enable: bool) -> Result, ConnectionError> { select_input(self, destination_window, enable) } fn shape_input_selected(&self, destination_window: xproto::Window) -> Result, ConnectionError> { input_selected(self, destination_window) } fn shape_get_rectangles(&self, window: xproto::Window, source_kind: SK) -> Result, ConnectionError> { get_rectangles(self, window, source_kind) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/shm.rs010064400017500001750000001123131402220031600144120ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Shm` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "MIT-SHM"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 2); pub type Seg = u32; /// Opcode for the Completion event pub const COMPLETION_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CompletionEvent { pub response_type: u8, pub sequence: u16, pub drawable: xproto::Drawable, pub minor_event: u16, pub major_event: u8, pub shmseg: Seg, pub offset: u32, } impl TryParse for CompletionEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (minor_event, remaining) = u16::try_parse(remaining)?; let (major_event, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (shmseg, remaining) = Seg::try_parse(remaining)?; let (offset, remaining) = u32::try_parse(remaining)?; let result = CompletionEvent { response_type, sequence, drawable, minor_event, major_event, shmseg, offset }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&CompletionEvent> for [u8; 32] { fn from(input: &CompletionEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let drawable_bytes = input.drawable.serialize(); let minor_event_bytes = input.minor_event.serialize(); let major_event_bytes = input.major_event.serialize(); let shmseg_bytes = input.shmseg.serialize(); let offset_bytes = input.offset.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], minor_event_bytes[0], minor_event_bytes[1], major_event_bytes[0], 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], offset_bytes[0], offset_bytes[1], offset_bytes[2], offset_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: CompletionEvent) -> Self { Self::from(&input) } } /// Opcode for the BadSeg error pub const BAD_SEG_ERROR: u8 = 0; /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest; impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryVersionRequest ) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub shared_pixmaps: bool, pub sequence: u16, pub length: u32, pub major_version: u16, pub minor_version: u16, pub uid: u16, pub gid: u16, pub pixmap_format: u8, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (shared_pixmaps, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u16::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; let (uid, remaining) = u16::try_parse(remaining)?; let (gid, remaining) = u16::try_parse(remaining)?; let (pixmap_format, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(15..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { shared_pixmaps, sequence, length, major_version, minor_version, uid, gid, pixmap_format }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Attach request pub const ATTACH_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AttachRequest { pub shmseg: Seg, pub shmid: u32, pub read_only: bool, } impl AttachRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let shmseg_bytes = self.shmseg.serialize(); let shmid_bytes = self.shmid.serialize(); let read_only_bytes = self.read_only.serialize(); let mut request0 = vec![ extension_information.major_opcode, ATTACH_REQUEST, 0, 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], shmid_bytes[0], shmid_bytes[1], shmid_bytes[2], shmid_bytes[3], read_only_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != ATTACH_REQUEST { return Err(ParseError::InvalidValue); } let (shmseg, remaining) = Seg::try_parse(value)?; let (shmid, remaining) = u32::try_parse(remaining)?; let (read_only, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(AttachRequest { shmseg, shmid, read_only, }) } } impl Request for AttachRequest { type Reply = (); } pub fn attach(conn: &Conn, shmseg: Seg, shmid: u32, read_only: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AttachRequest { shmseg, shmid, read_only, }; request0.send(conn) } /// Opcode for the Detach request pub const DETACH_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DetachRequest { pub shmseg: Seg, } impl DetachRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let shmseg_bytes = self.shmseg.serialize(); let mut request0 = vec![ extension_information.major_opcode, DETACH_REQUEST, 0, 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DETACH_REQUEST { return Err(ParseError::InvalidValue); } let (shmseg, remaining) = Seg::try_parse(value)?; let _ = remaining; Ok(DetachRequest { shmseg, }) } } impl Request for DetachRequest { type Reply = (); } pub fn detach(conn: &Conn, shmseg: Seg) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DetachRequest { shmseg, }; request0.send(conn) } /// Opcode for the PutImage request pub const PUT_IMAGE_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PutImageRequest { pub drawable: xproto::Drawable, pub gc: xproto::Gcontext, pub total_width: u16, pub total_height: u16, pub src_x: u16, pub src_y: u16, pub src_width: u16, pub src_height: u16, pub dst_x: i16, pub dst_y: i16, pub depth: u8, pub format: u8, pub send_event: bool, pub shmseg: Seg, pub offset: u32, } impl PutImageRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let gc_bytes = self.gc.serialize(); let total_width_bytes = self.total_width.serialize(); let total_height_bytes = self.total_height.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let src_width_bytes = self.src_width.serialize(); let src_height_bytes = self.src_height.serialize(); let dst_x_bytes = self.dst_x.serialize(); let dst_y_bytes = self.dst_y.serialize(); let depth_bytes = self.depth.serialize(); let format_bytes = self.format.serialize(); let send_event_bytes = self.send_event.serialize(); let shmseg_bytes = self.shmseg.serialize(); let offset_bytes = self.offset.serialize(); let mut request0 = vec![ extension_information.major_opcode, PUT_IMAGE_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], total_width_bytes[0], total_width_bytes[1], total_height_bytes[0], total_height_bytes[1], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], src_width_bytes[0], src_width_bytes[1], src_height_bytes[0], src_height_bytes[1], dst_x_bytes[0], dst_x_bytes[1], dst_y_bytes[0], dst_y_bytes[1], depth_bytes[0], format_bytes[0], send_event_bytes[0], 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], offset_bytes[0], offset_bytes[1], offset_bytes[2], offset_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PUT_IMAGE_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let (total_width, remaining) = u16::try_parse(remaining)?; let (total_height, remaining) = u16::try_parse(remaining)?; let (src_x, remaining) = u16::try_parse(remaining)?; let (src_y, remaining) = u16::try_parse(remaining)?; let (src_width, remaining) = u16::try_parse(remaining)?; let (src_height, remaining) = u16::try_parse(remaining)?; let (dst_x, remaining) = i16::try_parse(remaining)?; let (dst_y, remaining) = i16::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (send_event, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (shmseg, remaining) = Seg::try_parse(remaining)?; let (offset, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(PutImageRequest { drawable, gc, total_width, total_height, src_x, src_y, src_width, src_height, dst_x, dst_y, depth, format, send_event, shmseg, offset, }) } } impl Request for PutImageRequest { type Reply = (); } pub fn put_image(conn: &Conn, drawable: xproto::Drawable, gc: xproto::Gcontext, total_width: u16, total_height: u16, src_x: u16, src_y: u16, src_width: u16, src_height: u16, dst_x: i16, dst_y: i16, depth: u8, format: u8, send_event: bool, shmseg: Seg, offset: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PutImageRequest { drawable, gc, total_width, total_height, src_x, src_y, src_width, src_height, dst_x, dst_y, depth, format, send_event, shmseg, offset, }; request0.send(conn) } /// Opcode for the GetImage request pub const GET_IMAGE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetImageRequest { pub drawable: xproto::Drawable, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub plane_mask: u32, pub format: u8, pub shmseg: Seg, pub offset: u32, } impl GetImageRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let plane_mask_bytes = self.plane_mask.serialize(); let format_bytes = self.format.serialize(); let shmseg_bytes = self.shmseg.serialize(); let offset_bytes = self.offset.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_IMAGE_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], plane_mask_bytes[0], plane_mask_bytes[1], plane_mask_bytes[2], plane_mask_bytes[3], format_bytes[0], 0, 0, 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], offset_bytes[0], offset_bytes[1], offset_bytes[2], offset_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_IMAGE_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (plane_mask, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (shmseg, remaining) = Seg::try_parse(remaining)?; let (offset, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetImageRequest { drawable, x, y, width, height, plane_mask, format, shmseg, offset, }) } } impl Request for GetImageRequest { type Reply = GetImageReply; } pub fn get_image(conn: &Conn, drawable: xproto::Drawable, x: i16, y: i16, width: u16, height: u16, plane_mask: u32, format: u8, shmseg: Seg, offset: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetImageRequest { drawable, x, y, width, height, plane_mask, format, shmseg, offset, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetImageReply { pub depth: u8, pub sequence: u16, pub length: u32, pub visual: xproto::Visualid, pub size: u32, } impl TryParse for GetImageReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (size, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetImageReply { depth, sequence, length, visual, size }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the CreatePixmap request pub const CREATE_PIXMAP_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreatePixmapRequest { pub pid: xproto::Pixmap, pub drawable: xproto::Drawable, pub width: u16, pub height: u16, pub depth: u8, pub shmseg: Seg, pub offset: u32, } impl CreatePixmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let pid_bytes = self.pid.serialize(); let drawable_bytes = self.drawable.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let depth_bytes = self.depth.serialize(); let shmseg_bytes = self.shmseg.serialize(); let offset_bytes = self.offset.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_PIXMAP_REQUEST, 0, 0, pid_bytes[0], pid_bytes[1], pid_bytes[2], pid_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], depth_bytes[0], 0, 0, 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], offset_bytes[0], offset_bytes[1], offset_bytes[2], offset_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_PIXMAP_REQUEST { return Err(ParseError::InvalidValue); } let (pid, remaining) = xproto::Pixmap::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (shmseg, remaining) = Seg::try_parse(remaining)?; let (offset, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(CreatePixmapRequest { pid, drawable, width, height, depth, shmseg, offset, }) } } impl Request for CreatePixmapRequest { type Reply = (); } pub fn create_pixmap(conn: &Conn, pid: xproto::Pixmap, drawable: xproto::Drawable, width: u16, height: u16, depth: u8, shmseg: Seg, offset: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreatePixmapRequest { pid, drawable, width, height, depth, shmseg, offset, }; request0.send(conn) } /// Opcode for the AttachFd request pub const ATTACH_FD_REQUEST: u8 = 6; #[derive(Debug, PartialEq, Eq)] pub struct AttachFdRequest { pub shmseg: Seg, pub shm_fd: RawFdContainer, pub read_only: bool, } impl AttachFdRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let shmseg_bytes = self.shmseg.serialize(); let read_only_bytes = self.read_only.serialize(); let mut request0 = vec![ extension_information.major_opcode, ATTACH_FD_REQUEST, 0, 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], read_only_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![self.shm_fd])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request_fd(header: RequestHeader, value: &[u8], fds: &mut Vec) -> Result { if header.minor_opcode != ATTACH_FD_REQUEST { return Err(ParseError::InvalidValue); } let (shmseg, remaining) = Seg::try_parse(value)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let shm_fd = fds.remove(0); let (read_only, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(AttachFdRequest { shmseg, shm_fd, read_only, }) } } impl Request for AttachFdRequest { type Reply = (); } pub fn attach_fd(conn: &Conn, shmseg: Seg, shm_fd: A, read_only: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let shm_fd: RawFdContainer = shm_fd.into(); let request0 = AttachFdRequest { shmseg, shm_fd, read_only, }; request0.send(conn) } /// Opcode for the CreateSegment request pub const CREATE_SEGMENT_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateSegmentRequest { pub shmseg: Seg, pub size: u32, pub read_only: bool, } impl CreateSegmentRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let shmseg_bytes = self.shmseg.serialize(); let size_bytes = self.size.serialize(); let read_only_bytes = self.read_only.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_SEGMENT_REQUEST, 0, 0, shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], size_bytes[0], size_bytes[1], size_bytes[2], size_bytes[3], read_only_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply_with_fds(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_SEGMENT_REQUEST { return Err(ParseError::InvalidValue); } let (shmseg, remaining) = Seg::try_parse(value)?; let (size, remaining) = u32::try_parse(remaining)?; let (read_only, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(CreateSegmentRequest { shmseg, size, read_only, }) } } impl Request for CreateSegmentRequest { type Reply = CreateSegmentReply; } pub fn create_segment(conn: &Conn, shmseg: Seg, size: u32, read_only: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateSegmentRequest { shmseg, size, read_only, }; request0.send(conn) } #[derive(Debug, PartialEq, Eq)] pub struct CreateSegmentReply { pub nfd: u8, pub sequence: u16, pub length: u32, pub shm_fd: RawFdContainer, } impl TryParseFd for CreateSegmentReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if fds.is_empty() { return Err(ParseError::MissingFileDescriptors) } let shm_fd = fds.remove(0); let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateSegmentReply { nfd, sequence, length, shm_fd }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn shm_query_version(&self) -> Result, ConnectionError> { query_version(self) } fn shm_attach(&self, shmseg: Seg, shmid: u32, read_only: bool) -> Result, ConnectionError> { attach(self, shmseg, shmid, read_only) } fn shm_detach(&self, shmseg: Seg) -> Result, ConnectionError> { detach(self, shmseg) } fn shm_put_image(&self, drawable: xproto::Drawable, gc: xproto::Gcontext, total_width: u16, total_height: u16, src_x: u16, src_y: u16, src_width: u16, src_height: u16, dst_x: i16, dst_y: i16, depth: u8, format: u8, send_event: bool, shmseg: Seg, offset: u32) -> Result, ConnectionError> { put_image(self, drawable, gc, total_width, total_height, src_x, src_y, src_width, src_height, dst_x, dst_y, depth, format, send_event, shmseg, offset) } fn shm_get_image(&self, drawable: xproto::Drawable, x: i16, y: i16, width: u16, height: u16, plane_mask: u32, format: u8, shmseg: Seg, offset: u32) -> Result, ConnectionError> { get_image(self, drawable, x, y, width, height, plane_mask, format, shmseg, offset) } fn shm_create_pixmap(&self, pid: xproto::Pixmap, drawable: xproto::Drawable, width: u16, height: u16, depth: u8, shmseg: Seg, offset: u32) -> Result, ConnectionError> { create_pixmap(self, pid, drawable, width, height, depth, shmseg, offset) } fn shm_attach_fd(&self, shmseg: Seg, shm_fd: A, read_only: bool) -> Result, ConnectionError> where A: Into, { attach_fd(self, shmseg, shm_fd, read_only) } fn shm_create_segment(&self, shmseg: Seg, size: u32, read_only: bool) -> Result, ConnectionError> { create_segment(self, shmseg, size, read_only) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/sync.rs010064400017500001750000002726201402220031600146070ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Sync` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "SYNC"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (3, 1); pub type Alarm = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct ALARMSTATE(u8); impl ALARMSTATE { pub const ACTIVE: Self = Self(0); pub const INACTIVE: Self = Self(1); pub const DESTROYED: Self = Self(2); } impl From for u8 { #[inline] fn from(input: ALARMSTATE) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ALARMSTATE) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ALARMSTATE) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ALARMSTATE) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ALARMSTATE) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ALARMSTATE) -> Self { Some(u32::from(input.0)) } } impl From for ALARMSTATE { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ALARMSTATE { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ACTIVE.0.into(), "ACTIVE", "Active"), (Self::INACTIVE.0.into(), "INACTIVE", "Inactive"), (Self::DESTROYED.0.into(), "DESTROYED", "Destroyed"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } pub type Counter = u32; pub type Fence = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct TESTTYPE(u32); impl TESTTYPE { pub const POSITIVE_TRANSITION: Self = Self(0); pub const NEGATIVE_TRANSITION: Self = Self(1); pub const POSITIVE_COMPARISON: Self = Self(2); pub const NEGATIVE_COMPARISON: Self = Self(3); } impl From for u32 { #[inline] fn from(input: TESTTYPE) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: TESTTYPE) -> Self { Some(input.0) } } impl From for TESTTYPE { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for TESTTYPE { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for TESTTYPE { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for TESTTYPE { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::POSITIVE_TRANSITION.0, "POSITIVE_TRANSITION", "PositiveTransition"), (Self::NEGATIVE_TRANSITION.0, "NEGATIVE_TRANSITION", "NegativeTransition"), (Self::POSITIVE_COMPARISON.0, "POSITIVE_COMPARISON", "PositiveComparison"), (Self::NEGATIVE_COMPARISON.0, "NEGATIVE_COMPARISON", "NegativeComparison"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct VALUETYPE(u32); impl VALUETYPE { pub const ABSOLUTE: Self = Self(0); pub const RELATIVE: Self = Self(1); } impl From for u32 { #[inline] fn from(input: VALUETYPE) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: VALUETYPE) -> Self { Some(input.0) } } impl From for VALUETYPE { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for VALUETYPE { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for VALUETYPE { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for VALUETYPE { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ABSOLUTE.0, "ABSOLUTE", "Absolute"), (Self::RELATIVE.0, "RELATIVE", "Relative"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct CA(u8); impl CA { pub const COUNTER: Self = Self(1 << 0); pub const VALUE_TYPE: Self = Self(1 << 1); pub const VALUE: Self = Self(1 << 2); pub const TEST_TYPE: Self = Self(1 << 3); pub const DELTA: Self = Self(1 << 4); pub const EVENTS: Self = Self(1 << 5); } impl From for u8 { #[inline] fn from(input: CA) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: CA) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: CA) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: CA) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: CA) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: CA) -> Self { Some(u32::from(input.0)) } } impl From for CA { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for CA { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::COUNTER.0.into(), "COUNTER", "Counter"), (Self::VALUE_TYPE.0.into(), "VALUE_TYPE", "ValueType"), (Self::VALUE.0.into(), "VALUE", "Value"), (Self::TEST_TYPE.0.into(), "TEST_TYPE", "TestType"), (Self::DELTA.0.into(), "DELTA", "Delta"), (Self::EVENTS.0.into(), "EVENTS", "Events"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(CA, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Int64 { pub hi: i32, pub lo: u32, } impl TryParse for Int64 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (hi, remaining) = i32::try_parse(remaining)?; let (lo, remaining) = u32::try_parse(remaining)?; let result = Int64 { hi, lo }; Ok((result, remaining)) } } impl Serialize for Int64 { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let hi_bytes = self.hi.serialize(); let lo_bytes = self.lo.serialize(); [ hi_bytes[0], hi_bytes[1], hi_bytes[2], hi_bytes[3], lo_bytes[0], lo_bytes[1], lo_bytes[2], lo_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.hi.serialize_into(bytes); self.lo.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Systemcounter { pub counter: Counter, pub resolution: Int64, pub name: Vec, } impl TryParse for Systemcounter { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (counter, remaining) = Counter::try_parse(remaining)?; let (resolution, remaining) = Int64::try_parse(remaining)?; let (name_len, remaining) = u16::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = Systemcounter { counter, resolution, name }; Ok((result, remaining)) } } impl Serialize for Systemcounter { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(14); self.counter.serialize_into(bytes); self.resolution.serialize_into(bytes); let name_len = u16::try_from(self.name.len()).expect("`name` has too many elements"); name_len.serialize_into(bytes); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl Systemcounter { /// Get the value of the `name_len` field. /// /// The `name_len` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u16 { self.name.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Trigger { pub counter: Counter, pub wait_type: VALUETYPE, pub wait_value: Int64, pub test_type: TESTTYPE, } impl TryParse for Trigger { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (counter, remaining) = Counter::try_parse(remaining)?; let (wait_type, remaining) = u32::try_parse(remaining)?; let (wait_value, remaining) = Int64::try_parse(remaining)?; let (test_type, remaining) = u32::try_parse(remaining)?; let wait_type = wait_type.into(); let test_type = test_type.into(); let result = Trigger { counter, wait_type, wait_value, test_type }; Ok((result, remaining)) } } impl Serialize for Trigger { type Bytes = [u8; 20]; fn serialize(&self) -> [u8; 20] { let counter_bytes = self.counter.serialize(); let wait_type_bytes = u32::from(self.wait_type).serialize(); let wait_value_bytes = self.wait_value.serialize(); let test_type_bytes = u32::from(self.test_type).serialize(); [ counter_bytes[0], counter_bytes[1], counter_bytes[2], counter_bytes[3], wait_type_bytes[0], wait_type_bytes[1], wait_type_bytes[2], wait_type_bytes[3], wait_value_bytes[0], wait_value_bytes[1], wait_value_bytes[2], wait_value_bytes[3], wait_value_bytes[4], wait_value_bytes[5], wait_value_bytes[6], wait_value_bytes[7], test_type_bytes[0], test_type_bytes[1], test_type_bytes[2], test_type_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(20); self.counter.serialize_into(bytes); u32::from(self.wait_type).serialize_into(bytes); self.wait_value.serialize_into(bytes); u32::from(self.test_type).serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Waitcondition { pub trigger: Trigger, pub event_threshold: Int64, } impl TryParse for Waitcondition { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (trigger, remaining) = Trigger::try_parse(remaining)?; let (event_threshold, remaining) = Int64::try_parse(remaining)?; let result = Waitcondition { trigger, event_threshold }; Ok((result, remaining)) } } impl Serialize for Waitcondition { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let trigger_bytes = self.trigger.serialize(); let event_threshold_bytes = self.event_threshold.serialize(); [ trigger_bytes[0], trigger_bytes[1], trigger_bytes[2], trigger_bytes[3], trigger_bytes[4], trigger_bytes[5], trigger_bytes[6], trigger_bytes[7], trigger_bytes[8], trigger_bytes[9], trigger_bytes[10], trigger_bytes[11], trigger_bytes[12], trigger_bytes[13], trigger_bytes[14], trigger_bytes[15], trigger_bytes[16], trigger_bytes[17], trigger_bytes[18], trigger_bytes[19], event_threshold_bytes[0], event_threshold_bytes[1], event_threshold_bytes[2], event_threshold_bytes[3], event_threshold_bytes[4], event_threshold_bytes[5], event_threshold_bytes[6], event_threshold_bytes[7], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); self.trigger.serialize_into(bytes); self.event_threshold.serialize_into(bytes); } } /// Opcode for the Counter error pub const COUNTER_ERROR: u8 = 0; /// Opcode for the Alarm error pub const ALARM_ERROR: u8 = 1; /// Opcode for the Initialize request pub const INITIALIZE_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InitializeRequest { pub desired_major_version: u8, pub desired_minor_version: u8, } impl InitializeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let desired_major_version_bytes = self.desired_major_version.serialize(); let desired_minor_version_bytes = self.desired_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, INITIALIZE_REQUEST, 0, 0, desired_major_version_bytes[0], desired_minor_version_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != INITIALIZE_REQUEST { return Err(ParseError::InvalidValue); } let (desired_major_version, remaining) = u8::try_parse(value)?; let (desired_minor_version, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(InitializeRequest { desired_major_version, desired_minor_version, }) } } impl Request for InitializeRequest { type Reply = InitializeReply; } pub fn initialize(conn: &Conn, desired_major_version: u8, desired_minor_version: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = InitializeRequest { desired_major_version, desired_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InitializeReply { pub sequence: u16, pub length: u32, pub major_version: u8, pub minor_version: u8, } impl TryParse for InitializeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u8::try_parse(remaining)?; let (minor_version, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = InitializeReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the ListSystemCounters request pub const LIST_SYSTEM_COUNTERS_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListSystemCountersRequest; impl ListSystemCountersRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, LIST_SYSTEM_COUNTERS_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_SYSTEM_COUNTERS_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(ListSystemCountersRequest ) } } impl Request for ListSystemCountersRequest { type Reply = ListSystemCountersReply; } pub fn list_system_counters(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListSystemCountersRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListSystemCountersReply { pub sequence: u16, pub length: u32, pub counters: Vec, } impl TryParse for ListSystemCountersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (counters_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (counters, remaining) = crate::x11_utils::parse_list::(remaining, counters_len.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListSystemCountersReply { sequence, length, counters }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListSystemCountersReply { /// Get the value of the `counters_len` field. /// /// The `counters_len` field is used as the length field of the `counters` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn counters_len(&self) -> u32 { self.counters.len() .try_into().unwrap() } } /// Opcode for the CreateCounter request pub const CREATE_COUNTER_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateCounterRequest { pub id: Counter, pub initial_value: Int64, } impl CreateCounterRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let id_bytes = self.id.serialize(); let initial_value_bytes = self.initial_value.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_COUNTER_REQUEST, 0, 0, id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], initial_value_bytes[0], initial_value_bytes[1], initial_value_bytes[2], initial_value_bytes[3], initial_value_bytes[4], initial_value_bytes[5], initial_value_bytes[6], initial_value_bytes[7], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_COUNTER_REQUEST { return Err(ParseError::InvalidValue); } let (id, remaining) = Counter::try_parse(value)?; let (initial_value, remaining) = Int64::try_parse(remaining)?; let _ = remaining; Ok(CreateCounterRequest { id, initial_value, }) } } impl Request for CreateCounterRequest { type Reply = (); } pub fn create_counter(conn: &Conn, id: Counter, initial_value: Int64) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateCounterRequest { id, initial_value, }; request0.send(conn) } /// Opcode for the DestroyCounter request pub const DESTROY_COUNTER_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyCounterRequest { pub counter: Counter, } impl DestroyCounterRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let counter_bytes = self.counter.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_COUNTER_REQUEST, 0, 0, counter_bytes[0], counter_bytes[1], counter_bytes[2], counter_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_COUNTER_REQUEST { return Err(ParseError::InvalidValue); } let (counter, remaining) = Counter::try_parse(value)?; let _ = remaining; Ok(DestroyCounterRequest { counter, }) } } impl Request for DestroyCounterRequest { type Reply = (); } pub fn destroy_counter(conn: &Conn, counter: Counter) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyCounterRequest { counter, }; request0.send(conn) } /// Opcode for the QueryCounter request pub const QUERY_COUNTER_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryCounterRequest { pub counter: Counter, } impl QueryCounterRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let counter_bytes = self.counter.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_COUNTER_REQUEST, 0, 0, counter_bytes[0], counter_bytes[1], counter_bytes[2], counter_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_COUNTER_REQUEST { return Err(ParseError::InvalidValue); } let (counter, remaining) = Counter::try_parse(value)?; let _ = remaining; Ok(QueryCounterRequest { counter, }) } } impl Request for QueryCounterRequest { type Reply = QueryCounterReply; } pub fn query_counter(conn: &Conn, counter: Counter) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryCounterRequest { counter, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryCounterReply { pub sequence: u16, pub length: u32, pub counter_value: Int64, } impl TryParse for QueryCounterReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (counter_value, remaining) = Int64::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryCounterReply { sequence, length, counter_value }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Await request pub const AWAIT_REQUEST: u8 = 7; #[derive(Debug, Clone, PartialEq, Eq)] pub struct AwaitRequest<'input> { pub wait_list: Cow<'input, [Waitcondition]>, } impl<'input> AwaitRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, AWAIT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); let wait_list_bytes = self.wait_list.serialize(); let length_so_far = length_so_far + wait_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), wait_list_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != AWAIT_REQUEST { return Err(ParseError::InvalidValue); } let mut remaining = value; // Length is 'everything left in the input' let mut wait_list = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Waitcondition::try_parse(value)?; remaining = new_remaining; wait_list.push(v); } let _ = remaining; Ok(AwaitRequest { wait_list: Cow::Owned(wait_list), }) } /// Clone all borrowed data in this AwaitRequest. pub fn into_owned(self) -> AwaitRequest<'static> { AwaitRequest { wait_list: Cow::Owned(self.wait_list.into_owned()), } } } impl<'input> Request for AwaitRequest<'input> { type Reply = (); } pub fn await_<'c, 'input, Conn>(conn: &'c Conn, wait_list: &'input [Waitcondition]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AwaitRequest { wait_list: Cow::Borrowed(wait_list), }; request0.send(conn) } /// Opcode for the ChangeCounter request pub const CHANGE_COUNTER_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangeCounterRequest { pub counter: Counter, pub amount: Int64, } impl ChangeCounterRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let counter_bytes = self.counter.serialize(); let amount_bytes = self.amount.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_COUNTER_REQUEST, 0, 0, counter_bytes[0], counter_bytes[1], counter_bytes[2], counter_bytes[3], amount_bytes[0], amount_bytes[1], amount_bytes[2], amount_bytes[3], amount_bytes[4], amount_bytes[5], amount_bytes[6], amount_bytes[7], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CHANGE_COUNTER_REQUEST { return Err(ParseError::InvalidValue); } let (counter, remaining) = Counter::try_parse(value)?; let (amount, remaining) = Int64::try_parse(remaining)?; let _ = remaining; Ok(ChangeCounterRequest { counter, amount, }) } } impl Request for ChangeCounterRequest { type Reply = (); } pub fn change_counter(conn: &Conn, counter: Counter, amount: Int64) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeCounterRequest { counter, amount, }; request0.send(conn) } /// Opcode for the SetCounter request pub const SET_COUNTER_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetCounterRequest { pub counter: Counter, pub value: Int64, } impl SetCounterRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let counter_bytes = self.counter.serialize(); let value_bytes = self.value.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_COUNTER_REQUEST, 0, 0, counter_bytes[0], counter_bytes[1], counter_bytes[2], counter_bytes[3], value_bytes[0], value_bytes[1], value_bytes[2], value_bytes[3], value_bytes[4], value_bytes[5], value_bytes[6], value_bytes[7], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_COUNTER_REQUEST { return Err(ParseError::InvalidValue); } let (counter, remaining) = Counter::try_parse(value)?; let (value, remaining) = Int64::try_parse(remaining)?; let _ = remaining; Ok(SetCounterRequest { counter, value, }) } } impl Request for SetCounterRequest { type Reply = (); } pub fn set_counter(conn: &Conn, counter: Counter, value: Int64) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetCounterRequest { counter, value, }; request0.send(conn) } /// Auxiliary and optional information for the `create_alarm` function #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct CreateAlarmAux { pub counter: Option, pub value_type: Option, pub value: Option, pub test_type: Option, pub delta: Option, pub events: Option, } impl CreateAlarmAux { fn try_parse(value: &[u8], value_mask: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = value_mask; let mut outer_remaining = value; let counter = if switch_expr & u32::from(CA::COUNTER) != 0 { let remaining = outer_remaining; let (counter, remaining) = Counter::try_parse(remaining)?; outer_remaining = remaining; Some(counter) } else { None }; let value_type = if switch_expr & u32::from(CA::VALUE_TYPE) != 0 { let remaining = outer_remaining; let (value_type, remaining) = u32::try_parse(remaining)?; let value_type = value_type.into(); outer_remaining = remaining; Some(value_type) } else { None }; let value = if switch_expr & u32::from(CA::VALUE) != 0 { let remaining = outer_remaining; let (value, remaining) = Int64::try_parse(remaining)?; outer_remaining = remaining; Some(value) } else { None }; let test_type = if switch_expr & u32::from(CA::TEST_TYPE) != 0 { let remaining = outer_remaining; let (test_type, remaining) = u32::try_parse(remaining)?; let test_type = test_type.into(); outer_remaining = remaining; Some(test_type) } else { None }; let delta = if switch_expr & u32::from(CA::DELTA) != 0 { let remaining = outer_remaining; let (delta, remaining) = Int64::try_parse(remaining)?; outer_remaining = remaining; Some(delta) } else { None }; let events = if switch_expr & u32::from(CA::EVENTS) != 0 { let remaining = outer_remaining; let (events, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(events) } else { None }; let result = CreateAlarmAux { counter, value_type, value, test_type, delta, events }; Ok((result, outer_remaining)) } } impl CreateAlarmAux { #[allow(dead_code)] fn serialize(&self, value_mask: u32) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, value_mask); result } fn serialize_into(&self, bytes: &mut Vec, value_mask: u32) { assert_eq!(self.switch_expr(), value_mask, "switch `value_list` has an inconsistent discriminant"); if let Some(counter) = self.counter { counter.serialize_into(bytes); } if let Some(value_type) = self.value_type { u32::from(value_type).serialize_into(bytes); } if let Some(ref value) = self.value { value.serialize_into(bytes); } if let Some(test_type) = self.test_type { u32::from(test_type).serialize_into(bytes); } if let Some(ref delta) = self.delta { delta.serialize_into(bytes); } if let Some(events) = self.events { events.serialize_into(bytes); } } } impl CreateAlarmAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.counter.is_some() { expr_value |= u32::from(CA::COUNTER); } if self.value_type.is_some() { expr_value |= u32::from(CA::VALUE_TYPE); } if self.value.is_some() { expr_value |= u32::from(CA::VALUE); } if self.test_type.is_some() { expr_value |= u32::from(CA::TEST_TYPE); } if self.delta.is_some() { expr_value |= u32::from(CA::DELTA); } if self.events.is_some() { expr_value |= u32::from(CA::EVENTS); } expr_value } } impl CreateAlarmAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `counter` field of this structure. pub fn counter(mut self, value: I) -> Self where I: Into> { self.counter = value.into(); self } /// Set the `value_type` field of this structure. pub fn value_type(mut self, value: I) -> Self where I: Into> { self.value_type = value.into(); self } /// Set the `value` field of this structure. pub fn value(mut self, value: I) -> Self where I: Into> { self.value = value.into(); self } /// Set the `test_type` field of this structure. pub fn test_type(mut self, value: I) -> Self where I: Into> { self.test_type = value.into(); self } /// Set the `delta` field of this structure. pub fn delta(mut self, value: I) -> Self where I: Into> { self.delta = value.into(); self } /// Set the `events` field of this structure. pub fn events(mut self, value: I) -> Self where I: Into> { self.events = value.into(); self } } /// Opcode for the CreateAlarm request pub const CREATE_ALARM_REQUEST: u8 = 8; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateAlarmRequest<'input> { pub id: Alarm, pub value_list: Cow<'input, CreateAlarmAux>, } impl<'input> CreateAlarmRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let id_bytes = self.id.serialize(); let value_mask = self.value_list.switch_expr(); let value_mask_bytes = value_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_ALARM_REQUEST, 0, 0, id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], value_mask_bytes[0], value_mask_bytes[1], value_mask_bytes[2], value_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let value_list_bytes = self.value_list.serialize(value_mask); let length_so_far = length_so_far + value_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), value_list_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_ALARM_REQUEST { return Err(ParseError::InvalidValue); } let (id, remaining) = Alarm::try_parse(value)?; let (value_mask, remaining) = u32::try_parse(remaining)?; let (value_list, remaining) = CreateAlarmAux::try_parse(remaining, value_mask)?; let _ = remaining; Ok(CreateAlarmRequest { id, value_list: Cow::Owned(value_list), }) } /// Clone all borrowed data in this CreateAlarmRequest. pub fn into_owned(self) -> CreateAlarmRequest<'static> { CreateAlarmRequest { id: self.id, value_list: Cow::Owned(self.value_list.into_owned()), } } } impl<'input> Request for CreateAlarmRequest<'input> { type Reply = (); } pub fn create_alarm<'c, 'input, Conn>(conn: &'c Conn, id: Alarm, value_list: &'input CreateAlarmAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateAlarmRequest { id, value_list: Cow::Borrowed(value_list), }; request0.send(conn) } /// Auxiliary and optional information for the `change_alarm` function #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct ChangeAlarmAux { pub counter: Option, pub value_type: Option, pub value: Option, pub test_type: Option, pub delta: Option, pub events: Option, } impl ChangeAlarmAux { fn try_parse(value: &[u8], value_mask: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = value_mask; let mut outer_remaining = value; let counter = if switch_expr & u32::from(CA::COUNTER) != 0 { let remaining = outer_remaining; let (counter, remaining) = Counter::try_parse(remaining)?; outer_remaining = remaining; Some(counter) } else { None }; let value_type = if switch_expr & u32::from(CA::VALUE_TYPE) != 0 { let remaining = outer_remaining; let (value_type, remaining) = u32::try_parse(remaining)?; let value_type = value_type.into(); outer_remaining = remaining; Some(value_type) } else { None }; let value = if switch_expr & u32::from(CA::VALUE) != 0 { let remaining = outer_remaining; let (value, remaining) = Int64::try_parse(remaining)?; outer_remaining = remaining; Some(value) } else { None }; let test_type = if switch_expr & u32::from(CA::TEST_TYPE) != 0 { let remaining = outer_remaining; let (test_type, remaining) = u32::try_parse(remaining)?; let test_type = test_type.into(); outer_remaining = remaining; Some(test_type) } else { None }; let delta = if switch_expr & u32::from(CA::DELTA) != 0 { let remaining = outer_remaining; let (delta, remaining) = Int64::try_parse(remaining)?; outer_remaining = remaining; Some(delta) } else { None }; let events = if switch_expr & u32::from(CA::EVENTS) != 0 { let remaining = outer_remaining; let (events, remaining) = u32::try_parse(remaining)?; outer_remaining = remaining; Some(events) } else { None }; let result = ChangeAlarmAux { counter, value_type, value, test_type, delta, events }; Ok((result, outer_remaining)) } } impl ChangeAlarmAux { #[allow(dead_code)] fn serialize(&self, value_mask: u32) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, value_mask); result } fn serialize_into(&self, bytes: &mut Vec, value_mask: u32) { assert_eq!(self.switch_expr(), value_mask, "switch `value_list` has an inconsistent discriminant"); if let Some(counter) = self.counter { counter.serialize_into(bytes); } if let Some(value_type) = self.value_type { u32::from(value_type).serialize_into(bytes); } if let Some(ref value) = self.value { value.serialize_into(bytes); } if let Some(test_type) = self.test_type { u32::from(test_type).serialize_into(bytes); } if let Some(ref delta) = self.delta { delta.serialize_into(bytes); } if let Some(events) = self.events { events.serialize_into(bytes); } } } impl ChangeAlarmAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.counter.is_some() { expr_value |= u32::from(CA::COUNTER); } if self.value_type.is_some() { expr_value |= u32::from(CA::VALUE_TYPE); } if self.value.is_some() { expr_value |= u32::from(CA::VALUE); } if self.test_type.is_some() { expr_value |= u32::from(CA::TEST_TYPE); } if self.delta.is_some() { expr_value |= u32::from(CA::DELTA); } if self.events.is_some() { expr_value |= u32::from(CA::EVENTS); } expr_value } } impl ChangeAlarmAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `counter` field of this structure. pub fn counter(mut self, value: I) -> Self where I: Into> { self.counter = value.into(); self } /// Set the `value_type` field of this structure. pub fn value_type(mut self, value: I) -> Self where I: Into> { self.value_type = value.into(); self } /// Set the `value` field of this structure. pub fn value(mut self, value: I) -> Self where I: Into> { self.value = value.into(); self } /// Set the `test_type` field of this structure. pub fn test_type(mut self, value: I) -> Self where I: Into> { self.test_type = value.into(); self } /// Set the `delta` field of this structure. pub fn delta(mut self, value: I) -> Self where I: Into> { self.delta = value.into(); self } /// Set the `events` field of this structure. pub fn events(mut self, value: I) -> Self where I: Into> { self.events = value.into(); self } } /// Opcode for the ChangeAlarm request pub const CHANGE_ALARM_REQUEST: u8 = 9; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeAlarmRequest<'input> { pub id: Alarm, pub value_list: Cow<'input, ChangeAlarmAux>, } impl<'input> ChangeAlarmRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let id_bytes = self.id.serialize(); let value_mask = self.value_list.switch_expr(); let value_mask_bytes = value_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_ALARM_REQUEST, 0, 0, id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], value_mask_bytes[0], value_mask_bytes[1], value_mask_bytes[2], value_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let value_list_bytes = self.value_list.serialize(value_mask); let length_so_far = length_so_far + value_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), value_list_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_ALARM_REQUEST { return Err(ParseError::InvalidValue); } let (id, remaining) = Alarm::try_parse(value)?; let (value_mask, remaining) = u32::try_parse(remaining)?; let (value_list, remaining) = ChangeAlarmAux::try_parse(remaining, value_mask)?; let _ = remaining; Ok(ChangeAlarmRequest { id, value_list: Cow::Owned(value_list), }) } /// Clone all borrowed data in this ChangeAlarmRequest. pub fn into_owned(self) -> ChangeAlarmRequest<'static> { ChangeAlarmRequest { id: self.id, value_list: Cow::Owned(self.value_list.into_owned()), } } } impl<'input> Request for ChangeAlarmRequest<'input> { type Reply = (); } pub fn change_alarm<'c, 'input, Conn>(conn: &'c Conn, id: Alarm, value_list: &'input ChangeAlarmAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeAlarmRequest { id, value_list: Cow::Borrowed(value_list), }; request0.send(conn) } /// Opcode for the DestroyAlarm request pub const DESTROY_ALARM_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyAlarmRequest { pub alarm: Alarm, } impl DestroyAlarmRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let alarm_bytes = self.alarm.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_ALARM_REQUEST, 0, 0, alarm_bytes[0], alarm_bytes[1], alarm_bytes[2], alarm_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_ALARM_REQUEST { return Err(ParseError::InvalidValue); } let (alarm, remaining) = Alarm::try_parse(value)?; let _ = remaining; Ok(DestroyAlarmRequest { alarm, }) } } impl Request for DestroyAlarmRequest { type Reply = (); } pub fn destroy_alarm(conn: &Conn, alarm: Alarm) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyAlarmRequest { alarm, }; request0.send(conn) } /// Opcode for the QueryAlarm request pub const QUERY_ALARM_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryAlarmRequest { pub alarm: Alarm, } impl QueryAlarmRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let alarm_bytes = self.alarm.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_ALARM_REQUEST, 0, 0, alarm_bytes[0], alarm_bytes[1], alarm_bytes[2], alarm_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_ALARM_REQUEST { return Err(ParseError::InvalidValue); } let (alarm, remaining) = Alarm::try_parse(value)?; let _ = remaining; Ok(QueryAlarmRequest { alarm, }) } } impl Request for QueryAlarmRequest { type Reply = QueryAlarmReply; } pub fn query_alarm(conn: &Conn, alarm: Alarm) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryAlarmRequest { alarm, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryAlarmReply { pub sequence: u16, pub length: u32, pub trigger: Trigger, pub delta: Int64, pub events: bool, pub state: ALARMSTATE, } impl TryParse for QueryAlarmReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (trigger, remaining) = Trigger::try_parse(remaining)?; let (delta, remaining) = Int64::try_parse(remaining)?; let (events, remaining) = bool::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let state = state.into(); let result = QueryAlarmReply { sequence, length, trigger, delta, events, state }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetPriority request pub const SET_PRIORITY_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetPriorityRequest { pub id: u32, pub priority: i32, } impl SetPriorityRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let id_bytes = self.id.serialize(); let priority_bytes = self.priority.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PRIORITY_REQUEST, 0, 0, id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], priority_bytes[0], priority_bytes[1], priority_bytes[2], priority_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_PRIORITY_REQUEST { return Err(ParseError::InvalidValue); } let (id, remaining) = u32::try_parse(value)?; let (priority, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(SetPriorityRequest { id, priority, }) } } impl Request for SetPriorityRequest { type Reply = (); } pub fn set_priority(conn: &Conn, id: u32, priority: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPriorityRequest { id, priority, }; request0.send(conn) } /// Opcode for the GetPriority request pub const GET_PRIORITY_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPriorityRequest { pub id: u32, } impl GetPriorityRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let id_bytes = self.id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PRIORITY_REQUEST, 0, 0, id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PRIORITY_REQUEST { return Err(ParseError::InvalidValue); } let (id, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetPriorityRequest { id, }) } } impl Request for GetPriorityRequest { type Reply = GetPriorityReply; } pub fn get_priority(conn: &Conn, id: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPriorityRequest { id, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPriorityReply { pub sequence: u16, pub length: u32, pub priority: i32, } impl TryParse for GetPriorityReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (priority, remaining) = i32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPriorityReply { sequence, length, priority }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the CreateFence request pub const CREATE_FENCE_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateFenceRequest { pub drawable: xproto::Drawable, pub fence: Fence, pub initially_triggered: bool, } impl CreateFenceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let fence_bytes = self.fence.serialize(); let initially_triggered_bytes = self.initially_triggered.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_FENCE_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], fence_bytes[0], fence_bytes[1], fence_bytes[2], fence_bytes[3], initially_triggered_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_FENCE_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (fence, remaining) = Fence::try_parse(remaining)?; let (initially_triggered, remaining) = bool::try_parse(remaining)?; let _ = remaining; Ok(CreateFenceRequest { drawable, fence, initially_triggered, }) } } impl Request for CreateFenceRequest { type Reply = (); } pub fn create_fence(conn: &Conn, drawable: xproto::Drawable, fence: Fence, initially_triggered: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateFenceRequest { drawable, fence, initially_triggered, }; request0.send(conn) } /// Opcode for the TriggerFence request pub const TRIGGER_FENCE_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct TriggerFenceRequest { pub fence: Fence, } impl TriggerFenceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let fence_bytes = self.fence.serialize(); let mut request0 = vec![ extension_information.major_opcode, TRIGGER_FENCE_REQUEST, 0, 0, fence_bytes[0], fence_bytes[1], fence_bytes[2], fence_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != TRIGGER_FENCE_REQUEST { return Err(ParseError::InvalidValue); } let (fence, remaining) = Fence::try_parse(value)?; let _ = remaining; Ok(TriggerFenceRequest { fence, }) } } impl Request for TriggerFenceRequest { type Reply = (); } pub fn trigger_fence(conn: &Conn, fence: Fence) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = TriggerFenceRequest { fence, }; request0.send(conn) } /// Opcode for the ResetFence request pub const RESET_FENCE_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ResetFenceRequest { pub fence: Fence, } impl ResetFenceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let fence_bytes = self.fence.serialize(); let mut request0 = vec![ extension_information.major_opcode, RESET_FENCE_REQUEST, 0, 0, fence_bytes[0], fence_bytes[1], fence_bytes[2], fence_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != RESET_FENCE_REQUEST { return Err(ParseError::InvalidValue); } let (fence, remaining) = Fence::try_parse(value)?; let _ = remaining; Ok(ResetFenceRequest { fence, }) } } impl Request for ResetFenceRequest { type Reply = (); } pub fn reset_fence(conn: &Conn, fence: Fence) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ResetFenceRequest { fence, }; request0.send(conn) } /// Opcode for the DestroyFence request pub const DESTROY_FENCE_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyFenceRequest { pub fence: Fence, } impl DestroyFenceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let fence_bytes = self.fence.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_FENCE_REQUEST, 0, 0, fence_bytes[0], fence_bytes[1], fence_bytes[2], fence_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_FENCE_REQUEST { return Err(ParseError::InvalidValue); } let (fence, remaining) = Fence::try_parse(value)?; let _ = remaining; Ok(DestroyFenceRequest { fence, }) } } impl Request for DestroyFenceRequest { type Reply = (); } pub fn destroy_fence(conn: &Conn, fence: Fence) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyFenceRequest { fence, }; request0.send(conn) } /// Opcode for the QueryFence request pub const QUERY_FENCE_REQUEST: u8 = 18; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryFenceRequest { pub fence: Fence, } impl QueryFenceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let fence_bytes = self.fence.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_FENCE_REQUEST, 0, 0, fence_bytes[0], fence_bytes[1], fence_bytes[2], fence_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_FENCE_REQUEST { return Err(ParseError::InvalidValue); } let (fence, remaining) = Fence::try_parse(value)?; let _ = remaining; Ok(QueryFenceRequest { fence, }) } } impl Request for QueryFenceRequest { type Reply = QueryFenceReply; } pub fn query_fence(conn: &Conn, fence: Fence) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryFenceRequest { fence, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryFenceReply { pub sequence: u16, pub length: u32, pub triggered: bool, } impl TryParse for QueryFenceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (triggered, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryFenceReply { sequence, length, triggered }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the AwaitFence request pub const AWAIT_FENCE_REQUEST: u8 = 19; #[derive(Debug, Clone, PartialEq, Eq)] pub struct AwaitFenceRequest<'input> { pub fence_list: Cow<'input, [Fence]>, } impl<'input> AwaitFenceRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, AWAIT_FENCE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); let fence_list_bytes = self.fence_list.serialize(); let length_so_far = length_so_far + fence_list_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), fence_list_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != AWAIT_FENCE_REQUEST { return Err(ParseError::InvalidValue); } let mut remaining = value; // Length is 'everything left in the input' let mut fence_list = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = Fence::try_parse(value)?; remaining = new_remaining; fence_list.push(v); } let _ = remaining; Ok(AwaitFenceRequest { fence_list: Cow::Owned(fence_list), }) } /// Clone all borrowed data in this AwaitFenceRequest. pub fn into_owned(self) -> AwaitFenceRequest<'static> { AwaitFenceRequest { fence_list: Cow::Owned(self.fence_list.into_owned()), } } } impl<'input> Request for AwaitFenceRequest<'input> { type Reply = (); } pub fn await_fence<'c, 'input, Conn>(conn: &'c Conn, fence_list: &'input [Fence]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AwaitFenceRequest { fence_list: Cow::Borrowed(fence_list), }; request0.send(conn) } /// Opcode for the CounterNotify event pub const COUNTER_NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CounterNotifyEvent { pub response_type: u8, pub kind: u8, pub sequence: u16, pub counter: Counter, pub wait_value: Int64, pub counter_value: Int64, pub timestamp: xproto::Timestamp, pub count: u16, pub destroyed: bool, } impl TryParse for CounterNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (kind, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (counter, remaining) = Counter::try_parse(remaining)?; let (wait_value, remaining) = Int64::try_parse(remaining)?; let (counter_value, remaining) = Int64::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (count, remaining) = u16::try_parse(remaining)?; let (destroyed, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = CounterNotifyEvent { response_type, kind, sequence, counter, wait_value, counter_value, timestamp, count, destroyed }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&CounterNotifyEvent> for [u8; 32] { fn from(input: &CounterNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let kind_bytes = input.kind.serialize(); let sequence_bytes = input.sequence.serialize(); let counter_bytes = input.counter.serialize(); let wait_value_bytes = input.wait_value.serialize(); let counter_value_bytes = input.counter_value.serialize(); let timestamp_bytes = input.timestamp.serialize(); let count_bytes = input.count.serialize(); let destroyed_bytes = input.destroyed.serialize(); [ response_type_bytes[0], kind_bytes[0], sequence_bytes[0], sequence_bytes[1], counter_bytes[0], counter_bytes[1], counter_bytes[2], counter_bytes[3], wait_value_bytes[0], wait_value_bytes[1], wait_value_bytes[2], wait_value_bytes[3], wait_value_bytes[4], wait_value_bytes[5], wait_value_bytes[6], wait_value_bytes[7], counter_value_bytes[0], counter_value_bytes[1], counter_value_bytes[2], counter_value_bytes[3], counter_value_bytes[4], counter_value_bytes[5], counter_value_bytes[6], counter_value_bytes[7], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], count_bytes[0], count_bytes[1], destroyed_bytes[0], 0, ] } } impl From for [u8; 32] { fn from(input: CounterNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the AlarmNotify event pub const ALARM_NOTIFY_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AlarmNotifyEvent { pub response_type: u8, pub kind: u8, pub sequence: u16, pub alarm: Alarm, pub counter_value: Int64, pub alarm_value: Int64, pub timestamp: xproto::Timestamp, pub state: ALARMSTATE, } impl TryParse for AlarmNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (kind, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (alarm, remaining) = Alarm::try_parse(remaining)?; let (counter_value, remaining) = Int64::try_parse(remaining)?; let (alarm_value, remaining) = Int64::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let state = state.into(); let result = AlarmNotifyEvent { response_type, kind, sequence, alarm, counter_value, alarm_value, timestamp, state }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&AlarmNotifyEvent> for [u8; 32] { fn from(input: &AlarmNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let kind_bytes = input.kind.serialize(); let sequence_bytes = input.sequence.serialize(); let alarm_bytes = input.alarm.serialize(); let counter_value_bytes = input.counter_value.serialize(); let alarm_value_bytes = input.alarm_value.serialize(); let timestamp_bytes = input.timestamp.serialize(); let state_bytes = u8::from(input.state).serialize(); [ response_type_bytes[0], kind_bytes[0], sequence_bytes[0], sequence_bytes[1], alarm_bytes[0], alarm_bytes[1], alarm_bytes[2], alarm_bytes[3], counter_value_bytes[0], counter_value_bytes[1], counter_value_bytes[2], counter_value_bytes[3], counter_value_bytes[4], counter_value_bytes[5], counter_value_bytes[6], counter_value_bytes[7], alarm_value_bytes[0], alarm_value_bytes[1], alarm_value_bytes[2], alarm_value_bytes[3], alarm_value_bytes[4], alarm_value_bytes[5], alarm_value_bytes[6], alarm_value_bytes[7], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], state_bytes[0], 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: AlarmNotifyEvent) -> Self { Self::from(&input) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn sync_initialize(&self, desired_major_version: u8, desired_minor_version: u8) -> Result, ConnectionError> { initialize(self, desired_major_version, desired_minor_version) } fn sync_list_system_counters(&self) -> Result, ConnectionError> { list_system_counters(self) } fn sync_create_counter(&self, id: Counter, initial_value: Int64) -> Result, ConnectionError> { create_counter(self, id, initial_value) } fn sync_destroy_counter(&self, counter: Counter) -> Result, ConnectionError> { destroy_counter(self, counter) } fn sync_query_counter(&self, counter: Counter) -> Result, ConnectionError> { query_counter(self, counter) } fn sync_await_<'c, 'input>(&'c self, wait_list: &'input [Waitcondition]) -> Result, ConnectionError> { await_(self, wait_list) } fn sync_change_counter(&self, counter: Counter, amount: Int64) -> Result, ConnectionError> { change_counter(self, counter, amount) } fn sync_set_counter(&self, counter: Counter, value: Int64) -> Result, ConnectionError> { set_counter(self, counter, value) } fn sync_create_alarm<'c, 'input>(&'c self, id: Alarm, value_list: &'input CreateAlarmAux) -> Result, ConnectionError> { create_alarm(self, id, value_list) } fn sync_change_alarm<'c, 'input>(&'c self, id: Alarm, value_list: &'input ChangeAlarmAux) -> Result, ConnectionError> { change_alarm(self, id, value_list) } fn sync_destroy_alarm(&self, alarm: Alarm) -> Result, ConnectionError> { destroy_alarm(self, alarm) } fn sync_query_alarm(&self, alarm: Alarm) -> Result, ConnectionError> { query_alarm(self, alarm) } fn sync_set_priority(&self, id: u32, priority: i32) -> Result, ConnectionError> { set_priority(self, id, priority) } fn sync_get_priority(&self, id: u32) -> Result, ConnectionError> { get_priority(self, id) } fn sync_create_fence(&self, drawable: xproto::Drawable, fence: Fence, initially_triggered: bool) -> Result, ConnectionError> { create_fence(self, drawable, fence, initially_triggered) } fn sync_trigger_fence(&self, fence: Fence) -> Result, ConnectionError> { trigger_fence(self, fence) } fn sync_reset_fence(&self, fence: Fence) -> Result, ConnectionError> { reset_fence(self, fence) } fn sync_destroy_fence(&self, fence: Fence) -> Result, ConnectionError> { destroy_fence(self, fence) } fn sync_query_fence(&self, fence: Fence) -> Result, ConnectionError> { query_fence(self, fence) } fn sync_await_fence<'c, 'input>(&'c self, fence_list: &'input [Fence]) -> Result, ConnectionError> { await_fence(self, fence_list) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xc_misc.rs010064400017500001750000000314241402220031600152530ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `XCMisc` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XC-MISC"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 1); /// Opcode for the GetVersion request pub const GET_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVersionRequest { pub client_major_version: u16, pub client_minor_version: u16, } impl GetVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_minor_version_bytes[0], client_minor_version_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u16::try_parse(value)?; let (client_minor_version, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(GetVersionRequest { client_major_version, client_minor_version, }) } } impl Request for GetVersionRequest { type Reply = GetVersionReply; } pub fn get_version(conn: &Conn, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVersionReply { pub sequence: u16, pub length: u32, pub server_major_version: u16, pub server_minor_version: u16, } impl TryParse for GetVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major_version, remaining) = u16::try_parse(remaining)?; let (server_minor_version, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetVersionReply { sequence, length, server_major_version, server_minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetXIDRange request pub const GET_XID_RANGE_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetXIDRangeRequest; impl GetXIDRangeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_XID_RANGE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_XID_RANGE_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetXIDRangeRequest ) } } impl Request for GetXIDRangeRequest { type Reply = GetXIDRangeReply; } pub fn get_xid_range(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetXIDRangeRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetXIDRangeReply { pub sequence: u16, pub length: u32, pub start_id: u32, pub count: u32, } impl TryParse for GetXIDRangeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (start_id, remaining) = u32::try_parse(remaining)?; let (count, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetXIDRangeReply { sequence, length, start_id, count }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetXIDList request pub const GET_XID_LIST_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetXIDListRequest { pub count: u32, } impl GetXIDListRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let count_bytes = self.count.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_XID_LIST_REQUEST, 0, 0, count_bytes[0], count_bytes[1], count_bytes[2], count_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_XID_LIST_REQUEST { return Err(ParseError::InvalidValue); } let (count, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetXIDListRequest { count, }) } } impl Request for GetXIDListRequest { type Reply = GetXIDListReply; } pub fn get_xid_list(conn: &Conn, count: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetXIDListRequest { count, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetXIDListReply { pub sequence: u16, pub length: u32, pub ids: Vec, } impl TryParse for GetXIDListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (ids_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (ids, remaining) = crate::x11_utils::parse_list::(remaining, ids_len.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetXIDListReply { sequence, length, ids }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetXIDListReply { /// Get the value of the `ids_len` field. /// /// The `ids_len` field is used as the length field of the `ids` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn ids_len(&self) -> u32 { self.ids.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xc_misc_get_version(&self, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> { get_version(self, client_major_version, client_minor_version) } fn xc_misc_get_xid_range(&self) -> Result, ConnectionError> { get_xid_range(self) } fn xc_misc_get_xid_list(&self, count: u32) -> Result, ConnectionError> { get_xid_list(self, count) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xevie.rs010064400017500001750000000571471402220031600147600ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Xevie` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XEVIE"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 0); /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major_version: u16, pub client_minor_version: u16, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_minor_version_bytes[0], client_minor_version_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u16::try_parse(value)?; let (client_minor_version, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major_version, client_minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub server_major_version: u16, pub server_minor_version: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major_version, remaining) = u16::try_parse(remaining)?; let (server_minor_version, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, server_major_version, server_minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Start request pub const START_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct StartRequest { pub screen: u32, } impl StartRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, START_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != START_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(StartRequest { screen, }) } } impl Request for StartRequest { type Reply = StartReply; } pub fn start(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = StartRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct StartReply { pub sequence: u16, pub length: u32, } impl TryParse for StartReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = StartReply { sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the End request pub const END_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EndRequest { pub cmap: u32, } impl EndRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cmap_bytes = self.cmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, END_REQUEST, 0, 0, cmap_bytes[0], cmap_bytes[1], cmap_bytes[2], cmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != END_REQUEST { return Err(ParseError::InvalidValue); } let (cmap, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(EndRequest { cmap, }) } } impl Request for EndRequest { type Reply = EndReply; } pub fn end(conn: &Conn, cmap: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = EndRequest { cmap, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EndReply { pub sequence: u16, pub length: u32, } impl TryParse for EndReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = EndReply { sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Datatype(bool); impl Datatype { pub const UNMODIFIED: Self = Self(false); pub const MODIFIED: Self = Self(true); } impl From for bool { #[inline] fn from(input: Datatype) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Datatype) -> Self { Some(input.0) } } impl From for u8 { #[inline] fn from(input: Datatype) -> Self { u8::from(input.0) } } impl From for Option { #[inline] fn from(input: Datatype) -> Self { Some(u8::from(input.0)) } } impl From for u16 { #[inline] fn from(input: Datatype) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Datatype) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Datatype) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Datatype) -> Self { Some(u32::from(input.0)) } } impl From for Datatype { #[inline] fn from(value: bool) -> Self { Self(value) } } impl std::fmt::Debug for Datatype { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::UNMODIFIED.0.into(), "UNMODIFIED", "Unmodified"), (Self::MODIFIED.0.into(), "MODIFIED", "Modified"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Event { } impl TryParse for Event { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = remaining.get(32..).ok_or(ParseError::InsufficientData)?; let result = Event { }; Ok((result, remaining)) } } impl Serialize for Event { type Bytes = [u8; 32]; fn serialize(&self) -> [u8; 32] { [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(32); bytes.extend_from_slice(&[0; 32]); } } /// Opcode for the Send request pub const SEND_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SendRequest { pub event: Event, pub data_type: u32, } impl SendRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let event_bytes = self.event.serialize(); let data_type_bytes = self.data_type.serialize(); let mut request0 = vec![ extension_information.major_opcode, SEND_REQUEST, 0, 0, event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], event_bytes[4], event_bytes[5], event_bytes[6], event_bytes[7], event_bytes[8], event_bytes[9], event_bytes[10], event_bytes[11], event_bytes[12], event_bytes[13], event_bytes[14], event_bytes[15], event_bytes[16], event_bytes[17], event_bytes[18], event_bytes[19], event_bytes[20], event_bytes[21], event_bytes[22], event_bytes[23], event_bytes[24], event_bytes[25], event_bytes[26], event_bytes[27], event_bytes[28], event_bytes[29], event_bytes[30], event_bytes[31], data_type_bytes[0], data_type_bytes[1], data_type_bytes[2], data_type_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SEND_REQUEST { return Err(ParseError::InvalidValue); } let (event, remaining) = Event::try_parse(value)?; let (data_type, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(64..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SendRequest { event, data_type, }) } } impl Request for SendRequest { type Reply = SendReply; } pub fn send(conn: &Conn, event: Event, data_type: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SendRequest { event, data_type, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SendReply { pub sequence: u16, pub length: u32, } impl TryParse for SendReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = SendReply { sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SelectInput request pub const SELECT_INPUT_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectInputRequest { pub event_mask: u32, } impl SelectInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let event_mask_bytes = self.event_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_INPUT_REQUEST, 0, 0, event_mask_bytes[0], event_mask_bytes[1], event_mask_bytes[2], event_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (event_mask, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(SelectInputRequest { event_mask, }) } } impl Request for SelectInputRequest { type Reply = SelectInputReply; } pub fn select_input(conn: &Conn, event_mask: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SelectInputRequest { event_mask, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectInputReply { pub sequence: u16, pub length: u32, } impl TryParse for SelectInputReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = SelectInputReply { sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xevie_query_version(&self, client_major_version: u16, client_minor_version: u16) -> Result, ConnectionError> { query_version(self, client_major_version, client_minor_version) } fn xevie_start(&self, screen: u32) -> Result, ConnectionError> { start(self, screen) } fn xevie_end(&self, cmap: u32) -> Result, ConnectionError> { end(self, cmap) } fn xevie_send(&self, event: Event, data_type: u32) -> Result, ConnectionError> { send(self, event, data_type) } fn xevie_select_input(&self, event_mask: u32) -> Result, ConnectionError> { select_input(self, event_mask) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xf86dri.rs010064400017500001750000001441631402220031600151250ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `XF86Dri` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XFree86-DRI"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (4, 1); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DrmClipRect { pub x1: i16, pub y1: i16, pub x2: i16, pub x3: i16, } impl TryParse for DrmClipRect { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (x1, remaining) = i16::try_parse(remaining)?; let (y1, remaining) = i16::try_parse(remaining)?; let (x2, remaining) = i16::try_parse(remaining)?; let (x3, remaining) = i16::try_parse(remaining)?; let result = DrmClipRect { x1, y1, x2, x3 }; Ok((result, remaining)) } } impl Serialize for DrmClipRect { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let x1_bytes = self.x1.serialize(); let y1_bytes = self.y1.serialize(); let x2_bytes = self.x2.serialize(); let x3_bytes = self.x3.serialize(); [ x1_bytes[0], x1_bytes[1], y1_bytes[0], y1_bytes[1], x2_bytes[0], x2_bytes[1], x3_bytes[0], x3_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.x1.serialize_into(bytes); self.y1.serialize_into(bytes); self.x2.serialize_into(bytes); self.x3.serialize_into(bytes); } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest; impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryVersionRequest ) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub dri_major_version: u16, pub dri_minor_version: u16, pub dri_minor_patch: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (dri_major_version, remaining) = u16::try_parse(remaining)?; let (dri_minor_version, remaining) = u16::try_parse(remaining)?; let (dri_minor_patch, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, dri_major_version, dri_minor_version, dri_minor_patch }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryDirectRenderingCapable request pub const QUERY_DIRECT_RENDERING_CAPABLE_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryDirectRenderingCapableRequest { pub screen: u32, } impl QueryDirectRenderingCapableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_DIRECT_RENDERING_CAPABLE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_DIRECT_RENDERING_CAPABLE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(QueryDirectRenderingCapableRequest { screen, }) } } impl Request for QueryDirectRenderingCapableRequest { type Reply = QueryDirectRenderingCapableReply; } pub fn query_direct_rendering_capable(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryDirectRenderingCapableRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryDirectRenderingCapableReply { pub sequence: u16, pub length: u32, pub is_capable: bool, } impl TryParse for QueryDirectRenderingCapableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (is_capable, remaining) = bool::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryDirectRenderingCapableReply { sequence, length, is_capable }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the OpenConnection request pub const OPEN_CONNECTION_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OpenConnectionRequest { pub screen: u32, } impl OpenConnectionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, OPEN_CONNECTION_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != OPEN_CONNECTION_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(OpenConnectionRequest { screen, }) } } impl Request for OpenConnectionRequest { type Reply = OpenConnectionReply; } pub fn open_connection(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = OpenConnectionRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenConnectionReply { pub sequence: u16, pub length: u32, pub sarea_handle_low: u32, pub sarea_handle_high: u32, pub bus_id: Vec, } impl TryParse for OpenConnectionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (sarea_handle_low, remaining) = u32::try_parse(remaining)?; let (sarea_handle_high, remaining) = u32::try_parse(remaining)?; let (bus_id_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (bus_id, remaining) = crate::x11_utils::parse_u8_list(remaining, bus_id_len.try_to_usize()?)?; let bus_id = bus_id.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = OpenConnectionReply { sequence, length, sarea_handle_low, sarea_handle_high, bus_id }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl OpenConnectionReply { /// Get the value of the `bus_id_len` field. /// /// The `bus_id_len` field is used as the length field of the `bus_id` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn bus_id_len(&self) -> u32 { self.bus_id.len() .try_into().unwrap() } } /// Opcode for the CloseConnection request pub const CLOSE_CONNECTION_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CloseConnectionRequest { pub screen: u32, } impl CloseConnectionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, CLOSE_CONNECTION_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CLOSE_CONNECTION_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(CloseConnectionRequest { screen, }) } } impl Request for CloseConnectionRequest { type Reply = (); } pub fn close_connection(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CloseConnectionRequest { screen, }; request0.send(conn) } /// Opcode for the GetClientDriverName request pub const GET_CLIENT_DRIVER_NAME_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetClientDriverNameRequest { pub screen: u32, } impl GetClientDriverNameRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CLIENT_DRIVER_NAME_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CLIENT_DRIVER_NAME_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetClientDriverNameRequest { screen, }) } } impl Request for GetClientDriverNameRequest { type Reply = GetClientDriverNameReply; } pub fn get_client_driver_name(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetClientDriverNameRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetClientDriverNameReply { pub sequence: u16, pub length: u32, pub client_driver_major_version: u32, pub client_driver_minor_version: u32, pub client_driver_patch_version: u32, pub client_driver_name: Vec, } impl TryParse for GetClientDriverNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (client_driver_major_version, remaining) = u32::try_parse(remaining)?; let (client_driver_minor_version, remaining) = u32::try_parse(remaining)?; let (client_driver_patch_version, remaining) = u32::try_parse(remaining)?; let (client_driver_name_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (client_driver_name, remaining) = crate::x11_utils::parse_u8_list(remaining, client_driver_name_len.try_to_usize()?)?; let client_driver_name = client_driver_name.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetClientDriverNameReply { sequence, length, client_driver_major_version, client_driver_minor_version, client_driver_patch_version, client_driver_name }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetClientDriverNameReply { /// Get the value of the `client_driver_name_len` field. /// /// The `client_driver_name_len` field is used as the length field of the `client_driver_name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn client_driver_name_len(&self) -> u32 { self.client_driver_name.len() .try_into().unwrap() } } /// Opcode for the CreateContext request pub const CREATE_CONTEXT_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateContextRequest { pub screen: u32, pub visual: u32, pub context: u32, } impl CreateContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let visual_bytes = self.visual.serialize(); let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CONTEXT_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], visual_bytes[0], visual_bytes[1], visual_bytes[2], visual_bytes[3], context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (visual, remaining) = u32::try_parse(remaining)?; let (context, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(CreateContextRequest { screen, visual, context, }) } } impl Request for CreateContextRequest { type Reply = CreateContextReply; } pub fn create_context(conn: &Conn, screen: u32, visual: u32, context: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateContextRequest { screen, visual, context, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateContextReply { pub sequence: u16, pub length: u32, pub hw_context: u32, } impl TryParse for CreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (hw_context, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateContextReply { sequence, length, hw_context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the DestroyContext request pub const DESTROY_CONTEXT_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyContextRequest { pub screen: u32, pub context: u32, } impl DestroyContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_CONTEXT_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (context, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(DestroyContextRequest { screen, context, }) } } impl Request for DestroyContextRequest { type Reply = (); } pub fn destroy_context(conn: &Conn, screen: u32, context: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyContextRequest { screen, context, }; request0.send(conn) } /// Opcode for the CreateDrawable request pub const CREATE_DRAWABLE_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateDrawableRequest { pub screen: u32, pub drawable: u32, } impl CreateDrawableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_DRAWABLE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_DRAWABLE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (drawable, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(CreateDrawableRequest { screen, drawable, }) } } impl Request for CreateDrawableRequest { type Reply = CreateDrawableReply; } pub fn create_drawable(conn: &Conn, screen: u32, drawable: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateDrawableRequest { screen, drawable, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateDrawableReply { pub sequence: u16, pub length: u32, pub hw_drawable_handle: u32, } impl TryParse for CreateDrawableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (hw_drawable_handle, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateDrawableReply { sequence, length, hw_drawable_handle }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the DestroyDrawable request pub const DESTROY_DRAWABLE_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyDrawableRequest { pub screen: u32, pub drawable: u32, } impl DestroyDrawableRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_DRAWABLE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_DRAWABLE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (drawable, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(DestroyDrawableRequest { screen, drawable, }) } } impl Request for DestroyDrawableRequest { type Reply = (); } pub fn destroy_drawable(conn: &Conn, screen: u32, drawable: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyDrawableRequest { screen, drawable, }; request0.send(conn) } /// Opcode for the GetDrawableInfo request pub const GET_DRAWABLE_INFO_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDrawableInfoRequest { pub screen: u32, pub drawable: u32, } impl GetDrawableInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DRAWABLE_INFO_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DRAWABLE_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (drawable, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetDrawableInfoRequest { screen, drawable, }) } } impl Request for GetDrawableInfoRequest { type Reply = GetDrawableInfoReply; } pub fn get_drawable_info(conn: &Conn, screen: u32, drawable: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDrawableInfoRequest { screen, drawable, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDrawableInfoReply { pub sequence: u16, pub length: u32, pub drawable_table_index: u32, pub drawable_table_stamp: u32, pub drawable_origin_x: i16, pub drawable_origin_y: i16, pub drawable_size_w: i16, pub drawable_size_h: i16, pub back_x: i16, pub back_y: i16, pub clip_rects: Vec, pub back_clip_rects: Vec, } impl TryParse for GetDrawableInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (drawable_table_index, remaining) = u32::try_parse(remaining)?; let (drawable_table_stamp, remaining) = u32::try_parse(remaining)?; let (drawable_origin_x, remaining) = i16::try_parse(remaining)?; let (drawable_origin_y, remaining) = i16::try_parse(remaining)?; let (drawable_size_w, remaining) = i16::try_parse(remaining)?; let (drawable_size_h, remaining) = i16::try_parse(remaining)?; let (num_clip_rects, remaining) = u32::try_parse(remaining)?; let (back_x, remaining) = i16::try_parse(remaining)?; let (back_y, remaining) = i16::try_parse(remaining)?; let (num_back_clip_rects, remaining) = u32::try_parse(remaining)?; let (clip_rects, remaining) = crate::x11_utils::parse_list::(remaining, num_clip_rects.try_to_usize()?)?; let (back_clip_rects, remaining) = crate::x11_utils::parse_list::(remaining, num_back_clip_rects.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDrawableInfoReply { sequence, length, drawable_table_index, drawable_table_stamp, drawable_origin_x, drawable_origin_y, drawable_size_w, drawable_size_h, back_x, back_y, clip_rects, back_clip_rects }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDrawableInfoReply { /// Get the value of the `num_clip_rects` field. /// /// The `num_clip_rects` field is used as the length field of the `clip_rects` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_clip_rects(&self) -> u32 { self.clip_rects.len() .try_into().unwrap() } /// Get the value of the `num_back_clip_rects` field. /// /// The `num_back_clip_rects` field is used as the length field of the `back_clip_rects` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_back_clip_rects(&self) -> u32 { self.back_clip_rects.len() .try_into().unwrap() } } /// Opcode for the GetDeviceInfo request pub const GET_DEVICE_INFO_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceInfoRequest { pub screen: u32, } impl GetDeviceInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_INFO_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetDeviceInfoRequest { screen, }) } } impl Request for GetDeviceInfoRequest { type Reply = GetDeviceInfoReply; } pub fn get_device_info(conn: &Conn, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceInfoRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceInfoReply { pub sequence: u16, pub length: u32, pub framebuffer_handle_low: u32, pub framebuffer_handle_high: u32, pub framebuffer_origin_offset: u32, pub framebuffer_size: u32, pub framebuffer_stride: u32, pub device_private: Vec, } impl TryParse for GetDeviceInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (framebuffer_handle_low, remaining) = u32::try_parse(remaining)?; let (framebuffer_handle_high, remaining) = u32::try_parse(remaining)?; let (framebuffer_origin_offset, remaining) = u32::try_parse(remaining)?; let (framebuffer_size, remaining) = u32::try_parse(remaining)?; let (framebuffer_stride, remaining) = u32::try_parse(remaining)?; let (device_private_size, remaining) = u32::try_parse(remaining)?; let (device_private, remaining) = crate::x11_utils::parse_list::(remaining, device_private_size.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceInfoReply { sequence, length, framebuffer_handle_low, framebuffer_handle_high, framebuffer_origin_offset, framebuffer_size, framebuffer_stride, device_private }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceInfoReply { /// Get the value of the `device_private_size` field. /// /// The `device_private_size` field is used as the length field of the `device_private` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn device_private_size(&self) -> u32 { self.device_private.len() .try_into().unwrap() } } /// Opcode for the AuthConnection request pub const AUTH_CONNECTION_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AuthConnectionRequest { pub screen: u32, pub magic: u32, } impl AuthConnectionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let magic_bytes = self.magic.serialize(); let mut request0 = vec![ extension_information.major_opcode, AUTH_CONNECTION_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], magic_bytes[0], magic_bytes[1], magic_bytes[2], magic_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != AUTH_CONNECTION_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (magic, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(AuthConnectionRequest { screen, magic, }) } } impl Request for AuthConnectionRequest { type Reply = AuthConnectionReply; } pub fn auth_connection(conn: &Conn, screen: u32, magic: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = AuthConnectionRequest { screen, magic, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AuthConnectionReply { pub sequence: u16, pub length: u32, pub authenticated: u32, } impl TryParse for AuthConnectionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (authenticated, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = AuthConnectionReply { sequence, length, authenticated }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xf86dri_query_version(&self) -> Result, ConnectionError> { query_version(self) } fn xf86dri_query_direct_rendering_capable(&self, screen: u32) -> Result, ConnectionError> { query_direct_rendering_capable(self, screen) } fn xf86dri_open_connection(&self, screen: u32) -> Result, ConnectionError> { open_connection(self, screen) } fn xf86dri_close_connection(&self, screen: u32) -> Result, ConnectionError> { close_connection(self, screen) } fn xf86dri_get_client_driver_name(&self, screen: u32) -> Result, ConnectionError> { get_client_driver_name(self, screen) } fn xf86dri_create_context(&self, screen: u32, visual: u32, context: u32) -> Result, ConnectionError> { create_context(self, screen, visual, context) } fn xf86dri_destroy_context(&self, screen: u32, context: u32) -> Result, ConnectionError> { destroy_context(self, screen, context) } fn xf86dri_create_drawable(&self, screen: u32, drawable: u32) -> Result, ConnectionError> { create_drawable(self, screen, drawable) } fn xf86dri_destroy_drawable(&self, screen: u32, drawable: u32) -> Result, ConnectionError> { destroy_drawable(self, screen, drawable) } fn xf86dri_get_drawable_info(&self, screen: u32, drawable: u32) -> Result, ConnectionError> { get_drawable_info(self, screen, drawable) } fn xf86dri_get_device_info(&self, screen: u32) -> Result, ConnectionError> { get_device_info(self, screen) } fn xf86dri_auth_connection(&self, screen: u32, magic: u32) -> Result, ConnectionError> { auth_connection(self, screen, magic) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xf86vidmode.rs010064400017500001750000003517061402220031600160010ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `XF86VidMode` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XFree86-VidModeExtension"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (2, 2); pub type Syncrange = u32; pub type Dotclock = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct ModeFlag(u16); impl ModeFlag { pub const POSITIVE_H_SYNC: Self = Self(1 << 0); pub const NEGATIVE_H_SYNC: Self = Self(1 << 1); pub const POSITIVE_V_SYNC: Self = Self(1 << 2); pub const NEGATIVE_V_SYNC: Self = Self(1 << 3); pub const INTERLACE: Self = Self(1 << 4); pub const COMPOSITE_SYNC: Self = Self(1 << 5); pub const POSITIVE_C_SYNC: Self = Self(1 << 6); pub const NEGATIVE_C_SYNC: Self = Self(1 << 7); pub const H_SKEW: Self = Self(1 << 8); pub const BROADCAST: Self = Self(1 << 9); pub const PIXMUX: Self = Self(1 << 10); pub const DOUBLE_CLOCK: Self = Self(1 << 11); pub const HALF_CLOCK: Self = Self(1 << 12); } impl From for u16 { #[inline] fn from(input: ModeFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ModeFlag) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: ModeFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ModeFlag) -> Self { Some(u32::from(input.0)) } } impl From for ModeFlag { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for ModeFlag { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for ModeFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::POSITIVE_H_SYNC.0.into(), "POSITIVE_H_SYNC", "PositiveHSync"), (Self::NEGATIVE_H_SYNC.0.into(), "NEGATIVE_H_SYNC", "NegativeHSync"), (Self::POSITIVE_V_SYNC.0.into(), "POSITIVE_V_SYNC", "PositiveVSync"), (Self::NEGATIVE_V_SYNC.0.into(), "NEGATIVE_V_SYNC", "NegativeVSync"), (Self::INTERLACE.0.into(), "INTERLACE", "Interlace"), (Self::COMPOSITE_SYNC.0.into(), "COMPOSITE_SYNC", "CompositeSync"), (Self::POSITIVE_C_SYNC.0.into(), "POSITIVE_C_SYNC", "PositiveCSync"), (Self::NEGATIVE_C_SYNC.0.into(), "NEGATIVE_C_SYNC", "NegativeCSync"), (Self::H_SKEW.0.into(), "H_SKEW", "HSkew"), (Self::BROADCAST.0.into(), "BROADCAST", "Broadcast"), (Self::PIXMUX.0.into(), "PIXMUX", "Pixmux"), (Self::DOUBLE_CLOCK.0.into(), "DOUBLE_CLOCK", "DoubleClock"), (Self::HALF_CLOCK.0.into(), "HALF_CLOCK", "HalfClock"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ModeFlag, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct ClockFlag(u8); impl ClockFlag { pub const PROGRAMABLE: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: ClockFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ClockFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ClockFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ClockFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ClockFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ClockFlag) -> Self { Some(u32::from(input.0)) } } impl From for ClockFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ClockFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::PROGRAMABLE.0.into(), "PROGRAMABLE", "Programable"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ClockFlag, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Permission(u8); impl Permission { pub const READ: Self = Self(1 << 0); pub const WRITE: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: Permission) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Permission) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Permission) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Permission) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Permission) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Permission) -> Self { Some(u32::from(input.0)) } } impl From for Permission { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Permission { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::READ.0.into(), "READ", "Read"), (Self::WRITE.0.into(), "WRITE", "Write"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(Permission, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ModeInfo { pub dotclock: Dotclock, pub hdisplay: u16, pub hsyncstart: u16, pub hsyncend: u16, pub htotal: u16, pub hskew: u32, pub vdisplay: u16, pub vsyncstart: u16, pub vsyncend: u16, pub vtotal: u16, pub flags: u32, pub privsize: u32, } impl TryParse for ModeInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (dotclock, remaining) = Dotclock::try_parse(remaining)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; let (hsyncend, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u32::try_parse(remaining)?; let (vdisplay, remaining) = u16::try_parse(remaining)?; let (vsyncstart, remaining) = u16::try_parse(remaining)?; let (vsyncend, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (privsize, remaining) = u32::try_parse(remaining)?; let result = ModeInfo { dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, privsize }; Ok((result, remaining)) } } impl Serialize for ModeInfo { type Bytes = [u8; 48]; fn serialize(&self) -> [u8; 48] { let dotclock_bytes = self.dotclock.serialize(); let hdisplay_bytes = self.hdisplay.serialize(); let hsyncstart_bytes = self.hsyncstart.serialize(); let hsyncend_bytes = self.hsyncend.serialize(); let htotal_bytes = self.htotal.serialize(); let hskew_bytes = self.hskew.serialize(); let vdisplay_bytes = self.vdisplay.serialize(); let vsyncstart_bytes = self.vsyncstart.serialize(); let vsyncend_bytes = self.vsyncend.serialize(); let vtotal_bytes = self.vtotal.serialize(); let flags_bytes = self.flags.serialize(); let privsize_bytes = self.privsize.serialize(); [ dotclock_bytes[0], dotclock_bytes[1], dotclock_bytes[2], dotclock_bytes[3], hdisplay_bytes[0], hdisplay_bytes[1], hsyncstart_bytes[0], hsyncstart_bytes[1], hsyncend_bytes[0], hsyncend_bytes[1], htotal_bytes[0], htotal_bytes[1], hskew_bytes[0], hskew_bytes[1], hskew_bytes[2], hskew_bytes[3], vdisplay_bytes[0], vdisplay_bytes[1], vsyncstart_bytes[0], vsyncstart_bytes[1], vsyncend_bytes[0], vsyncend_bytes[1], vtotal_bytes[0], vtotal_bytes[1], 0, 0, 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, privsize_bytes[0], privsize_bytes[1], privsize_bytes[2], privsize_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(48); self.dotclock.serialize_into(bytes); self.hdisplay.serialize_into(bytes); self.hsyncstart.serialize_into(bytes); self.hsyncend.serialize_into(bytes); self.htotal.serialize_into(bytes); self.hskew.serialize_into(bytes); self.vdisplay.serialize_into(bytes); self.vsyncstart.serialize_into(bytes); self.vsyncend.serialize_into(bytes); self.vtotal.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); self.flags.serialize_into(bytes); bytes.extend_from_slice(&[0; 12]); self.privsize.serialize_into(bytes); } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest; impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryVersionRequest ) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u16, pub minor_version: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u16::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetModeLine request pub const GET_MODE_LINE_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetModeLineRequest { pub screen: u16, } impl GetModeLineRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MODE_LINE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MODE_LINE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetModeLineRequest { screen, }) } } impl Request for GetModeLineRequest { type Reply = GetModeLineReply; } pub fn get_mode_line(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetModeLineRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetModeLineReply { pub sequence: u16, pub length: u32, pub dotclock: Dotclock, pub hdisplay: u16, pub hsyncstart: u16, pub hsyncend: u16, pub htotal: u16, pub hskew: u16, pub vdisplay: u16, pub vsyncstart: u16, pub vsyncend: u16, pub vtotal: u16, pub flags: u32, pub private: Vec, } impl TryParse for GetModeLineReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (dotclock, remaining) = Dotclock::try_parse(remaining)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; let (hsyncend, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u16::try_parse(remaining)?; let (vdisplay, remaining) = u16::try_parse(remaining)?; let (vsyncstart, remaining) = u16::try_parse(remaining)?; let (vsyncend, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (privsize, remaining) = u32::try_parse(remaining)?; let (private, remaining) = crate::x11_utils::parse_u8_list(remaining, privsize.try_to_usize()?)?; let private = private.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetModeLineReply { sequence, length, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetModeLineReply { /// Get the value of the `privsize` field. /// /// The `privsize` field is used as the length field of the `private` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn privsize(&self) -> u32 { self.private.len() .try_into().unwrap() } } /// Opcode for the ModModeLine request pub const MOD_MODE_LINE_REQUEST: u8 = 2; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ModModeLineRequest<'input> { pub screen: u32, pub hdisplay: u16, pub hsyncstart: u16, pub hsyncend: u16, pub htotal: u16, pub hskew: u16, pub vdisplay: u16, pub vsyncstart: u16, pub vsyncend: u16, pub vtotal: u16, pub flags: u32, pub private: Cow<'input, [u8]>, } impl<'input> ModModeLineRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let hdisplay_bytes = self.hdisplay.serialize(); let hsyncstart_bytes = self.hsyncstart.serialize(); let hsyncend_bytes = self.hsyncend.serialize(); let htotal_bytes = self.htotal.serialize(); let hskew_bytes = self.hskew.serialize(); let vdisplay_bytes = self.vdisplay.serialize(); let vsyncstart_bytes = self.vsyncstart.serialize(); let vsyncend_bytes = self.vsyncend.serialize(); let vtotal_bytes = self.vtotal.serialize(); let flags_bytes = self.flags.serialize(); let privsize = u32::try_from(self.private.len()).expect("`private` has too many elements"); let privsize_bytes = privsize.serialize(); let mut request0 = vec![ extension_information.major_opcode, MOD_MODE_LINE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], hdisplay_bytes[0], hdisplay_bytes[1], hsyncstart_bytes[0], hsyncstart_bytes[1], hsyncend_bytes[0], hsyncend_bytes[1], htotal_bytes[0], htotal_bytes[1], hskew_bytes[0], hskew_bytes[1], vdisplay_bytes[0], vdisplay_bytes[1], vsyncstart_bytes[0], vsyncstart_bytes[1], vsyncend_bytes[0], vsyncend_bytes[1], vtotal_bytes[0], vtotal_bytes[1], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, privsize_bytes[0], privsize_bytes[1], privsize_bytes[2], privsize_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.private.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.private, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != MOD_MODE_LINE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; let (hsyncend, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u16::try_parse(remaining)?; let (vdisplay, remaining) = u16::try_parse(remaining)?; let (vsyncstart, remaining) = u16::try_parse(remaining)?; let (vsyncend, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (privsize, remaining) = u32::try_parse(remaining)?; let (private, remaining) = crate::x11_utils::parse_u8_list(remaining, privsize.try_to_usize()?)?; let _ = remaining; Ok(ModModeLineRequest { screen, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }) } /// Clone all borrowed data in this ModModeLineRequest. pub fn into_owned(self) -> ModModeLineRequest<'static> { ModModeLineRequest { screen: self.screen, hdisplay: self.hdisplay, hsyncstart: self.hsyncstart, hsyncend: self.hsyncend, htotal: self.htotal, hskew: self.hskew, vdisplay: self.vdisplay, vsyncstart: self.vsyncstart, vsyncend: self.vsyncend, vtotal: self.vtotal, flags: self.flags, private: Cow::Owned(self.private.into_owned()), } } } impl<'input> Request for ModModeLineRequest<'input> { type Reply = (); } pub fn mod_mode_line<'c, 'input, Conn, A>(conn: &'c Conn, screen: u32, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let flags: u32 = flags.into(); let request0 = ModModeLineRequest { screen, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }; request0.send(conn) } /// Opcode for the SwitchMode request pub const SWITCH_MODE_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SwitchModeRequest { pub screen: u16, pub zoom: u16, } impl SwitchModeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let zoom_bytes = self.zoom.serialize(); let mut request0 = vec![ extension_information.major_opcode, SWITCH_MODE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], zoom_bytes[0], zoom_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SWITCH_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let (zoom, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(SwitchModeRequest { screen, zoom, }) } } impl Request for SwitchModeRequest { type Reply = (); } pub fn switch_mode(conn: &Conn, screen: u16, zoom: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SwitchModeRequest { screen, zoom, }; request0.send(conn) } /// Opcode for the GetMonitor request pub const GET_MONITOR_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMonitorRequest { pub screen: u16, } impl GetMonitorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MONITOR_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MONITOR_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetMonitorRequest { screen, }) } } impl Request for GetMonitorRequest { type Reply = GetMonitorReply; } pub fn get_monitor(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetMonitorRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetMonitorReply { pub sequence: u16, pub length: u32, pub hsync: Vec, pub vsync: Vec, pub vendor: Vec, pub alignment_pad: Vec, pub model: Vec, } impl TryParse for GetMonitorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (vendor_length, remaining) = u8::try_parse(remaining)?; let (model_length, remaining) = u8::try_parse(remaining)?; let (num_hsync, remaining) = u8::try_parse(remaining)?; let (num_vsync, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (hsync, remaining) = crate::x11_utils::parse_list::(remaining, num_hsync.try_to_usize()?)?; let (vsync, remaining) = crate::x11_utils::parse_list::(remaining, num_vsync.try_to_usize()?)?; let (vendor, remaining) = crate::x11_utils::parse_u8_list(remaining, vendor_length.try_to_usize()?)?; let vendor = vendor.to_vec(); let (alignment_pad, remaining) = crate::x11_utils::parse_u8_list(remaining, (u32::from(vendor_length).checked_add(3u32).ok_or(ParseError::InvalidExpression)? & (!3u32)).checked_sub(u32::from(vendor_length)).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let alignment_pad = alignment_pad.to_vec(); let (model, remaining) = crate::x11_utils::parse_u8_list(remaining, model_length.try_to_usize()?)?; let model = model.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMonitorReply { sequence, length, hsync, vsync, vendor, alignment_pad, model }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetMonitorReply { /// Get the value of the `vendor_length` field. /// /// The `vendor_length` field is used as the length field of the `vendor` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn vendor_length(&self) -> u8 { self.vendor.len() .try_into().unwrap() } /// Get the value of the `model_length` field. /// /// The `model_length` field is used as the length field of the `model` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn model_length(&self) -> u8 { self.model.len() .try_into().unwrap() } /// Get the value of the `num_hsync` field. /// /// The `num_hsync` field is used as the length field of the `hsync` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_hsync(&self) -> u8 { self.hsync.len() .try_into().unwrap() } /// Get the value of the `num_vsync` field. /// /// The `num_vsync` field is used as the length field of the `vsync` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_vsync(&self) -> u8 { self.vsync.len() .try_into().unwrap() } } /// Opcode for the LockModeSwitch request pub const LOCK_MODE_SWITCH_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct LockModeSwitchRequest { pub screen: u16, pub lock: u16, } impl LockModeSwitchRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let lock_bytes = self.lock.serialize(); let mut request0 = vec![ extension_information.major_opcode, LOCK_MODE_SWITCH_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], lock_bytes[0], lock_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LOCK_MODE_SWITCH_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let (lock, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(LockModeSwitchRequest { screen, lock, }) } } impl Request for LockModeSwitchRequest { type Reply = (); } pub fn lock_mode_switch(conn: &Conn, screen: u16, lock: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = LockModeSwitchRequest { screen, lock, }; request0.send(conn) } /// Opcode for the GetAllModeLines request pub const GET_ALL_MODE_LINES_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetAllModeLinesRequest { pub screen: u16, } impl GetAllModeLinesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_ALL_MODE_LINES_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_ALL_MODE_LINES_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetAllModeLinesRequest { screen, }) } } impl Request for GetAllModeLinesRequest { type Reply = GetAllModeLinesReply; } pub fn get_all_mode_lines(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetAllModeLinesRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetAllModeLinesReply { pub sequence: u16, pub length: u32, pub modeinfo: Vec, } impl TryParse for GetAllModeLinesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (modecount, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (modeinfo, remaining) = crate::x11_utils::parse_list::(remaining, modecount.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetAllModeLinesReply { sequence, length, modeinfo }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetAllModeLinesReply { /// Get the value of the `modecount` field. /// /// The `modecount` field is used as the length field of the `modeinfo` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn modecount(&self) -> u32 { self.modeinfo.len() .try_into().unwrap() } } /// Opcode for the AddModeLine request pub const ADD_MODE_LINE_REQUEST: u8 = 7; #[derive(Debug, Clone, PartialEq, Eq)] pub struct AddModeLineRequest<'input> { pub screen: u32, pub dotclock: Dotclock, pub hdisplay: u16, pub hsyncstart: u16, pub hsyncend: u16, pub htotal: u16, pub hskew: u16, pub vdisplay: u16, pub vsyncstart: u16, pub vsyncend: u16, pub vtotal: u16, pub flags: u32, pub after_dotclock: Dotclock, pub after_hdisplay: u16, pub after_hsyncstart: u16, pub after_hsyncend: u16, pub after_htotal: u16, pub after_hskew: u16, pub after_vdisplay: u16, pub after_vsyncstart: u16, pub after_vsyncend: u16, pub after_vtotal: u16, pub after_flags: u32, pub private: Cow<'input, [u8]>, } impl<'input> AddModeLineRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let dotclock_bytes = self.dotclock.serialize(); let hdisplay_bytes = self.hdisplay.serialize(); let hsyncstart_bytes = self.hsyncstart.serialize(); let hsyncend_bytes = self.hsyncend.serialize(); let htotal_bytes = self.htotal.serialize(); let hskew_bytes = self.hskew.serialize(); let vdisplay_bytes = self.vdisplay.serialize(); let vsyncstart_bytes = self.vsyncstart.serialize(); let vsyncend_bytes = self.vsyncend.serialize(); let vtotal_bytes = self.vtotal.serialize(); let flags_bytes = self.flags.serialize(); let privsize = u32::try_from(self.private.len()).expect("`private` has too many elements"); let privsize_bytes = privsize.serialize(); let after_dotclock_bytes = self.after_dotclock.serialize(); let after_hdisplay_bytes = self.after_hdisplay.serialize(); let after_hsyncstart_bytes = self.after_hsyncstart.serialize(); let after_hsyncend_bytes = self.after_hsyncend.serialize(); let after_htotal_bytes = self.after_htotal.serialize(); let after_hskew_bytes = self.after_hskew.serialize(); let after_vdisplay_bytes = self.after_vdisplay.serialize(); let after_vsyncstart_bytes = self.after_vsyncstart.serialize(); let after_vsyncend_bytes = self.after_vsyncend.serialize(); let after_vtotal_bytes = self.after_vtotal.serialize(); let after_flags_bytes = self.after_flags.serialize(); let mut request0 = vec![ extension_information.major_opcode, ADD_MODE_LINE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], dotclock_bytes[0], dotclock_bytes[1], dotclock_bytes[2], dotclock_bytes[3], hdisplay_bytes[0], hdisplay_bytes[1], hsyncstart_bytes[0], hsyncstart_bytes[1], hsyncend_bytes[0], hsyncend_bytes[1], htotal_bytes[0], htotal_bytes[1], hskew_bytes[0], hskew_bytes[1], vdisplay_bytes[0], vdisplay_bytes[1], vsyncstart_bytes[0], vsyncstart_bytes[1], vsyncend_bytes[0], vsyncend_bytes[1], vtotal_bytes[0], vtotal_bytes[1], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, privsize_bytes[0], privsize_bytes[1], privsize_bytes[2], privsize_bytes[3], after_dotclock_bytes[0], after_dotclock_bytes[1], after_dotclock_bytes[2], after_dotclock_bytes[3], after_hdisplay_bytes[0], after_hdisplay_bytes[1], after_hsyncstart_bytes[0], after_hsyncstart_bytes[1], after_hsyncend_bytes[0], after_hsyncend_bytes[1], after_htotal_bytes[0], after_htotal_bytes[1], after_hskew_bytes[0], after_hskew_bytes[1], after_vdisplay_bytes[0], after_vdisplay_bytes[1], after_vsyncstart_bytes[0], after_vsyncstart_bytes[1], after_vsyncend_bytes[0], after_vsyncend_bytes[1], after_vtotal_bytes[0], after_vtotal_bytes[1], 0, 0, after_flags_bytes[0], after_flags_bytes[1], after_flags_bytes[2], after_flags_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.private.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.private, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != ADD_MODE_LINE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (dotclock, remaining) = Dotclock::try_parse(remaining)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; let (hsyncend, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u16::try_parse(remaining)?; let (vdisplay, remaining) = u16::try_parse(remaining)?; let (vsyncstart, remaining) = u16::try_parse(remaining)?; let (vsyncend, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (privsize, remaining) = u32::try_parse(remaining)?; let (after_dotclock, remaining) = Dotclock::try_parse(remaining)?; let (after_hdisplay, remaining) = u16::try_parse(remaining)?; let (after_hsyncstart, remaining) = u16::try_parse(remaining)?; let (after_hsyncend, remaining) = u16::try_parse(remaining)?; let (after_htotal, remaining) = u16::try_parse(remaining)?; let (after_hskew, remaining) = u16::try_parse(remaining)?; let (after_vdisplay, remaining) = u16::try_parse(remaining)?; let (after_vsyncstart, remaining) = u16::try_parse(remaining)?; let (after_vsyncend, remaining) = u16::try_parse(remaining)?; let (after_vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (after_flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (private, remaining) = crate::x11_utils::parse_u8_list(remaining, privsize.try_to_usize()?)?; let _ = remaining; Ok(AddModeLineRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, after_dotclock, after_hdisplay, after_hsyncstart, after_hsyncend, after_htotal, after_hskew, after_vdisplay, after_vsyncstart, after_vsyncend, after_vtotal, after_flags, private: Cow::Borrowed(private), }) } /// Clone all borrowed data in this AddModeLineRequest. pub fn into_owned(self) -> AddModeLineRequest<'static> { AddModeLineRequest { screen: self.screen, dotclock: self.dotclock, hdisplay: self.hdisplay, hsyncstart: self.hsyncstart, hsyncend: self.hsyncend, htotal: self.htotal, hskew: self.hskew, vdisplay: self.vdisplay, vsyncstart: self.vsyncstart, vsyncend: self.vsyncend, vtotal: self.vtotal, flags: self.flags, after_dotclock: self.after_dotclock, after_hdisplay: self.after_hdisplay, after_hsyncstart: self.after_hsyncstart, after_hsyncend: self.after_hsyncend, after_htotal: self.after_htotal, after_hskew: self.after_hskew, after_vdisplay: self.after_vdisplay, after_vsyncstart: self.after_vsyncstart, after_vsyncend: self.after_vsyncend, after_vtotal: self.after_vtotal, after_flags: self.after_flags, private: Cow::Owned(self.private.into_owned()), } } } impl<'input> Request for AddModeLineRequest<'input> { type Reply = (); } pub fn add_mode_line<'c, 'input, Conn, A, B>(conn: &'c Conn, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, after_dotclock: Dotclock, after_hdisplay: u16, after_hsyncstart: u16, after_hsyncend: u16, after_htotal: u16, after_hskew: u16, after_vdisplay: u16, after_vsyncstart: u16, after_vsyncend: u16, after_vtotal: u16, after_flags: B, private: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let flags: u32 = flags.into(); let after_flags: u32 = after_flags.into(); let request0 = AddModeLineRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, after_dotclock, after_hdisplay, after_hsyncstart, after_hsyncend, after_htotal, after_hskew, after_vdisplay, after_vsyncstart, after_vsyncend, after_vtotal, after_flags, private: Cow::Borrowed(private), }; request0.send(conn) } /// Opcode for the DeleteModeLine request pub const DELETE_MODE_LINE_REQUEST: u8 = 8; #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeleteModeLineRequest<'input> { pub screen: u32, pub dotclock: Dotclock, pub hdisplay: u16, pub hsyncstart: u16, pub hsyncend: u16, pub htotal: u16, pub hskew: u16, pub vdisplay: u16, pub vsyncstart: u16, pub vsyncend: u16, pub vtotal: u16, pub flags: u32, pub private: Cow<'input, [u8]>, } impl<'input> DeleteModeLineRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let dotclock_bytes = self.dotclock.serialize(); let hdisplay_bytes = self.hdisplay.serialize(); let hsyncstart_bytes = self.hsyncstart.serialize(); let hsyncend_bytes = self.hsyncend.serialize(); let htotal_bytes = self.htotal.serialize(); let hskew_bytes = self.hskew.serialize(); let vdisplay_bytes = self.vdisplay.serialize(); let vsyncstart_bytes = self.vsyncstart.serialize(); let vsyncend_bytes = self.vsyncend.serialize(); let vtotal_bytes = self.vtotal.serialize(); let flags_bytes = self.flags.serialize(); let privsize = u32::try_from(self.private.len()).expect("`private` has too many elements"); let privsize_bytes = privsize.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_MODE_LINE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], dotclock_bytes[0], dotclock_bytes[1], dotclock_bytes[2], dotclock_bytes[3], hdisplay_bytes[0], hdisplay_bytes[1], hsyncstart_bytes[0], hsyncstart_bytes[1], hsyncend_bytes[0], hsyncend_bytes[1], htotal_bytes[0], htotal_bytes[1], hskew_bytes[0], hskew_bytes[1], vdisplay_bytes[0], vdisplay_bytes[1], vsyncstart_bytes[0], vsyncstart_bytes[1], vsyncend_bytes[0], vsyncend_bytes[1], vtotal_bytes[0], vtotal_bytes[1], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, privsize_bytes[0], privsize_bytes[1], privsize_bytes[2], privsize_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.private.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.private, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != DELETE_MODE_LINE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (dotclock, remaining) = Dotclock::try_parse(remaining)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; let (hsyncend, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u16::try_parse(remaining)?; let (vdisplay, remaining) = u16::try_parse(remaining)?; let (vsyncstart, remaining) = u16::try_parse(remaining)?; let (vsyncend, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (privsize, remaining) = u32::try_parse(remaining)?; let (private, remaining) = crate::x11_utils::parse_u8_list(remaining, privsize.try_to_usize()?)?; let _ = remaining; Ok(DeleteModeLineRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }) } /// Clone all borrowed data in this DeleteModeLineRequest. pub fn into_owned(self) -> DeleteModeLineRequest<'static> { DeleteModeLineRequest { screen: self.screen, dotclock: self.dotclock, hdisplay: self.hdisplay, hsyncstart: self.hsyncstart, hsyncend: self.hsyncend, htotal: self.htotal, hskew: self.hskew, vdisplay: self.vdisplay, vsyncstart: self.vsyncstart, vsyncend: self.vsyncend, vtotal: self.vtotal, flags: self.flags, private: Cow::Owned(self.private.into_owned()), } } } impl<'input> Request for DeleteModeLineRequest<'input> { type Reply = (); } pub fn delete_mode_line<'c, 'input, Conn, A>(conn: &'c Conn, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let flags: u32 = flags.into(); let request0 = DeleteModeLineRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }; request0.send(conn) } /// Opcode for the ValidateModeLine request pub const VALIDATE_MODE_LINE_REQUEST: u8 = 9; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ValidateModeLineRequest<'input> { pub screen: u32, pub dotclock: Dotclock, pub hdisplay: u16, pub hsyncstart: u16, pub hsyncend: u16, pub htotal: u16, pub hskew: u16, pub vdisplay: u16, pub vsyncstart: u16, pub vsyncend: u16, pub vtotal: u16, pub flags: u32, pub private: Cow<'input, [u8]>, } impl<'input> ValidateModeLineRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let dotclock_bytes = self.dotclock.serialize(); let hdisplay_bytes = self.hdisplay.serialize(); let hsyncstart_bytes = self.hsyncstart.serialize(); let hsyncend_bytes = self.hsyncend.serialize(); let htotal_bytes = self.htotal.serialize(); let hskew_bytes = self.hskew.serialize(); let vdisplay_bytes = self.vdisplay.serialize(); let vsyncstart_bytes = self.vsyncstart.serialize(); let vsyncend_bytes = self.vsyncend.serialize(); let vtotal_bytes = self.vtotal.serialize(); let flags_bytes = self.flags.serialize(); let privsize = u32::try_from(self.private.len()).expect("`private` has too many elements"); let privsize_bytes = privsize.serialize(); let mut request0 = vec![ extension_information.major_opcode, VALIDATE_MODE_LINE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], dotclock_bytes[0], dotclock_bytes[1], dotclock_bytes[2], dotclock_bytes[3], hdisplay_bytes[0], hdisplay_bytes[1], hsyncstart_bytes[0], hsyncstart_bytes[1], hsyncend_bytes[0], hsyncend_bytes[1], htotal_bytes[0], htotal_bytes[1], hskew_bytes[0], hskew_bytes[1], vdisplay_bytes[0], vdisplay_bytes[1], vsyncstart_bytes[0], vsyncstart_bytes[1], vsyncend_bytes[0], vsyncend_bytes[1], vtotal_bytes[0], vtotal_bytes[1], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, privsize_bytes[0], privsize_bytes[1], privsize_bytes[2], privsize_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.private.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.private, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != VALIDATE_MODE_LINE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (dotclock, remaining) = Dotclock::try_parse(remaining)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; let (hsyncend, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u16::try_parse(remaining)?; let (vdisplay, remaining) = u16::try_parse(remaining)?; let (vsyncstart, remaining) = u16::try_parse(remaining)?; let (vsyncend, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (privsize, remaining) = u32::try_parse(remaining)?; let (private, remaining) = crate::x11_utils::parse_u8_list(remaining, privsize.try_to_usize()?)?; let _ = remaining; Ok(ValidateModeLineRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }) } /// Clone all borrowed data in this ValidateModeLineRequest. pub fn into_owned(self) -> ValidateModeLineRequest<'static> { ValidateModeLineRequest { screen: self.screen, dotclock: self.dotclock, hdisplay: self.hdisplay, hsyncstart: self.hsyncstart, hsyncend: self.hsyncend, htotal: self.htotal, hskew: self.hskew, vdisplay: self.vdisplay, vsyncstart: self.vsyncstart, vsyncend: self.vsyncend, vtotal: self.vtotal, flags: self.flags, private: Cow::Owned(self.private.into_owned()), } } } impl<'input> Request for ValidateModeLineRequest<'input> { type Reply = ValidateModeLineReply; } pub fn validate_mode_line<'c, 'input, Conn, A>(conn: &'c Conn, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let flags: u32 = flags.into(); let request0 = ValidateModeLineRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ValidateModeLineReply { pub sequence: u16, pub length: u32, pub status: u32, } impl TryParse for ValidateModeLineReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ValidateModeLineReply { sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SwitchToMode request pub const SWITCH_TO_MODE_REQUEST: u8 = 10; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SwitchToModeRequest<'input> { pub screen: u32, pub dotclock: Dotclock, pub hdisplay: u16, pub hsyncstart: u16, pub hsyncend: u16, pub htotal: u16, pub hskew: u16, pub vdisplay: u16, pub vsyncstart: u16, pub vsyncend: u16, pub vtotal: u16, pub flags: u32, pub private: Cow<'input, [u8]>, } impl<'input> SwitchToModeRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let dotclock_bytes = self.dotclock.serialize(); let hdisplay_bytes = self.hdisplay.serialize(); let hsyncstart_bytes = self.hsyncstart.serialize(); let hsyncend_bytes = self.hsyncend.serialize(); let htotal_bytes = self.htotal.serialize(); let hskew_bytes = self.hskew.serialize(); let vdisplay_bytes = self.vdisplay.serialize(); let vsyncstart_bytes = self.vsyncstart.serialize(); let vsyncend_bytes = self.vsyncend.serialize(); let vtotal_bytes = self.vtotal.serialize(); let flags_bytes = self.flags.serialize(); let privsize = u32::try_from(self.private.len()).expect("`private` has too many elements"); let privsize_bytes = privsize.serialize(); let mut request0 = vec![ extension_information.major_opcode, SWITCH_TO_MODE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], dotclock_bytes[0], dotclock_bytes[1], dotclock_bytes[2], dotclock_bytes[3], hdisplay_bytes[0], hdisplay_bytes[1], hsyncstart_bytes[0], hsyncstart_bytes[1], hsyncend_bytes[0], hsyncend_bytes[1], htotal_bytes[0], htotal_bytes[1], hskew_bytes[0], hskew_bytes[1], vdisplay_bytes[0], vdisplay_bytes[1], vsyncstart_bytes[0], vsyncstart_bytes[1], vsyncend_bytes[0], vsyncend_bytes[1], vtotal_bytes[0], vtotal_bytes[1], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, privsize_bytes[0], privsize_bytes[1], privsize_bytes[2], privsize_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.private.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.private, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SWITCH_TO_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u32::try_parse(value)?; let (dotclock, remaining) = Dotclock::try_parse(remaining)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; let (hsyncend, remaining) = u16::try_parse(remaining)?; let (htotal, remaining) = u16::try_parse(remaining)?; let (hskew, remaining) = u16::try_parse(remaining)?; let (vdisplay, remaining) = u16::try_parse(remaining)?; let (vsyncstart, remaining) = u16::try_parse(remaining)?; let (vsyncend, remaining) = u16::try_parse(remaining)?; let (vtotal, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (privsize, remaining) = u32::try_parse(remaining)?; let (private, remaining) = crate::x11_utils::parse_u8_list(remaining, privsize.try_to_usize()?)?; let _ = remaining; Ok(SwitchToModeRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }) } /// Clone all borrowed data in this SwitchToModeRequest. pub fn into_owned(self) -> SwitchToModeRequest<'static> { SwitchToModeRequest { screen: self.screen, dotclock: self.dotclock, hdisplay: self.hdisplay, hsyncstart: self.hsyncstart, hsyncend: self.hsyncend, htotal: self.htotal, hskew: self.hskew, vdisplay: self.vdisplay, vsyncstart: self.vsyncstart, vsyncend: self.vsyncend, vtotal: self.vtotal, flags: self.flags, private: Cow::Owned(self.private.into_owned()), } } } impl<'input> Request for SwitchToModeRequest<'input> { type Reply = (); } pub fn switch_to_mode<'c, 'input, Conn, A>(conn: &'c Conn, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let flags: u32 = flags.into(); let request0 = SwitchToModeRequest { screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private: Cow::Borrowed(private), }; request0.send(conn) } /// Opcode for the GetViewPort request pub const GET_VIEW_PORT_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetViewPortRequest { pub screen: u16, } impl GetViewPortRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_VIEW_PORT_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_VIEW_PORT_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetViewPortRequest { screen, }) } } impl Request for GetViewPortRequest { type Reply = GetViewPortReply; } pub fn get_view_port(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetViewPortRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetViewPortReply { pub sequence: u16, pub length: u32, pub x: u32, pub y: u32, } impl TryParse for GetViewPortReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (x, remaining) = u32::try_parse(remaining)?; let (y, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetViewPortReply { sequence, length, x, y }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetViewPort request pub const SET_VIEW_PORT_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetViewPortRequest { pub screen: u16, pub x: u32, pub y: u32, } impl SetViewPortRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_VIEW_PORT_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, x_bytes[0], x_bytes[1], x_bytes[2], x_bytes[3], y_bytes[0], y_bytes[1], y_bytes[2], y_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_VIEW_PORT_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (x, remaining) = u32::try_parse(remaining)?; let (y, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SetViewPortRequest { screen, x, y, }) } } impl Request for SetViewPortRequest { type Reply = (); } pub fn set_view_port(conn: &Conn, screen: u16, x: u32, y: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetViewPortRequest { screen, x, y, }; request0.send(conn) } /// Opcode for the GetDotClocks request pub const GET_DOT_CLOCKS_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDotClocksRequest { pub screen: u16, } impl GetDotClocksRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DOT_CLOCKS_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DOT_CLOCKS_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDotClocksRequest { screen, }) } } impl Request for GetDotClocksRequest { type Reply = GetDotClocksReply; } pub fn get_dot_clocks(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDotClocksRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDotClocksReply { pub sequence: u16, pub length: u32, pub flags: u32, pub clocks: u32, pub maxclocks: u32, pub clock: Vec, } impl TryParse for GetDotClocksReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let (clocks, remaining) = u32::try_parse(remaining)?; let (maxclocks, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (clock, remaining) = crate::x11_utils::parse_list::(remaining, 1u32.checked_sub(flags & 1u32).ok_or(ParseError::InvalidExpression)?.checked_mul(clocks).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDotClocksReply { sequence, length, flags, clocks, maxclocks, clock }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetClientVersion request pub const SET_CLIENT_VERSION_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetClientVersionRequest { pub major: u16, pub minor: u16, } impl SetClientVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_bytes = self.major.serialize(); let minor_bytes = self.minor.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CLIENT_VERSION_REQUEST, 0, 0, major_bytes[0], major_bytes[1], minor_bytes[0], minor_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_CLIENT_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major, remaining) = u16::try_parse(value)?; let (minor, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(SetClientVersionRequest { major, minor, }) } } impl Request for SetClientVersionRequest { type Reply = (); } pub fn set_client_version(conn: &Conn, major: u16, minor: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetClientVersionRequest { major, minor, }; request0.send(conn) } /// Opcode for the SetGamma request pub const SET_GAMMA_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetGammaRequest { pub screen: u16, pub red: u32, pub green: u32, pub blue: u32, } impl SetGammaRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let red_bytes = self.red.serialize(); let green_bytes = self.green.serialize(); let blue_bytes = self.blue.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_GAMMA_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, red_bytes[0], red_bytes[1], red_bytes[2], red_bytes[3], green_bytes[0], green_bytes[1], green_bytes[2], green_bytes[3], blue_bytes[0], blue_bytes[1], blue_bytes[2], blue_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_GAMMA_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (red, remaining) = u32::try_parse(remaining)?; let (green, remaining) = u32::try_parse(remaining)?; let (blue, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SetGammaRequest { screen, red, green, blue, }) } } impl Request for SetGammaRequest { type Reply = (); } pub fn set_gamma(conn: &Conn, screen: u16, red: u32, green: u32, blue: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetGammaRequest { screen, red, green, blue, }; request0.send(conn) } /// Opcode for the GetGamma request pub const GET_GAMMA_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetGammaRequest { pub screen: u16, } impl GetGammaRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_GAMMA_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_GAMMA_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(26..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetGammaRequest { screen, }) } } impl Request for GetGammaRequest { type Reply = GetGammaReply; } pub fn get_gamma(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetGammaRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetGammaReply { pub sequence: u16, pub length: u32, pub red: u32, pub green: u32, pub blue: u32, } impl TryParse for GetGammaReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (red, remaining) = u32::try_parse(remaining)?; let (green, remaining) = u32::try_parse(remaining)?; let (blue, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetGammaReply { sequence, length, red, green, blue }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetGammaRamp request pub const GET_GAMMA_RAMP_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetGammaRampRequest { pub screen: u16, pub size: u16, } impl GetGammaRampRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let size_bytes = self.size.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_GAMMA_RAMP_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], size_bytes[0], size_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_GAMMA_RAMP_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let (size, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(GetGammaRampRequest { screen, size, }) } } impl Request for GetGammaRampRequest { type Reply = GetGammaRampReply; } pub fn get_gamma_ramp(conn: &Conn, screen: u16, size: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetGammaRampRequest { screen, size, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetGammaRampReply { pub sequence: u16, pub length: u32, pub size: u16, pub red: Vec, pub green: Vec, pub blue: Vec, } impl TryParse for GetGammaRampReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (size, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (red, remaining) = crate::x11_utils::parse_list::(remaining, (u32::from(size).checked_add(1u32).ok_or(ParseError::InvalidExpression)? & (!1u32)).try_to_usize()?)?; let (green, remaining) = crate::x11_utils::parse_list::(remaining, (u32::from(size).checked_add(1u32).ok_or(ParseError::InvalidExpression)? & (!1u32)).try_to_usize()?)?; let (blue, remaining) = crate::x11_utils::parse_list::(remaining, (u32::from(size).checked_add(1u32).ok_or(ParseError::InvalidExpression)? & (!1u32)).try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetGammaRampReply { sequence, length, size, red, green, blue }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetGammaRamp request pub const SET_GAMMA_RAMP_REQUEST: u8 = 18; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetGammaRampRequest<'input> { pub screen: u16, pub size: u16, pub red: Cow<'input, [u16]>, pub green: Cow<'input, [u16]>, pub blue: Cow<'input, [u16]>, } impl<'input> SetGammaRampRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let size_bytes = self.size.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_GAMMA_RAMP_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], size_bytes[0], size_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(self.red.len(), usize::try_from(u32::from(self.size).checked_add(1u32).unwrap() & (!1u32)).unwrap(), "`red` has an incorrect length"); let red_bytes = self.red.serialize(); let length_so_far = length_so_far + red_bytes.len(); assert_eq!(self.green.len(), usize::try_from(u32::from(self.size).checked_add(1u32).unwrap() & (!1u32)).unwrap(), "`green` has an incorrect length"); let green_bytes = self.green.serialize(); let length_so_far = length_so_far + green_bytes.len(); assert_eq!(self.blue.len(), usize::try_from(u32::from(self.size).checked_add(1u32).unwrap() & (!1u32)).unwrap(), "`blue` has an incorrect length"); let blue_bytes = self.blue.serialize(); let length_so_far = length_so_far + blue_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), red_bytes.into(), green_bytes.into(), blue_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_GAMMA_RAMP_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let (size, remaining) = u16::try_parse(remaining)?; let (red, remaining) = crate::x11_utils::parse_list::(remaining, (u32::from(size).checked_add(1u32).ok_or(ParseError::InvalidExpression)? & (!1u32)).try_to_usize()?)?; let (green, remaining) = crate::x11_utils::parse_list::(remaining, (u32::from(size).checked_add(1u32).ok_or(ParseError::InvalidExpression)? & (!1u32)).try_to_usize()?)?; let (blue, remaining) = crate::x11_utils::parse_list::(remaining, (u32::from(size).checked_add(1u32).ok_or(ParseError::InvalidExpression)? & (!1u32)).try_to_usize()?)?; let _ = remaining; Ok(SetGammaRampRequest { screen, size, red: Cow::Owned(red), green: Cow::Owned(green), blue: Cow::Owned(blue), }) } /// Clone all borrowed data in this SetGammaRampRequest. pub fn into_owned(self) -> SetGammaRampRequest<'static> { SetGammaRampRequest { screen: self.screen, size: self.size, red: Cow::Owned(self.red.into_owned()), green: Cow::Owned(self.green.into_owned()), blue: Cow::Owned(self.blue.into_owned()), } } } impl<'input> Request for SetGammaRampRequest<'input> { type Reply = (); } pub fn set_gamma_ramp<'c, 'input, Conn>(conn: &'c Conn, screen: u16, size: u16, red: &'input [u16], green: &'input [u16], blue: &'input [u16]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetGammaRampRequest { screen, size, red: Cow::Borrowed(red), green: Cow::Borrowed(green), blue: Cow::Borrowed(blue), }; request0.send(conn) } /// Opcode for the GetGammaRampSize request pub const GET_GAMMA_RAMP_SIZE_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetGammaRampSizeRequest { pub screen: u16, } impl GetGammaRampSizeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_GAMMA_RAMP_SIZE_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_GAMMA_RAMP_SIZE_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetGammaRampSizeRequest { screen, }) } } impl Request for GetGammaRampSizeRequest { type Reply = GetGammaRampSizeReply; } pub fn get_gamma_ramp_size(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetGammaRampSizeRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetGammaRampSizeReply { pub sequence: u16, pub length: u32, pub size: u16, } impl TryParse for GetGammaRampSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (size, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetGammaRampSizeReply { sequence, length, size }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetPermissions request pub const GET_PERMISSIONS_REQUEST: u8 = 20; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPermissionsRequest { pub screen: u16, } impl GetPermissionsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PERMISSIONS_REQUEST, 0, 0, screen_bytes[0], screen_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PERMISSIONS_REQUEST { return Err(ParseError::InvalidValue); } let (screen, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetPermissionsRequest { screen, }) } } impl Request for GetPermissionsRequest { type Reply = GetPermissionsReply; } pub fn get_permissions(conn: &Conn, screen: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPermissionsRequest { screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPermissionsReply { pub sequence: u16, pub length: u32, pub permissions: u32, } impl TryParse for GetPermissionsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (permissions, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPermissionsReply { sequence, length, permissions }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the BadClock error pub const BAD_CLOCK_ERROR: u8 = 0; /// Opcode for the BadHTimings error pub const BAD_H_TIMINGS_ERROR: u8 = 1; /// Opcode for the BadVTimings error pub const BAD_V_TIMINGS_ERROR: u8 = 2; /// Opcode for the ModeUnsuitable error pub const MODE_UNSUITABLE_ERROR: u8 = 3; /// Opcode for the ExtensionDisabled error pub const EXTENSION_DISABLED_ERROR: u8 = 4; /// Opcode for the ClientNotLocal error pub const CLIENT_NOT_LOCAL_ERROR: u8 = 5; /// Opcode for the ZoomLocked error pub const ZOOM_LOCKED_ERROR: u8 = 6; /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xf86vidmode_query_version(&self) -> Result, ConnectionError> { query_version(self) } fn xf86vidmode_get_mode_line(&self, screen: u16) -> Result, ConnectionError> { get_mode_line(self, screen) } fn xf86vidmode_mod_mode_line<'c, 'input, A>(&'c self, screen: u32, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where A: Into, { mod_mode_line(self, screen, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private) } fn xf86vidmode_switch_mode(&self, screen: u16, zoom: u16) -> Result, ConnectionError> { switch_mode(self, screen, zoom) } fn xf86vidmode_get_monitor(&self, screen: u16) -> Result, ConnectionError> { get_monitor(self, screen) } fn xf86vidmode_lock_mode_switch(&self, screen: u16, lock: u16) -> Result, ConnectionError> { lock_mode_switch(self, screen, lock) } fn xf86vidmode_get_all_mode_lines(&self, screen: u16) -> Result, ConnectionError> { get_all_mode_lines(self, screen) } fn xf86vidmode_add_mode_line<'c, 'input, A, B>(&'c self, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, after_dotclock: Dotclock, after_hdisplay: u16, after_hsyncstart: u16, after_hsyncend: u16, after_htotal: u16, after_hskew: u16, after_vdisplay: u16, after_vsyncstart: u16, after_vsyncend: u16, after_vtotal: u16, after_flags: B, private: &'input [u8]) -> Result, ConnectionError> where A: Into, B: Into, { add_mode_line(self, screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, after_dotclock, after_hdisplay, after_hsyncstart, after_hsyncend, after_htotal, after_hskew, after_vdisplay, after_vsyncstart, after_vsyncend, after_vtotal, after_flags, private) } fn xf86vidmode_delete_mode_line<'c, 'input, A>(&'c self, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where A: Into, { delete_mode_line(self, screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private) } fn xf86vidmode_validate_mode_line<'c, 'input, A>(&'c self, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where A: Into, { validate_mode_line(self, screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private) } fn xf86vidmode_switch_to_mode<'c, 'input, A>(&'c self, screen: u32, dotclock: Dotclock, hdisplay: u16, hsyncstart: u16, hsyncend: u16, htotal: u16, hskew: u16, vdisplay: u16, vsyncstart: u16, vsyncend: u16, vtotal: u16, flags: A, private: &'input [u8]) -> Result, ConnectionError> where A: Into, { switch_to_mode(self, screen, dotclock, hdisplay, hsyncstart, hsyncend, htotal, hskew, vdisplay, vsyncstart, vsyncend, vtotal, flags, private) } fn xf86vidmode_get_view_port(&self, screen: u16) -> Result, ConnectionError> { get_view_port(self, screen) } fn xf86vidmode_set_view_port(&self, screen: u16, x: u32, y: u32) -> Result, ConnectionError> { set_view_port(self, screen, x, y) } fn xf86vidmode_get_dot_clocks(&self, screen: u16) -> Result, ConnectionError> { get_dot_clocks(self, screen) } fn xf86vidmode_set_client_version(&self, major: u16, minor: u16) -> Result, ConnectionError> { set_client_version(self, major, minor) } fn xf86vidmode_set_gamma(&self, screen: u16, red: u32, green: u32, blue: u32) -> Result, ConnectionError> { set_gamma(self, screen, red, green, blue) } fn xf86vidmode_get_gamma(&self, screen: u16) -> Result, ConnectionError> { get_gamma(self, screen) } fn xf86vidmode_get_gamma_ramp(&self, screen: u16, size: u16) -> Result, ConnectionError> { get_gamma_ramp(self, screen, size) } fn xf86vidmode_set_gamma_ramp<'c, 'input>(&'c self, screen: u16, size: u16, red: &'input [u16], green: &'input [u16], blue: &'input [u16]) -> Result, ConnectionError> { set_gamma_ramp(self, screen, size, red, green, blue) } fn xf86vidmode_get_gamma_ramp_size(&self, screen: u16) -> Result, ConnectionError> { get_gamma_ramp_size(self, screen) } fn xf86vidmode_get_permissions(&self, screen: u16) -> Result, ConnectionError> { get_permissions(self, screen) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xfixes.rs010064400017500001750000004125721402220031600151430ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `XFixes` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::render; use super::shape; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XFIXES"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (5, 0); /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major_version: u32, pub client_minor_version: u32, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_version_bytes = self.client_major_version.serialize(); let client_minor_version_bytes = self.client_minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_version_bytes[0], client_major_version_bytes[1], client_major_version_bytes[2], client_major_version_bytes[3], client_minor_version_bytes[0], client_minor_version_bytes[1], client_minor_version_bytes[2], client_minor_version_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major_version, remaining) = u32::try_parse(value)?; let (client_minor_version, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major_version, client_minor_version, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major_version, client_minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u32, pub minor_version: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SaveSetMode(u8); impl SaveSetMode { pub const INSERT: Self = Self(0); pub const DELETE: Self = Self(1); } impl From for u8 { #[inline] fn from(input: SaveSetMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SaveSetMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SaveSetMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SaveSetMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SaveSetMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SaveSetMode) -> Self { Some(u32::from(input.0)) } } impl From for SaveSetMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SaveSetMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::INSERT.0.into(), "INSERT", "Insert"), (Self::DELETE.0.into(), "DELETE", "Delete"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SaveSetTarget(u8); impl SaveSetTarget { pub const NEAREST: Self = Self(0); pub const ROOT: Self = Self(1); } impl From for u8 { #[inline] fn from(input: SaveSetTarget) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SaveSetTarget) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SaveSetTarget) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SaveSetTarget) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SaveSetTarget) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SaveSetTarget) -> Self { Some(u32::from(input.0)) } } impl From for SaveSetTarget { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SaveSetTarget { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NEAREST.0.into(), "NEAREST", "Nearest"), (Self::ROOT.0.into(), "ROOT", "Root"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SaveSetMapping(u8); impl SaveSetMapping { pub const MAP: Self = Self(0); pub const UNMAP: Self = Self(1); } impl From for u8 { #[inline] fn from(input: SaveSetMapping) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SaveSetMapping) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SaveSetMapping) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SaveSetMapping) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SaveSetMapping) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SaveSetMapping) -> Self { Some(u32::from(input.0)) } } impl From for SaveSetMapping { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SaveSetMapping { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::MAP.0.into(), "MAP", "Map"), (Self::UNMAP.0.into(), "UNMAP", "Unmap"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the ChangeSaveSet request pub const CHANGE_SAVE_SET_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangeSaveSetRequest { pub mode: SaveSetMode, pub target: SaveSetTarget, pub map: SaveSetMapping, pub window: xproto::Window, } impl ChangeSaveSetRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mode_bytes = u8::from(self.mode).serialize(); let target_bytes = u8::from(self.target).serialize(); let map_bytes = u8::from(self.map).serialize(); let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_SAVE_SET_REQUEST, 0, 0, mode_bytes[0], target_bytes[0], map_bytes[0], 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CHANGE_SAVE_SET_REQUEST { return Err(ParseError::InvalidValue); } let (mode, remaining) = u8::try_parse(value)?; let mode = mode.into(); let (target, remaining) = u8::try_parse(remaining)?; let target = target.into(); let (map, remaining) = u8::try_parse(remaining)?; let map = map.into(); let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let _ = remaining; Ok(ChangeSaveSetRequest { mode, target, map, window, }) } } impl Request for ChangeSaveSetRequest { type Reply = (); } pub fn change_save_set(conn: &Conn, mode: SaveSetMode, target: SaveSetTarget, map: SaveSetMapping, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeSaveSetRequest { mode, target, map, window, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SelectionEvent(u8); impl SelectionEvent { pub const SET_SELECTION_OWNER: Self = Self(0); pub const SELECTION_WINDOW_DESTROY: Self = Self(1); pub const SELECTION_CLIENT_CLOSE: Self = Self(2); } impl From for u8 { #[inline] fn from(input: SelectionEvent) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SelectionEvent) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SelectionEvent) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SelectionEvent) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SelectionEvent) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SelectionEvent) -> Self { Some(u32::from(input.0)) } } impl From for SelectionEvent { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SelectionEvent { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SET_SELECTION_OWNER.0.into(), "SET_SELECTION_OWNER", "SetSelectionOwner"), (Self::SELECTION_WINDOW_DESTROY.0.into(), "SELECTION_WINDOW_DESTROY", "SelectionWindowDestroy"), (Self::SELECTION_CLIENT_CLOSE.0.into(), "SELECTION_CLIENT_CLOSE", "SelectionClientClose"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SelectionEventMask(u8); impl SelectionEventMask { pub const SET_SELECTION_OWNER: Self = Self(1 << 0); pub const SELECTION_WINDOW_DESTROY: Self = Self(1 << 1); pub const SELECTION_CLIENT_CLOSE: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: SelectionEventMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SelectionEventMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SelectionEventMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SelectionEventMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SelectionEventMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SelectionEventMask) -> Self { Some(u32::from(input.0)) } } impl From for SelectionEventMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SelectionEventMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SET_SELECTION_OWNER.0.into(), "SET_SELECTION_OWNER", "SetSelectionOwner"), (Self::SELECTION_WINDOW_DESTROY.0.into(), "SELECTION_WINDOW_DESTROY", "SelectionWindowDestroy"), (Self::SELECTION_CLIENT_CLOSE.0.into(), "SELECTION_CLIENT_CLOSE", "SelectionClientClose"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SelectionEventMask, u8); /// Opcode for the SelectionNotify event pub const SELECTION_NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectionNotifyEvent { pub response_type: u8, pub subtype: SelectionEvent, pub sequence: u16, pub window: xproto::Window, pub owner: xproto::Window, pub selection: xproto::Atom, pub timestamp: xproto::Timestamp, pub selection_timestamp: xproto::Timestamp, } impl TryParse for SelectionNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (subtype, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (owner, remaining) = xproto::Window::try_parse(remaining)?; let (selection, remaining) = xproto::Atom::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (selection_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let subtype = subtype.into(); let result = SelectionNotifyEvent { response_type, subtype, sequence, window, owner, selection, timestamp, selection_timestamp }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&SelectionNotifyEvent> for [u8; 32] { fn from(input: &SelectionNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let subtype_bytes = u8::from(input.subtype).serialize(); let sequence_bytes = input.sequence.serialize(); let window_bytes = input.window.serialize(); let owner_bytes = input.owner.serialize(); let selection_bytes = input.selection.serialize(); let timestamp_bytes = input.timestamp.serialize(); let selection_timestamp_bytes = input.selection_timestamp.serialize(); [ response_type_bytes[0], subtype_bytes[0], sequence_bytes[0], sequence_bytes[1], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], owner_bytes[0], owner_bytes[1], owner_bytes[2], owner_bytes[3], selection_bytes[0], selection_bytes[1], selection_bytes[2], selection_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], selection_timestamp_bytes[0], selection_timestamp_bytes[1], selection_timestamp_bytes[2], selection_timestamp_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: SelectionNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the SelectSelectionInput request pub const SELECT_SELECTION_INPUT_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectSelectionInputRequest { pub window: xproto::Window, pub selection: xproto::Atom, pub event_mask: u32, } impl SelectSelectionInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let selection_bytes = self.selection.serialize(); let event_mask_bytes = self.event_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_SELECTION_INPUT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], selection_bytes[0], selection_bytes[1], selection_bytes[2], selection_bytes[3], event_mask_bytes[0], event_mask_bytes[1], event_mask_bytes[2], event_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_SELECTION_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (selection, remaining) = xproto::Atom::try_parse(remaining)?; let (event_mask, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SelectSelectionInputRequest { window, selection, event_mask, }) } } impl Request for SelectSelectionInputRequest { type Reply = (); } pub fn select_selection_input(conn: &Conn, window: xproto::Window, selection: xproto::Atom, event_mask: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let event_mask: u32 = event_mask.into(); let request0 = SelectSelectionInputRequest { window, selection, event_mask, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct CursorNotify(u8); impl CursorNotify { pub const DISPLAY_CURSOR: Self = Self(0); } impl From for u8 { #[inline] fn from(input: CursorNotify) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: CursorNotify) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: CursorNotify) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: CursorNotify) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: CursorNotify) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: CursorNotify) -> Self { Some(u32::from(input.0)) } } impl From for CursorNotify { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for CursorNotify { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DISPLAY_CURSOR.0.into(), "DISPLAY_CURSOR", "DisplayCursor"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct CursorNotifyMask(u8); impl CursorNotifyMask { pub const DISPLAY_CURSOR: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: CursorNotifyMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: CursorNotifyMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: CursorNotifyMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: CursorNotifyMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: CursorNotifyMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: CursorNotifyMask) -> Self { Some(u32::from(input.0)) } } impl From for CursorNotifyMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for CursorNotifyMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DISPLAY_CURSOR.0.into(), "DISPLAY_CURSOR", "DisplayCursor"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(CursorNotifyMask, u8); /// Opcode for the CursorNotify event pub const CURSOR_NOTIFY_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CursorNotifyEvent { pub response_type: u8, pub subtype: CursorNotify, pub sequence: u16, pub window: xproto::Window, pub cursor_serial: u32, pub timestamp: xproto::Timestamp, pub name: xproto::Atom, } impl TryParse for CursorNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (subtype, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (cursor_serial, remaining) = u32::try_parse(remaining)?; let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (name, remaining) = xproto::Atom::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let subtype = subtype.into(); let result = CursorNotifyEvent { response_type, subtype, sequence, window, cursor_serial, timestamp, name }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&CursorNotifyEvent> for [u8; 32] { fn from(input: &CursorNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let subtype_bytes = u8::from(input.subtype).serialize(); let sequence_bytes = input.sequence.serialize(); let window_bytes = input.window.serialize(); let cursor_serial_bytes = input.cursor_serial.serialize(); let timestamp_bytes = input.timestamp.serialize(); let name_bytes = input.name.serialize(); [ response_type_bytes[0], subtype_bytes[0], sequence_bytes[0], sequence_bytes[1], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], cursor_serial_bytes[0], cursor_serial_bytes[1], cursor_serial_bytes[2], cursor_serial_bytes[3], timestamp_bytes[0], timestamp_bytes[1], timestamp_bytes[2], timestamp_bytes[3], name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: CursorNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the SelectCursorInput request pub const SELECT_CURSOR_INPUT_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectCursorInputRequest { pub window: xproto::Window, pub event_mask: u32, } impl SelectCursorInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let event_mask_bytes = self.event_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_CURSOR_INPUT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], event_mask_bytes[0], event_mask_bytes[1], event_mask_bytes[2], event_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_CURSOR_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (event_mask, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SelectCursorInputRequest { window, event_mask, }) } } impl Request for SelectCursorInputRequest { type Reply = (); } pub fn select_cursor_input(conn: &Conn, window: xproto::Window, event_mask: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let event_mask: u32 = event_mask.into(); let request0 = SelectCursorInputRequest { window, event_mask, }; request0.send(conn) } /// Opcode for the GetCursorImage request pub const GET_CURSOR_IMAGE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCursorImageRequest; impl GetCursorImageRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_CURSOR_IMAGE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CURSOR_IMAGE_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetCursorImageRequest ) } } impl Request for GetCursorImageRequest { type Reply = GetCursorImageReply; } pub fn get_cursor_image(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCursorImageRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCursorImageReply { pub sequence: u16, pub length: u32, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub xhot: u16, pub yhot: u16, pub cursor_serial: u32, pub cursor_image: Vec, } impl TryParse for GetCursorImageReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (xhot, remaining) = u16::try_parse(remaining)?; let (yhot, remaining) = u16::try_parse(remaining)?; let (cursor_serial, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (cursor_image, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(width).checked_mul(u32::from(height)).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCursorImageReply { sequence, length, x, y, width, height, xhot, yhot, cursor_serial, cursor_image }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } pub type Region = u32; /// Opcode for the BadRegion error pub const BAD_REGION_ERROR: u8 = 0; #[derive(Clone, Copy, PartialEq, Eq)] pub struct RegionEnum(u8); impl RegionEnum { pub const NONE: Self = Self(0); } impl From for u8 { #[inline] fn from(input: RegionEnum) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: RegionEnum) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: RegionEnum) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: RegionEnum) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: RegionEnum) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: RegionEnum) -> Self { Some(u32::from(input.0)) } } impl From for RegionEnum { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for RegionEnum { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NONE.0.into(), "NONE", "None"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the CreateRegion request pub const CREATE_REGION_REQUEST: u8 = 5; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateRegionRequest<'input> { pub region: Region, pub rectangles: Cow<'input, [xproto::Rectangle]>, } impl<'input> CreateRegionRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_REGION_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let rectangles_bytes = self.rectangles.serialize(); let length_so_far = length_so_far + rectangles_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), rectangles_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut rectangles = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = xproto::Rectangle::try_parse(remaining)?; remaining = new_remaining; rectangles.push(v); } let _ = remaining; Ok(CreateRegionRequest { region, rectangles: Cow::Owned(rectangles), }) } /// Clone all borrowed data in this CreateRegionRequest. pub fn into_owned(self) -> CreateRegionRequest<'static> { CreateRegionRequest { region: self.region, rectangles: Cow::Owned(self.rectangles.into_owned()), } } } impl<'input> Request for CreateRegionRequest<'input> { type Reply = (); } pub fn create_region<'c, 'input, Conn>(conn: &'c Conn, region: Region, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRegionRequest { region, rectangles: Cow::Borrowed(rectangles), }; request0.send(conn) } /// Opcode for the CreateRegionFromBitmap request pub const CREATE_REGION_FROM_BITMAP_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateRegionFromBitmapRequest { pub region: Region, pub bitmap: xproto::Pixmap, } impl CreateRegionFromBitmapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let bitmap_bytes = self.bitmap.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_REGION_FROM_BITMAP_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], bitmap_bytes[0], bitmap_bytes[1], bitmap_bytes[2], bitmap_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_REGION_FROM_BITMAP_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let (bitmap, remaining) = xproto::Pixmap::try_parse(remaining)?; let _ = remaining; Ok(CreateRegionFromBitmapRequest { region, bitmap, }) } } impl Request for CreateRegionFromBitmapRequest { type Reply = (); } pub fn create_region_from_bitmap(conn: &Conn, region: Region, bitmap: xproto::Pixmap) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRegionFromBitmapRequest { region, bitmap, }; request0.send(conn) } /// Opcode for the CreateRegionFromWindow request pub const CREATE_REGION_FROM_WINDOW_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateRegionFromWindowRequest { pub region: Region, pub window: xproto::Window, pub kind: shape::SK, } impl CreateRegionFromWindowRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let window_bytes = self.window.serialize(); let kind_bytes = shape::Kind::from(self.kind).serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_REGION_FROM_WINDOW_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], kind_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_REGION_FROM_WINDOW_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (kind, remaining) = shape::Kind::try_parse(remaining)?; let kind = kind.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(CreateRegionFromWindowRequest { region, window, kind, }) } } impl Request for CreateRegionFromWindowRequest { type Reply = (); } pub fn create_region_from_window(conn: &Conn, region: Region, window: xproto::Window, kind: shape::SK) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRegionFromWindowRequest { region, window, kind, }; request0.send(conn) } /// Opcode for the CreateRegionFromGC request pub const CREATE_REGION_FROM_GC_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateRegionFromGCRequest { pub region: Region, pub gc: xproto::Gcontext, } impl CreateRegionFromGCRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let gc_bytes = self.gc.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_REGION_FROM_GC_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_REGION_FROM_GC_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let _ = remaining; Ok(CreateRegionFromGCRequest { region, gc, }) } } impl Request for CreateRegionFromGCRequest { type Reply = (); } pub fn create_region_from_gc(conn: &Conn, region: Region, gc: xproto::Gcontext) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRegionFromGCRequest { region, gc, }; request0.send(conn) } /// Opcode for the CreateRegionFromPicture request pub const CREATE_REGION_FROM_PICTURE_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateRegionFromPictureRequest { pub region: Region, pub picture: render::Picture, } impl CreateRegionFromPictureRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let picture_bytes = self.picture.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_REGION_FROM_PICTURE_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_REGION_FROM_PICTURE_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let (picture, remaining) = render::Picture::try_parse(remaining)?; let _ = remaining; Ok(CreateRegionFromPictureRequest { region, picture, }) } } impl Request for CreateRegionFromPictureRequest { type Reply = (); } pub fn create_region_from_picture(conn: &Conn, region: Region, picture: render::Picture) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateRegionFromPictureRequest { region, picture, }; request0.send(conn) } /// Opcode for the DestroyRegion request pub const DESTROY_REGION_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyRegionRequest { pub region: Region, } impl DestroyRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_REGION_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let _ = remaining; Ok(DestroyRegionRequest { region, }) } } impl Request for DestroyRegionRequest { type Reply = (); } pub fn destroy_region(conn: &Conn, region: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyRegionRequest { region, }; request0.send(conn) } /// Opcode for the SetRegion request pub const SET_REGION_REQUEST: u8 = 11; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetRegionRequest<'input> { pub region: Region, pub rectangles: Cow<'input, [xproto::Rectangle]>, } impl<'input> SetRegionRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_REGION_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let rectangles_bytes = self.rectangles.serialize(); let length_so_far = length_so_far + rectangles_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), rectangles_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let mut remaining = remaining; // Length is 'everything left in the input' let mut rectangles = Vec::new(); while !remaining.is_empty() { let (v, new_remaining) = xproto::Rectangle::try_parse(remaining)?; remaining = new_remaining; rectangles.push(v); } let _ = remaining; Ok(SetRegionRequest { region, rectangles: Cow::Owned(rectangles), }) } /// Clone all borrowed data in this SetRegionRequest. pub fn into_owned(self) -> SetRegionRequest<'static> { SetRegionRequest { region: self.region, rectangles: Cow::Owned(self.rectangles.into_owned()), } } } impl<'input> Request for SetRegionRequest<'input> { type Reply = (); } pub fn set_region<'c, 'input, Conn>(conn: &'c Conn, region: Region, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetRegionRequest { region, rectangles: Cow::Borrowed(rectangles), }; request0.send(conn) } /// Opcode for the CopyRegion request pub const COPY_REGION_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CopyRegionRequest { pub source: Region, pub destination: Region, } impl CopyRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source_bytes = self.source.serialize(); let destination_bytes = self.destination.serialize(); let mut request0 = vec![ extension_information.major_opcode, COPY_REGION_REQUEST, 0, 0, source_bytes[0], source_bytes[1], source_bytes[2], source_bytes[3], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != COPY_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (source, remaining) = Region::try_parse(value)?; let (destination, remaining) = Region::try_parse(remaining)?; let _ = remaining; Ok(CopyRegionRequest { source, destination, }) } } impl Request for CopyRegionRequest { type Reply = (); } pub fn copy_region(conn: &Conn, source: Region, destination: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CopyRegionRequest { source, destination, }; request0.send(conn) } /// Opcode for the UnionRegion request pub const UNION_REGION_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UnionRegionRequest { pub source1: Region, pub source2: Region, pub destination: Region, } impl UnionRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source1_bytes = self.source1.serialize(); let source2_bytes = self.source2.serialize(); let destination_bytes = self.destination.serialize(); let mut request0 = vec![ extension_information.major_opcode, UNION_REGION_REQUEST, 0, 0, source1_bytes[0], source1_bytes[1], source1_bytes[2], source1_bytes[3], source2_bytes[0], source2_bytes[1], source2_bytes[2], source2_bytes[3], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNION_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (source1, remaining) = Region::try_parse(value)?; let (source2, remaining) = Region::try_parse(remaining)?; let (destination, remaining) = Region::try_parse(remaining)?; let _ = remaining; Ok(UnionRegionRequest { source1, source2, destination, }) } } impl Request for UnionRegionRequest { type Reply = (); } pub fn union_region(conn: &Conn, source1: Region, source2: Region, destination: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = UnionRegionRequest { source1, source2, destination, }; request0.send(conn) } /// Opcode for the IntersectRegion request pub const INTERSECT_REGION_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IntersectRegionRequest { pub source1: Region, pub source2: Region, pub destination: Region, } impl IntersectRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source1_bytes = self.source1.serialize(); let source2_bytes = self.source2.serialize(); let destination_bytes = self.destination.serialize(); let mut request0 = vec![ extension_information.major_opcode, INTERSECT_REGION_REQUEST, 0, 0, source1_bytes[0], source1_bytes[1], source1_bytes[2], source1_bytes[3], source2_bytes[0], source2_bytes[1], source2_bytes[2], source2_bytes[3], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != INTERSECT_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (source1, remaining) = Region::try_parse(value)?; let (source2, remaining) = Region::try_parse(remaining)?; let (destination, remaining) = Region::try_parse(remaining)?; let _ = remaining; Ok(IntersectRegionRequest { source1, source2, destination, }) } } impl Request for IntersectRegionRequest { type Reply = (); } pub fn intersect_region(conn: &Conn, source1: Region, source2: Region, destination: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = IntersectRegionRequest { source1, source2, destination, }; request0.send(conn) } /// Opcode for the SubtractRegion request pub const SUBTRACT_REGION_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SubtractRegionRequest { pub source1: Region, pub source2: Region, pub destination: Region, } impl SubtractRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source1_bytes = self.source1.serialize(); let source2_bytes = self.source2.serialize(); let destination_bytes = self.destination.serialize(); let mut request0 = vec![ extension_information.major_opcode, SUBTRACT_REGION_REQUEST, 0, 0, source1_bytes[0], source1_bytes[1], source1_bytes[2], source1_bytes[3], source2_bytes[0], source2_bytes[1], source2_bytes[2], source2_bytes[3], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SUBTRACT_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (source1, remaining) = Region::try_parse(value)?; let (source2, remaining) = Region::try_parse(remaining)?; let (destination, remaining) = Region::try_parse(remaining)?; let _ = remaining; Ok(SubtractRegionRequest { source1, source2, destination, }) } } impl Request for SubtractRegionRequest { type Reply = (); } pub fn subtract_region(conn: &Conn, source1: Region, source2: Region, destination: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SubtractRegionRequest { source1, source2, destination, }; request0.send(conn) } /// Opcode for the InvertRegion request pub const INVERT_REGION_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InvertRegionRequest { pub source: Region, pub bounds: xproto::Rectangle, pub destination: Region, } impl InvertRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source_bytes = self.source.serialize(); let bounds_bytes = self.bounds.serialize(); let destination_bytes = self.destination.serialize(); let mut request0 = vec![ extension_information.major_opcode, INVERT_REGION_REQUEST, 0, 0, source_bytes[0], source_bytes[1], source_bytes[2], source_bytes[3], bounds_bytes[0], bounds_bytes[1], bounds_bytes[2], bounds_bytes[3], bounds_bytes[4], bounds_bytes[5], bounds_bytes[6], bounds_bytes[7], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != INVERT_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (source, remaining) = Region::try_parse(value)?; let (bounds, remaining) = xproto::Rectangle::try_parse(remaining)?; let (destination, remaining) = Region::try_parse(remaining)?; let _ = remaining; Ok(InvertRegionRequest { source, bounds, destination, }) } } impl Request for InvertRegionRequest { type Reply = (); } pub fn invert_region(conn: &Conn, source: Region, bounds: xproto::Rectangle, destination: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = InvertRegionRequest { source, bounds, destination, }; request0.send(conn) } /// Opcode for the TranslateRegion request pub const TRANSLATE_REGION_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct TranslateRegionRequest { pub region: Region, pub dx: i16, pub dy: i16, } impl TranslateRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let dx_bytes = self.dx.serialize(); let dy_bytes = self.dy.serialize(); let mut request0 = vec![ extension_information.major_opcode, TRANSLATE_REGION_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], dx_bytes[0], dx_bytes[1], dy_bytes[0], dy_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != TRANSLATE_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let (dx, remaining) = i16::try_parse(remaining)?; let (dy, remaining) = i16::try_parse(remaining)?; let _ = remaining; Ok(TranslateRegionRequest { region, dx, dy, }) } } impl Request for TranslateRegionRequest { type Reply = (); } pub fn translate_region(conn: &Conn, region: Region, dx: i16, dy: i16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = TranslateRegionRequest { region, dx, dy, }; request0.send(conn) } /// Opcode for the RegionExtents request pub const REGION_EXTENTS_REQUEST: u8 = 18; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct RegionExtentsRequest { pub source: Region, pub destination: Region, } impl RegionExtentsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source_bytes = self.source.serialize(); let destination_bytes = self.destination.serialize(); let mut request0 = vec![ extension_information.major_opcode, REGION_EXTENTS_REQUEST, 0, 0, source_bytes[0], source_bytes[1], source_bytes[2], source_bytes[3], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != REGION_EXTENTS_REQUEST { return Err(ParseError::InvalidValue); } let (source, remaining) = Region::try_parse(value)?; let (destination, remaining) = Region::try_parse(remaining)?; let _ = remaining; Ok(RegionExtentsRequest { source, destination, }) } } impl Request for RegionExtentsRequest { type Reply = (); } pub fn region_extents(conn: &Conn, source: Region, destination: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = RegionExtentsRequest { source, destination, }; request0.send(conn) } /// Opcode for the FetchRegion request pub const FETCH_REGION_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FetchRegionRequest { pub region: Region, } impl FetchRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let region_bytes = self.region.serialize(); let mut request0 = vec![ extension_information.major_opcode, FETCH_REGION_REQUEST, 0, 0, region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FETCH_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (region, remaining) = Region::try_parse(value)?; let _ = remaining; Ok(FetchRegionRequest { region, }) } } impl Request for FetchRegionRequest { type Reply = FetchRegionReply; } pub fn fetch_region(conn: &Conn, region: Region) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FetchRegionRequest { region, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FetchRegionReply { pub sequence: u16, pub extents: xproto::Rectangle, pub rectangles: Vec, } impl TryParse for FetchRegionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (extents, remaining) = xproto::Rectangle::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (rectangles, remaining) = crate::x11_utils::parse_list::(remaining, length.checked_div(2u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = FetchRegionReply { sequence, extents, rectangles }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl FetchRegionReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `rectangles` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.rectangles.len() .checked_mul(2).unwrap() .try_into().unwrap() } } /// Opcode for the SetGCClipRegion request pub const SET_GC_CLIP_REGION_REQUEST: u8 = 20; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetGCClipRegionRequest { pub gc: xproto::Gcontext, pub region: Region, pub x_origin: i16, pub y_origin: i16, } impl SetGCClipRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let gc_bytes = self.gc.serialize(); let region_bytes = self.region.serialize(); let x_origin_bytes = self.x_origin.serialize(); let y_origin_bytes = self.y_origin.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_GC_CLIP_REGION_REQUEST, 0, 0, gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], x_origin_bytes[0], x_origin_bytes[1], y_origin_bytes[0], y_origin_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_GC_CLIP_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (gc, remaining) = xproto::Gcontext::try_parse(value)?; let (region, remaining) = Region::try_parse(remaining)?; let (x_origin, remaining) = i16::try_parse(remaining)?; let (y_origin, remaining) = i16::try_parse(remaining)?; let _ = remaining; Ok(SetGCClipRegionRequest { gc, region, x_origin, y_origin, }) } } impl Request for SetGCClipRegionRequest { type Reply = (); } pub fn set_gc_clip_region(conn: &Conn, gc: xproto::Gcontext, region: A, x_origin: i16, y_origin: i16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let region: Region = region.into(); let request0 = SetGCClipRegionRequest { gc, region, x_origin, y_origin, }; request0.send(conn) } /// Opcode for the SetWindowShapeRegion request pub const SET_WINDOW_SHAPE_REGION_REQUEST: u8 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetWindowShapeRegionRequest { pub dest: xproto::Window, pub dest_kind: shape::SK, pub x_offset: i16, pub y_offset: i16, pub region: Region, } impl SetWindowShapeRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let dest_bytes = self.dest.serialize(); let dest_kind_bytes = shape::Kind::from(self.dest_kind).serialize(); let x_offset_bytes = self.x_offset.serialize(); let y_offset_bytes = self.y_offset.serialize(); let region_bytes = self.region.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_WINDOW_SHAPE_REGION_REQUEST, 0, 0, dest_bytes[0], dest_bytes[1], dest_bytes[2], dest_bytes[3], dest_kind_bytes[0], 0, 0, 0, x_offset_bytes[0], x_offset_bytes[1], y_offset_bytes[0], y_offset_bytes[1], region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_WINDOW_SHAPE_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (dest, remaining) = xproto::Window::try_parse(value)?; let (dest_kind, remaining) = shape::Kind::try_parse(remaining)?; let dest_kind = dest_kind.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (x_offset, remaining) = i16::try_parse(remaining)?; let (y_offset, remaining) = i16::try_parse(remaining)?; let (region, remaining) = Region::try_parse(remaining)?; let _ = remaining; Ok(SetWindowShapeRegionRequest { dest, dest_kind, x_offset, y_offset, region, }) } } impl Request for SetWindowShapeRegionRequest { type Reply = (); } pub fn set_window_shape_region(conn: &Conn, dest: xproto::Window, dest_kind: shape::SK, x_offset: i16, y_offset: i16, region: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let region: Region = region.into(); let request0 = SetWindowShapeRegionRequest { dest, dest_kind, x_offset, y_offset, region, }; request0.send(conn) } /// Opcode for the SetPictureClipRegion request pub const SET_PICTURE_CLIP_REGION_REQUEST: u8 = 22; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetPictureClipRegionRequest { pub picture: render::Picture, pub region: Region, pub x_origin: i16, pub y_origin: i16, } impl SetPictureClipRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let picture_bytes = self.picture.serialize(); let region_bytes = self.region.serialize(); let x_origin_bytes = self.x_origin.serialize(); let y_origin_bytes = self.y_origin.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PICTURE_CLIP_REGION_REQUEST, 0, 0, picture_bytes[0], picture_bytes[1], picture_bytes[2], picture_bytes[3], region_bytes[0], region_bytes[1], region_bytes[2], region_bytes[3], x_origin_bytes[0], x_origin_bytes[1], y_origin_bytes[0], y_origin_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_PICTURE_CLIP_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (picture, remaining) = render::Picture::try_parse(value)?; let (region, remaining) = Region::try_parse(remaining)?; let (x_origin, remaining) = i16::try_parse(remaining)?; let (y_origin, remaining) = i16::try_parse(remaining)?; let _ = remaining; Ok(SetPictureClipRegionRequest { picture, region, x_origin, y_origin, }) } } impl Request for SetPictureClipRegionRequest { type Reply = (); } pub fn set_picture_clip_region(conn: &Conn, picture: render::Picture, region: A, x_origin: i16, y_origin: i16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let region: Region = region.into(); let request0 = SetPictureClipRegionRequest { picture, region, x_origin, y_origin, }; request0.send(conn) } /// Opcode for the SetCursorName request pub const SET_CURSOR_NAME_REQUEST: u8 = 23; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetCursorNameRequest<'input> { pub cursor: xproto::Cursor, pub name: Cow<'input, [u8]>, } impl<'input> SetCursorNameRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cursor_bytes = self.cursor.serialize(); let nbytes = u16::try_from(self.name.len()).expect("`name` has too many elements"); let nbytes_bytes = nbytes.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CURSOR_NAME_REQUEST, 0, 0, cursor_bytes[0], cursor_bytes[1], cursor_bytes[2], cursor_bytes[3], nbytes_bytes[0], nbytes_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.name.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.name, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_CURSOR_NAME_REQUEST { return Err(ParseError::InvalidValue); } let (cursor, remaining) = xproto::Cursor::try_parse(value)?; let (nbytes, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, nbytes.try_to_usize()?)?; let _ = remaining; Ok(SetCursorNameRequest { cursor, name: Cow::Borrowed(name), }) } /// Clone all borrowed data in this SetCursorNameRequest. pub fn into_owned(self) -> SetCursorNameRequest<'static> { SetCursorNameRequest { cursor: self.cursor, name: Cow::Owned(self.name.into_owned()), } } } impl<'input> Request for SetCursorNameRequest<'input> { type Reply = (); } pub fn set_cursor_name<'c, 'input, Conn>(conn: &'c Conn, cursor: xproto::Cursor, name: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetCursorNameRequest { cursor, name: Cow::Borrowed(name), }; request0.send(conn) } /// Opcode for the GetCursorName request pub const GET_CURSOR_NAME_REQUEST: u8 = 24; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCursorNameRequest { pub cursor: xproto::Cursor, } impl GetCursorNameRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cursor_bytes = self.cursor.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CURSOR_NAME_REQUEST, 0, 0, cursor_bytes[0], cursor_bytes[1], cursor_bytes[2], cursor_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CURSOR_NAME_REQUEST { return Err(ParseError::InvalidValue); } let (cursor, remaining) = xproto::Cursor::try_parse(value)?; let _ = remaining; Ok(GetCursorNameRequest { cursor, }) } } impl Request for GetCursorNameRequest { type Reply = GetCursorNameReply; } pub fn get_cursor_name(conn: &Conn, cursor: xproto::Cursor) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCursorNameRequest { cursor, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCursorNameReply { pub sequence: u16, pub length: u32, pub atom: xproto::Atom, pub name: Vec, } impl TryParse for GetCursorNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (atom, remaining) = xproto::Atom::try_parse(remaining)?; let (nbytes, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(18..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, nbytes.try_to_usize()?)?; let name = name.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCursorNameReply { sequence, length, atom, name }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetCursorNameReply { /// Get the value of the `nbytes` field. /// /// The `nbytes` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn nbytes(&self) -> u16 { self.name.len() .try_into().unwrap() } } /// Opcode for the GetCursorImageAndName request pub const GET_CURSOR_IMAGE_AND_NAME_REQUEST: u8 = 25; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCursorImageAndNameRequest; impl GetCursorImageAndNameRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_CURSOR_IMAGE_AND_NAME_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CURSOR_IMAGE_AND_NAME_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetCursorImageAndNameRequest ) } } impl Request for GetCursorImageAndNameRequest { type Reply = GetCursorImageAndNameReply; } pub fn get_cursor_image_and_name(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetCursorImageAndNameRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCursorImageAndNameReply { pub sequence: u16, pub length: u32, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub xhot: u16, pub yhot: u16, pub cursor_serial: u32, pub cursor_atom: xproto::Atom, pub cursor_image: Vec, pub name: Vec, } impl TryParse for GetCursorImageAndNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (xhot, remaining) = u16::try_parse(remaining)?; let (yhot, remaining) = u16::try_parse(remaining)?; let (cursor_serial, remaining) = u32::try_parse(remaining)?; let (cursor_atom, remaining) = xproto::Atom::try_parse(remaining)?; let (nbytes, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (cursor_image, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(width).checked_mul(u32::from(height)).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, nbytes.try_to_usize()?)?; let name = name.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCursorImageAndNameReply { sequence, length, x, y, width, height, xhot, yhot, cursor_serial, cursor_atom, cursor_image, name }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetCursorImageAndNameReply { /// Get the value of the `nbytes` field. /// /// The `nbytes` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn nbytes(&self) -> u16 { self.name.len() .try_into().unwrap() } } /// Opcode for the ChangeCursor request pub const CHANGE_CURSOR_REQUEST: u8 = 26; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangeCursorRequest { pub source: xproto::Cursor, pub destination: xproto::Cursor, } impl ChangeCursorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source_bytes = self.source.serialize(); let destination_bytes = self.destination.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_CURSOR_REQUEST, 0, 0, source_bytes[0], source_bytes[1], source_bytes[2], source_bytes[3], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CHANGE_CURSOR_REQUEST { return Err(ParseError::InvalidValue); } let (source, remaining) = xproto::Cursor::try_parse(value)?; let (destination, remaining) = xproto::Cursor::try_parse(remaining)?; let _ = remaining; Ok(ChangeCursorRequest { source, destination, }) } } impl Request for ChangeCursorRequest { type Reply = (); } pub fn change_cursor(conn: &Conn, source: xproto::Cursor, destination: xproto::Cursor) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeCursorRequest { source, destination, }; request0.send(conn) } /// Opcode for the ChangeCursorByName request pub const CHANGE_CURSOR_BY_NAME_REQUEST: u8 = 27; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeCursorByNameRequest<'input> { pub src: xproto::Cursor, pub name: Cow<'input, [u8]>, } impl<'input> ChangeCursorByNameRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let src_bytes = self.src.serialize(); let nbytes = u16::try_from(self.name.len()).expect("`name` has too many elements"); let nbytes_bytes = nbytes.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_CURSOR_BY_NAME_REQUEST, 0, 0, src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3], nbytes_bytes[0], nbytes_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.name.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.name, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_CURSOR_BY_NAME_REQUEST { return Err(ParseError::InvalidValue); } let (src, remaining) = xproto::Cursor::try_parse(value)?; let (nbytes, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, nbytes.try_to_usize()?)?; let _ = remaining; Ok(ChangeCursorByNameRequest { src, name: Cow::Borrowed(name), }) } /// Clone all borrowed data in this ChangeCursorByNameRequest. pub fn into_owned(self) -> ChangeCursorByNameRequest<'static> { ChangeCursorByNameRequest { src: self.src, name: Cow::Owned(self.name.into_owned()), } } } impl<'input> Request for ChangeCursorByNameRequest<'input> { type Reply = (); } pub fn change_cursor_by_name<'c, 'input, Conn>(conn: &'c Conn, src: xproto::Cursor, name: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeCursorByNameRequest { src, name: Cow::Borrowed(name), }; request0.send(conn) } /// Opcode for the ExpandRegion request pub const EXPAND_REGION_REQUEST: u8 = 28; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ExpandRegionRequest { pub source: Region, pub destination: Region, pub left: u16, pub right: u16, pub top: u16, pub bottom: u16, } impl ExpandRegionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let source_bytes = self.source.serialize(); let destination_bytes = self.destination.serialize(); let left_bytes = self.left.serialize(); let right_bytes = self.right.serialize(); let top_bytes = self.top.serialize(); let bottom_bytes = self.bottom.serialize(); let mut request0 = vec![ extension_information.major_opcode, EXPAND_REGION_REQUEST, 0, 0, source_bytes[0], source_bytes[1], source_bytes[2], source_bytes[3], destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], left_bytes[0], left_bytes[1], right_bytes[0], right_bytes[1], top_bytes[0], top_bytes[1], bottom_bytes[0], bottom_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != EXPAND_REGION_REQUEST { return Err(ParseError::InvalidValue); } let (source, remaining) = Region::try_parse(value)?; let (destination, remaining) = Region::try_parse(remaining)?; let (left, remaining) = u16::try_parse(remaining)?; let (right, remaining) = u16::try_parse(remaining)?; let (top, remaining) = u16::try_parse(remaining)?; let (bottom, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(ExpandRegionRequest { source, destination, left, right, top, bottom, }) } } impl Request for ExpandRegionRequest { type Reply = (); } pub fn expand_region(conn: &Conn, source: Region, destination: Region, left: u16, right: u16, top: u16, bottom: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ExpandRegionRequest { source, destination, left, right, top, bottom, }; request0.send(conn) } /// Opcode for the HideCursor request pub const HIDE_CURSOR_REQUEST: u8 = 29; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct HideCursorRequest { pub window: xproto::Window, } impl HideCursorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, HIDE_CURSOR_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != HIDE_CURSOR_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(HideCursorRequest { window, }) } } impl Request for HideCursorRequest { type Reply = (); } pub fn hide_cursor(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = HideCursorRequest { window, }; request0.send(conn) } /// Opcode for the ShowCursor request pub const SHOW_CURSOR_REQUEST: u8 = 30; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ShowCursorRequest { pub window: xproto::Window, } impl ShowCursorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, SHOW_CURSOR_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SHOW_CURSOR_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(ShowCursorRequest { window, }) } } impl Request for ShowCursorRequest { type Reply = (); } pub fn show_cursor(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ShowCursorRequest { window, }; request0.send(conn) } pub type Barrier = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct BarrierDirections(u8); impl BarrierDirections { pub const POSITIVE_X: Self = Self(1 << 0); pub const POSITIVE_Y: Self = Self(1 << 1); pub const NEGATIVE_X: Self = Self(1 << 2); pub const NEGATIVE_Y: Self = Self(1 << 3); } impl From for u8 { #[inline] fn from(input: BarrierDirections) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BarrierDirections) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: BarrierDirections) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: BarrierDirections) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: BarrierDirections) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BarrierDirections) -> Self { Some(u32::from(input.0)) } } impl From for BarrierDirections { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for BarrierDirections { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::POSITIVE_X.0.into(), "POSITIVE_X", "PositiveX"), (Self::POSITIVE_Y.0.into(), "POSITIVE_Y", "PositiveY"), (Self::NEGATIVE_X.0.into(), "NEGATIVE_X", "NegativeX"), (Self::NEGATIVE_Y.0.into(), "NEGATIVE_Y", "NegativeY"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(BarrierDirections, u8); /// Opcode for the CreatePointerBarrier request pub const CREATE_POINTER_BARRIER_REQUEST: u8 = 31; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreatePointerBarrierRequest<'input> { pub barrier: Barrier, pub window: xproto::Window, pub x1: u16, pub y1: u16, pub x2: u16, pub y2: u16, pub directions: u32, pub devices: Cow<'input, [u16]>, } impl<'input> CreatePointerBarrierRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let barrier_bytes = self.barrier.serialize(); let window_bytes = self.window.serialize(); let x1_bytes = self.x1.serialize(); let y1_bytes = self.y1.serialize(); let x2_bytes = self.x2.serialize(); let y2_bytes = self.y2.serialize(); let directions_bytes = self.directions.serialize(); let num_devices = u16::try_from(self.devices.len()).expect("`devices` has too many elements"); let num_devices_bytes = num_devices.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_POINTER_BARRIER_REQUEST, 0, 0, barrier_bytes[0], barrier_bytes[1], barrier_bytes[2], barrier_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], x1_bytes[0], x1_bytes[1], y1_bytes[0], y1_bytes[1], x2_bytes[0], x2_bytes[1], y2_bytes[0], y2_bytes[1], directions_bytes[0], directions_bytes[1], directions_bytes[2], directions_bytes[3], 0, 0, num_devices_bytes[0], num_devices_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let devices_bytes = self.devices.serialize(); let length_so_far = length_so_far + devices_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), devices_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_POINTER_BARRIER_REQUEST { return Err(ParseError::InvalidValue); } let (barrier, remaining) = Barrier::try_parse(value)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (x1, remaining) = u16::try_parse(remaining)?; let (y1, remaining) = u16::try_parse(remaining)?; let (x2, remaining) = u16::try_parse(remaining)?; let (y2, remaining) = u16::try_parse(remaining)?; let (directions, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (num_devices, remaining) = u16::try_parse(remaining)?; let (devices, remaining) = crate::x11_utils::parse_list::(remaining, num_devices.try_to_usize()?)?; let _ = remaining; Ok(CreatePointerBarrierRequest { barrier, window, x1, y1, x2, y2, directions, devices: Cow::Owned(devices), }) } /// Clone all borrowed data in this CreatePointerBarrierRequest. pub fn into_owned(self) -> CreatePointerBarrierRequest<'static> { CreatePointerBarrierRequest { barrier: self.barrier, window: self.window, x1: self.x1, y1: self.y1, x2: self.x2, y2: self.y2, directions: self.directions, devices: Cow::Owned(self.devices.into_owned()), } } } impl<'input> Request for CreatePointerBarrierRequest<'input> { type Reply = (); } pub fn create_pointer_barrier<'c, 'input, Conn, A>(conn: &'c Conn, barrier: Barrier, window: xproto::Window, x1: u16, y1: u16, x2: u16, y2: u16, directions: A, devices: &'input [u16]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let directions: u32 = directions.into(); let request0 = CreatePointerBarrierRequest { barrier, window, x1, y1, x2, y2, directions, devices: Cow::Borrowed(devices), }; request0.send(conn) } /// Opcode for the DeletePointerBarrier request pub const DELETE_POINTER_BARRIER_REQUEST: u8 = 32; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeletePointerBarrierRequest { pub barrier: Barrier, } impl DeletePointerBarrierRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let barrier_bytes = self.barrier.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_POINTER_BARRIER_REQUEST, 0, 0, barrier_bytes[0], barrier_bytes[1], barrier_bytes[2], barrier_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_POINTER_BARRIER_REQUEST { return Err(ParseError::InvalidValue); } let (barrier, remaining) = Barrier::try_parse(value)?; let _ = remaining; Ok(DeletePointerBarrierRequest { barrier, }) } } impl Request for DeletePointerBarrierRequest { type Reply = (); } pub fn delete_pointer_barrier(conn: &Conn, barrier: Barrier) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeletePointerBarrierRequest { barrier, }; request0.send(conn) } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xfixes_query_version(&self, client_major_version: u32, client_minor_version: u32) -> Result, ConnectionError> { query_version(self, client_major_version, client_minor_version) } fn xfixes_change_save_set(&self, mode: SaveSetMode, target: SaveSetTarget, map: SaveSetMapping, window: xproto::Window) -> Result, ConnectionError> { change_save_set(self, mode, target, map, window) } fn xfixes_select_selection_input(&self, window: xproto::Window, selection: xproto::Atom, event_mask: A) -> Result, ConnectionError> where A: Into, { select_selection_input(self, window, selection, event_mask) } fn xfixes_select_cursor_input(&self, window: xproto::Window, event_mask: A) -> Result, ConnectionError> where A: Into, { select_cursor_input(self, window, event_mask) } fn xfixes_get_cursor_image(&self) -> Result, ConnectionError> { get_cursor_image(self) } fn xfixes_create_region<'c, 'input>(&'c self, region: Region, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> { create_region(self, region, rectangles) } fn xfixes_create_region_from_bitmap(&self, region: Region, bitmap: xproto::Pixmap) -> Result, ConnectionError> { create_region_from_bitmap(self, region, bitmap) } fn xfixes_create_region_from_window(&self, region: Region, window: xproto::Window, kind: shape::SK) -> Result, ConnectionError> { create_region_from_window(self, region, window, kind) } fn xfixes_create_region_from_gc(&self, region: Region, gc: xproto::Gcontext) -> Result, ConnectionError> { create_region_from_gc(self, region, gc) } fn xfixes_create_region_from_picture(&self, region: Region, picture: render::Picture) -> Result, ConnectionError> { create_region_from_picture(self, region, picture) } fn xfixes_destroy_region(&self, region: Region) -> Result, ConnectionError> { destroy_region(self, region) } fn xfixes_set_region<'c, 'input>(&'c self, region: Region, rectangles: &'input [xproto::Rectangle]) -> Result, ConnectionError> { set_region(self, region, rectangles) } fn xfixes_copy_region(&self, source: Region, destination: Region) -> Result, ConnectionError> { copy_region(self, source, destination) } fn xfixes_union_region(&self, source1: Region, source2: Region, destination: Region) -> Result, ConnectionError> { union_region(self, source1, source2, destination) } fn xfixes_intersect_region(&self, source1: Region, source2: Region, destination: Region) -> Result, ConnectionError> { intersect_region(self, source1, source2, destination) } fn xfixes_subtract_region(&self, source1: Region, source2: Region, destination: Region) -> Result, ConnectionError> { subtract_region(self, source1, source2, destination) } fn xfixes_invert_region(&self, source: Region, bounds: xproto::Rectangle, destination: Region) -> Result, ConnectionError> { invert_region(self, source, bounds, destination) } fn xfixes_translate_region(&self, region: Region, dx: i16, dy: i16) -> Result, ConnectionError> { translate_region(self, region, dx, dy) } fn xfixes_region_extents(&self, source: Region, destination: Region) -> Result, ConnectionError> { region_extents(self, source, destination) } fn xfixes_fetch_region(&self, region: Region) -> Result, ConnectionError> { fetch_region(self, region) } fn xfixes_set_gc_clip_region(&self, gc: xproto::Gcontext, region: A, x_origin: i16, y_origin: i16) -> Result, ConnectionError> where A: Into, { set_gc_clip_region(self, gc, region, x_origin, y_origin) } fn xfixes_set_window_shape_region(&self, dest: xproto::Window, dest_kind: shape::SK, x_offset: i16, y_offset: i16, region: A) -> Result, ConnectionError> where A: Into, { set_window_shape_region(self, dest, dest_kind, x_offset, y_offset, region) } fn xfixes_set_picture_clip_region(&self, picture: render::Picture, region: A, x_origin: i16, y_origin: i16) -> Result, ConnectionError> where A: Into, { set_picture_clip_region(self, picture, region, x_origin, y_origin) } fn xfixes_set_cursor_name<'c, 'input>(&'c self, cursor: xproto::Cursor, name: &'input [u8]) -> Result, ConnectionError> { set_cursor_name(self, cursor, name) } fn xfixes_get_cursor_name(&self, cursor: xproto::Cursor) -> Result, ConnectionError> { get_cursor_name(self, cursor) } fn xfixes_get_cursor_image_and_name(&self) -> Result, ConnectionError> { get_cursor_image_and_name(self) } fn xfixes_change_cursor(&self, source: xproto::Cursor, destination: xproto::Cursor) -> Result, ConnectionError> { change_cursor(self, source, destination) } fn xfixes_change_cursor_by_name<'c, 'input>(&'c self, src: xproto::Cursor, name: &'input [u8]) -> Result, ConnectionError> { change_cursor_by_name(self, src, name) } fn xfixes_expand_region(&self, source: Region, destination: Region, left: u16, right: u16, top: u16, bottom: u16) -> Result, ConnectionError> { expand_region(self, source, destination, left, right, top, bottom) } fn xfixes_hide_cursor(&self, window: xproto::Window) -> Result, ConnectionError> { hide_cursor(self, window) } fn xfixes_show_cursor(&self, window: xproto::Window) -> Result, ConnectionError> { show_cursor(self, window) } fn xfixes_create_pointer_barrier<'c, 'input, A>(&'c self, barrier: Barrier, window: xproto::Window, x1: u16, y1: u16, x2: u16, y2: u16, directions: A, devices: &'input [u16]) -> Result, ConnectionError> where A: Into, { create_pointer_barrier(self, barrier, window, x1, y1, x2, y2, directions, devices) } fn xfixes_delete_pointer_barrier(&self, barrier: Barrier) -> Result, ConnectionError> { delete_pointer_barrier(self, barrier) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xinerama.rs010064400017500001750000000607621402220031600154410ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Xinerama` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XINERAMA"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 1); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ScreenInfo { pub x_org: i16, pub y_org: i16, pub width: u16, pub height: u16, } impl TryParse for ScreenInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (x_org, remaining) = i16::try_parse(remaining)?; let (y_org, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let result = ScreenInfo { x_org, y_org, width, height }; Ok((result, remaining)) } } impl Serialize for ScreenInfo { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let x_org_bytes = self.x_org.serialize(); let y_org_bytes = self.y_org.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); [ x_org_bytes[0], x_org_bytes[1], y_org_bytes[0], y_org_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.x_org.serialize_into(bytes); self.y_org.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub major: u8, pub minor: u8, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_bytes = self.major.serialize(); let minor_bytes = self.minor.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, major_bytes[0], minor_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major, remaining) = u8::try_parse(value)?; let (minor, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { major, minor, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, major: u8, minor: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { major, minor, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major: u16, pub minor: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major, remaining) = u16::try_parse(remaining)?; let (minor, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major, minor }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetState request pub const GET_STATE_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetStateRequest { pub window: xproto::Window, } impl GetStateRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_STATE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_STATE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetStateRequest { window, }) } } impl Request for GetStateRequest { type Reply = GetStateReply; } pub fn get_state(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetStateRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetStateReply { pub state: u8, pub sequence: u16, pub length: u32, pub window: xproto::Window, } impl TryParse for GetStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetStateReply { state, sequence, length, window }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetScreenCount request pub const GET_SCREEN_COUNT_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenCountRequest { pub window: xproto::Window, } impl GetScreenCountRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SCREEN_COUNT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SCREEN_COUNT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetScreenCountRequest { window, }) } } impl Request for GetScreenCountRequest { type Reply = GetScreenCountReply; } pub fn get_screen_count(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetScreenCountRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenCountReply { pub screen_count: u8, pub sequence: u16, pub length: u32, pub window: xproto::Window, } impl TryParse for GetScreenCountReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (screen_count, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetScreenCountReply { screen_count, sequence, length, window }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetScreenSize request pub const GET_SCREEN_SIZE_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenSizeRequest { pub window: xproto::Window, pub screen: u32, } impl GetScreenSizeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let screen_bytes = self.screen.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SCREEN_SIZE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SCREEN_SIZE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (screen, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetScreenSizeRequest { window, screen, }) } } impl Request for GetScreenSizeRequest { type Reply = GetScreenSizeReply; } pub fn get_screen_size(conn: &Conn, window: xproto::Window, screen: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetScreenSizeRequest { window, screen, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetScreenSizeReply { pub sequence: u16, pub length: u32, pub width: u32, pub height: u32, pub window: xproto::Window, pub screen: u32, } impl TryParse for GetScreenSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u32::try_parse(remaining)?; let (height, remaining) = u32::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (screen, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetScreenSizeReply { sequence, length, width, height, window, screen }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the IsActive request pub const IS_ACTIVE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsActiveRequest; impl IsActiveRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, IS_ACTIVE_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != IS_ACTIVE_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(IsActiveRequest ) } } impl Request for IsActiveRequest { type Reply = IsActiveReply; } pub fn is_active(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = IsActiveRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IsActiveReply { pub sequence: u16, pub length: u32, pub state: u32, } impl TryParse for IsActiveReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (state, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = IsActiveReply { sequence, length, state }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryScreens request pub const QUERY_SCREENS_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryScreensRequest; impl QueryScreensRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_SCREENS_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_SCREENS_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryScreensRequest ) } } impl Request for QueryScreensRequest { type Reply = QueryScreensReply; } pub fn query_screens(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryScreensRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryScreensReply { pub sequence: u16, pub length: u32, pub screen_info: Vec, } impl TryParse for QueryScreensReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (number, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (screen_info, remaining) = crate::x11_utils::parse_list::(remaining, number.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryScreensReply { sequence, length, screen_info }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryScreensReply { /// Get the value of the `number` field. /// /// The `number` field is used as the length field of the `screen_info` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn number(&self) -> u32 { self.screen_info.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xinerama_query_version(&self, major: u8, minor: u8) -> Result, ConnectionError> { query_version(self, major, minor) } fn xinerama_get_state(&self, window: xproto::Window) -> Result, ConnectionError> { get_state(self, window) } fn xinerama_get_screen_count(&self, window: xproto::Window) -> Result, ConnectionError> { get_screen_count(self, window) } fn xinerama_get_screen_size(&self, window: xproto::Window, screen: u32) -> Result, ConnectionError> { get_screen_size(self, window, screen) } fn xinerama_is_active(&self) -> Result, ConnectionError> { is_active(self) } fn xinerama_query_screens(&self) -> Result, ConnectionError> { query_screens(self) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xinput.rs010064400017500001750000024151461402220031600151660ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Input` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xfixes; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XInputExtension"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (2, 3); pub type EventClass = u32; pub type KeyCode = u8; pub type DeviceId = u16; pub type Fp1616 = i32; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Fp3232 { pub integral: i32, pub frac: u32, } impl TryParse for Fp3232 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (integral, remaining) = i32::try_parse(remaining)?; let (frac, remaining) = u32::try_parse(remaining)?; let result = Fp3232 { integral, frac }; Ok((result, remaining)) } } impl Serialize for Fp3232 { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let integral_bytes = self.integral.serialize(); let frac_bytes = self.frac.serialize(); [ integral_bytes[0], integral_bytes[1], integral_bytes[2], integral_bytes[3], frac_bytes[0], frac_bytes[1], frac_bytes[2], frac_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.integral.serialize_into(bytes); self.frac.serialize_into(bytes); } } /// Opcode for the GetExtensionVersion request pub const GET_EXTENSION_VERSION_REQUEST: u8 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetExtensionVersionRequest<'input> { pub name: Cow<'input, [u8]>, } impl<'input> GetExtensionVersionRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let name_len = u16::try_from(self.name.len()).expect("`name` has too many elements"); let name_len_bytes = name_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_EXTENSION_VERSION_REQUEST, 0, 0, name_len_bytes[0], name_len_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.name.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.name, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != GET_EXTENSION_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (name_len, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let _ = remaining; Ok(GetExtensionVersionRequest { name: Cow::Borrowed(name), }) } /// Clone all borrowed data in this GetExtensionVersionRequest. pub fn into_owned(self) -> GetExtensionVersionRequest<'static> { GetExtensionVersionRequest { name: Cow::Owned(self.name.into_owned()), } } } impl<'input> Request for GetExtensionVersionRequest<'input> { type Reply = GetExtensionVersionReply; } pub fn get_extension_version<'c, 'input, Conn>(conn: &'c Conn, name: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetExtensionVersionRequest { name: Cow::Borrowed(name), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetExtensionVersionReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub server_major: u16, pub server_minor: u16, pub present: bool, } impl TryParse for GetExtensionVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major, remaining) = u16::try_parse(remaining)?; let (server_minor, remaining) = u16::try_parse(remaining)?; let (present, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(19..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetExtensionVersionReply { xi_reply_type, sequence, length, server_major, server_minor, present }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DeviceUse(u8); impl DeviceUse { pub const IS_X_POINTER: Self = Self(0); pub const IS_X_KEYBOARD: Self = Self(1); pub const IS_X_EXTENSION_DEVICE: Self = Self(2); pub const IS_X_EXTENSION_KEYBOARD: Self = Self(3); pub const IS_X_EXTENSION_POINTER: Self = Self(4); } impl From for u8 { #[inline] fn from(input: DeviceUse) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DeviceUse) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: DeviceUse) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceUse) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: DeviceUse) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceUse) -> Self { Some(u32::from(input.0)) } } impl From for DeviceUse { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for DeviceUse { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::IS_X_POINTER.0.into(), "IS_X_POINTER", "IsXPointer"), (Self::IS_X_KEYBOARD.0.into(), "IS_X_KEYBOARD", "IsXKeyboard"), (Self::IS_X_EXTENSION_DEVICE.0.into(), "IS_X_EXTENSION_DEVICE", "IsXExtensionDevice"), (Self::IS_X_EXTENSION_KEYBOARD.0.into(), "IS_X_EXTENSION_KEYBOARD", "IsXExtensionKeyboard"), (Self::IS_X_EXTENSION_POINTER.0.into(), "IS_X_EXTENSION_POINTER", "IsXExtensionPointer"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct InputClass(u8); impl InputClass { pub const KEY: Self = Self(0); pub const BUTTON: Self = Self(1); pub const VALUATOR: Self = Self(2); pub const FEEDBACK: Self = Self(3); pub const PROXIMITY: Self = Self(4); pub const FOCUS: Self = Self(5); pub const OTHER: Self = Self(6); } impl From for u8 { #[inline] fn from(input: InputClass) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: InputClass) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: InputClass) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: InputClass) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: InputClass) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: InputClass) -> Self { Some(u32::from(input.0)) } } impl From for InputClass { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for InputClass { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEY.0.into(), "KEY", "Key"), (Self::BUTTON.0.into(), "BUTTON", "Button"), (Self::VALUATOR.0.into(), "VALUATOR", "Valuator"), (Self::FEEDBACK.0.into(), "FEEDBACK", "Feedback"), (Self::PROXIMITY.0.into(), "PROXIMITY", "Proximity"), (Self::FOCUS.0.into(), "FOCUS", "Focus"), (Self::OTHER.0.into(), "OTHER", "Other"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ValuatorMode(u8); impl ValuatorMode { pub const RELATIVE: Self = Self(0); pub const ABSOLUTE: Self = Self(1); } impl From for u8 { #[inline] fn from(input: ValuatorMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ValuatorMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ValuatorMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ValuatorMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ValuatorMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ValuatorMode) -> Self { Some(u32::from(input.0)) } } impl From for ValuatorMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ValuatorMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::RELATIVE.0.into(), "RELATIVE", "Relative"), (Self::ABSOLUTE.0.into(), "ABSOLUTE", "Absolute"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceInfo { pub device_type: xproto::Atom, pub device_id: u8, pub num_class_info: u8, pub device_use: DeviceUse, } impl TryParse for DeviceInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (device_type, remaining) = xproto::Atom::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (num_class_info, remaining) = u8::try_parse(remaining)?; let (device_use, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let device_use = device_use.into(); let result = DeviceInfo { device_type, device_id, num_class_info, device_use }; Ok((result, remaining)) } } impl Serialize for DeviceInfo { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let device_type_bytes = self.device_type.serialize(); let device_id_bytes = self.device_id.serialize(); let num_class_info_bytes = self.num_class_info.serialize(); let device_use_bytes = u8::from(self.device_use).serialize(); [ device_type_bytes[0], device_type_bytes[1], device_type_bytes[2], device_type_bytes[3], device_id_bytes[0], num_class_info_bytes[0], device_use_bytes[0], 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.device_type.serialize_into(bytes); self.device_id.serialize_into(bytes); self.num_class_info.serialize_into(bytes); u8::from(self.device_use).serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyInfo { pub class_id: InputClass, pub len: u8, pub min_keycode: KeyCode, pub max_keycode: KeyCode, pub num_keys: u16, } impl TryParse for KeyInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (min_keycode, remaining) = KeyCode::try_parse(remaining)?; let (max_keycode, remaining) = KeyCode::try_parse(remaining)?; let (num_keys, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let class_id = class_id.into(); let result = KeyInfo { class_id, len, min_keycode, max_keycode, num_keys }; Ok((result, remaining)) } } impl Serialize for KeyInfo { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let class_id_bytes = u8::from(self.class_id).serialize(); let len_bytes = self.len.serialize(); let min_keycode_bytes = self.min_keycode.serialize(); let max_keycode_bytes = self.max_keycode.serialize(); let num_keys_bytes = self.num_keys.serialize(); [ class_id_bytes[0], len_bytes[0], min_keycode_bytes[0], max_keycode_bytes[0], num_keys_bytes[0], num_keys_bytes[1], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.class_id).serialize_into(bytes); self.len.serialize_into(bytes); self.min_keycode.serialize_into(bytes); self.max_keycode.serialize_into(bytes); self.num_keys.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ButtonInfo { pub class_id: InputClass, pub len: u8, pub num_buttons: u16, } impl TryParse for ButtonInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_buttons, remaining) = u16::try_parse(remaining)?; let class_id = class_id.into(); let result = ButtonInfo { class_id, len, num_buttons }; Ok((result, remaining)) } } impl Serialize for ButtonInfo { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let class_id_bytes = u8::from(self.class_id).serialize(); let len_bytes = self.len.serialize(); let num_buttons_bytes = self.num_buttons.serialize(); [ class_id_bytes[0], len_bytes[0], num_buttons_bytes[0], num_buttons_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); u8::from(self.class_id).serialize_into(bytes); self.len.serialize_into(bytes); self.num_buttons.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AxisInfo { pub resolution: u32, pub minimum: i32, pub maximum: i32, } impl TryParse for AxisInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (resolution, remaining) = u32::try_parse(remaining)?; let (minimum, remaining) = i32::try_parse(remaining)?; let (maximum, remaining) = i32::try_parse(remaining)?; let result = AxisInfo { resolution, minimum, maximum }; Ok((result, remaining)) } } impl Serialize for AxisInfo { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let resolution_bytes = self.resolution.serialize(); let minimum_bytes = self.minimum.serialize(); let maximum_bytes = self.maximum.serialize(); [ resolution_bytes[0], resolution_bytes[1], resolution_bytes[2], resolution_bytes[3], minimum_bytes[0], minimum_bytes[1], minimum_bytes[2], minimum_bytes[3], maximum_bytes[0], maximum_bytes[1], maximum_bytes[2], maximum_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.resolution.serialize_into(bytes); self.minimum.serialize_into(bytes); self.maximum.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ValuatorInfo { pub class_id: InputClass, pub len: u8, pub mode: ValuatorMode, pub motion_size: u32, pub axes: Vec, } impl TryParse for ValuatorInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (axes_len, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (motion_size, remaining) = u32::try_parse(remaining)?; let (axes, remaining) = crate::x11_utils::parse_list::(remaining, axes_len.try_to_usize()?)?; let class_id = class_id.into(); let mode = mode.into(); let result = ValuatorInfo { class_id, len, mode, motion_size, axes }; Ok((result, remaining)) } } impl Serialize for ValuatorInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.class_id).serialize_into(bytes); self.len.serialize_into(bytes); let axes_len = u8::try_from(self.axes.len()).expect("`axes` has too many elements"); axes_len.serialize_into(bytes); u8::from(self.mode).serialize_into(bytes); self.motion_size.serialize_into(bytes); self.axes.serialize_into(bytes); } } impl ValuatorInfo { /// Get the value of the `axes_len` field. /// /// The `axes_len` field is used as the length field of the `axes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn axes_len(&self) -> u8 { self.axes.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InputInfoInfoKey { pub min_keycode: KeyCode, pub max_keycode: KeyCode, pub num_keys: u16, } impl TryParse for InputInfoInfoKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (min_keycode, remaining) = KeyCode::try_parse(remaining)?; let (max_keycode, remaining) = KeyCode::try_parse(remaining)?; let (num_keys, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let result = InputInfoInfoKey { min_keycode, max_keycode, num_keys }; Ok((result, remaining)) } } impl Serialize for InputInfoInfoKey { type Bytes = [u8; 6]; fn serialize(&self) -> [u8; 6] { let min_keycode_bytes = self.min_keycode.serialize(); let max_keycode_bytes = self.max_keycode.serialize(); let num_keys_bytes = self.num_keys.serialize(); [ min_keycode_bytes[0], max_keycode_bytes[0], num_keys_bytes[0], num_keys_bytes[1], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(6); self.min_keycode.serialize_into(bytes); self.max_keycode.serialize_into(bytes); self.num_keys.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InputInfoInfoButton { pub num_buttons: u16, } impl TryParse for InputInfoInfoButton { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_buttons, remaining) = u16::try_parse(remaining)?; let result = InputInfoInfoButton { num_buttons }; Ok((result, remaining)) } } impl Serialize for InputInfoInfoButton { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let num_buttons_bytes = self.num_buttons.serialize(); [ num_buttons_bytes[0], num_buttons_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.num_buttons.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct InputInfoInfoValuator { pub mode: ValuatorMode, pub motion_size: u32, pub axes: Vec, } impl TryParse for InputInfoInfoValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (axes_len, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (motion_size, remaining) = u32::try_parse(remaining)?; let (axes, remaining) = crate::x11_utils::parse_list::(remaining, axes_len.try_to_usize()?)?; let mode = mode.into(); let result = InputInfoInfoValuator { mode, motion_size, axes }; Ok((result, remaining)) } } impl Serialize for InputInfoInfoValuator { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(6); let axes_len = u8::try_from(self.axes.len()).expect("`axes` has too many elements"); axes_len.serialize_into(bytes); u8::from(self.mode).serialize_into(bytes); self.motion_size.serialize_into(bytes); self.axes.serialize_into(bytes); } } impl InputInfoInfoValuator { /// Get the value of the `axes_len` field. /// /// The `axes_len` field is used as the length field of the `axes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn axes_len(&self) -> u8 { self.axes.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum InputInfoInfo { Key(InputInfoInfoKey), Button(InputInfoInfoButton), Valuator(InputInfoInfoValuator), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl InputInfoInfo { fn try_parse(value: &[u8], class_id: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(class_id); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(InputClass::KEY) { let (key, new_remaining) = InputInfoInfoKey::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(InputInfoInfo::Key(key)); } if switch_expr == u32::from(InputClass::BUTTON) { let (button, new_remaining) = InputInfoInfoButton::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(InputInfoInfo::Button(button)); } if switch_expr == u32::from(InputClass::VALUATOR) { let (valuator, new_remaining) = InputInfoInfoValuator::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(InputInfoInfo::Valuator(valuator)); } match parse_result { None => Ok((InputInfoInfo::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl InputInfoInfo { pub fn as_key(&self) -> Option<&InputInfoInfoKey> { match self { InputInfoInfo::Key(value) => Some(value), _ => None, } } pub fn as_button(&self) -> Option<&InputInfoInfoButton> { match self { InputInfoInfo::Button(value) => Some(value), _ => None, } } pub fn as_valuator(&self) -> Option<&InputInfoInfoValuator> { match self { InputInfoInfo::Valuator(value) => Some(value), _ => None, } } } impl InputInfoInfo { #[allow(dead_code)] fn serialize(&self, class_id: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, class_id); result } fn serialize_into(&self, bytes: &mut Vec, class_id: u8) { assert_eq!(self.switch_expr(), u32::from(class_id), "switch `info` has an inconsistent discriminant"); match self { InputInfoInfo::Key(key) => key.serialize_into(bytes), InputInfoInfo::Button(button) => button.serialize_into(bytes), InputInfoInfo::Valuator(valuator) => valuator.serialize_into(bytes), InputInfoInfo::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl InputInfoInfo { fn switch_expr(&self) -> u32 { match self { InputInfoInfo::Key(_) => u32::from(InputClass::KEY), InputInfoInfo::Button(_) => u32::from(InputClass::BUTTON), InputInfoInfo::Valuator(_) => u32::from(InputClass::VALUATOR), InputInfoInfo::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct InputInfo { pub len: u8, pub info: InputInfoInfo, } impl TryParse for InputInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (info, remaining) = InputInfoInfo::try_parse(remaining, class_id)?; let result = InputInfo { len, info }; Ok((result, remaining)) } } impl Serialize for InputInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); let class_id = u8::try_from(self.info.switch_expr()).unwrap(); class_id.serialize_into(bytes); self.len.serialize_into(bytes); self.info.serialize_into(bytes, class_id); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceName { pub string: Vec, } impl TryParse for DeviceName { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (len, remaining) = u8::try_parse(remaining)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, len.try_to_usize()?)?; let string = string.to_vec(); let result = DeviceName { string }; Ok((result, remaining)) } } impl Serialize for DeviceName { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let len = u8::try_from(self.string.len()).expect("`string` has too many elements"); len.serialize_into(bytes); bytes.extend_from_slice(&self.string); } } #[allow(clippy::len_without_is_empty)] // This is not a container and is_empty() makes no sense impl DeviceName { /// Get the value of the `len` field. /// /// The `len` field is used as the length field of the `string` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn len(&self) -> u8 { self.string.len() .try_into().unwrap() } } /// Opcode for the ListInputDevices request pub const LIST_INPUT_DEVICES_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListInputDevicesRequest; impl ListInputDevicesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, LIST_INPUT_DEVICES_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_INPUT_DEVICES_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(ListInputDevicesRequest ) } } impl Request for ListInputDevicesRequest { type Reply = ListInputDevicesReply; } pub fn list_input_devices(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListInputDevicesRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListInputDevicesReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub devices: Vec, pub infos: Vec, pub names: Vec, } impl TryParse for ListInputDevicesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (devices_len, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let (devices, remaining) = crate::x11_utils::parse_list::(remaining, devices_len.try_to_usize()?)?; let (infos, remaining) = crate::x11_utils::parse_list::(remaining, devices.iter().try_fold(0u32, |acc, x| acc.checked_add(u32::from(x.num_class_info)).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let (names, remaining) = crate::x11_utils::parse_list::(remaining, devices_len.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListInputDevicesReply { xi_reply_type, sequence, length, devices, infos, names }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListInputDevicesReply { /// Get the value of the `devices_len` field. /// /// The `devices_len` field is used as the length field of the `devices` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn devices_len(&self) -> u8 { self.devices.len() .try_into().unwrap() } } pub type EventTypeBase = u8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InputClassInfo { pub class_id: InputClass, pub event_type_base: EventTypeBase, } impl TryParse for InputClassInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (event_type_base, remaining) = EventTypeBase::try_parse(remaining)?; let class_id = class_id.into(); let result = InputClassInfo { class_id, event_type_base }; Ok((result, remaining)) } } impl Serialize for InputClassInfo { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let class_id_bytes = u8::from(self.class_id).serialize(); let event_type_base_bytes = self.event_type_base.serialize(); [ class_id_bytes[0], event_type_base_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); u8::from(self.class_id).serialize_into(bytes); self.event_type_base.serialize_into(bytes); } } /// Opcode for the OpenDevice request pub const OPEN_DEVICE_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OpenDeviceRequest { pub device_id: u8, } impl OpenDeviceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, OPEN_DEVICE_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != OPEN_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(OpenDeviceRequest { device_id, }) } } impl Request for OpenDeviceRequest { type Reply = OpenDeviceReply; } pub fn open_device(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = OpenDeviceRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenDeviceReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub class_info: Vec, } impl TryParse for OpenDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_classes, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let (class_info, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = OpenDeviceReply { xi_reply_type, sequence, length, class_info }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl OpenDeviceReply { /// Get the value of the `num_classes` field. /// /// The `num_classes` field is used as the length field of the `class_info` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_classes(&self) -> u8 { self.class_info.len() .try_into().unwrap() } } /// Opcode for the CloseDevice request pub const CLOSE_DEVICE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CloseDeviceRequest { pub device_id: u8, } impl CloseDeviceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, CLOSE_DEVICE_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CLOSE_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(CloseDeviceRequest { device_id, }) } } impl Request for CloseDeviceRequest { type Reply = (); } pub fn close_device(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CloseDeviceRequest { device_id, }; request0.send(conn) } /// Opcode for the SetDeviceMode request pub const SET_DEVICE_MODE_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetDeviceModeRequest { pub device_id: u8, pub mode: ValuatorMode, } impl SetDeviceModeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_MODE_REQUEST, 0, 0, device_id_bytes[0], mode_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_DEVICE_MODE_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let (mode, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SetDeviceModeRequest { device_id, mode, }) } } impl Request for SetDeviceModeRequest { type Reply = SetDeviceModeReply; } pub fn set_device_mode(conn: &Conn, device_id: u8, mode: ValuatorMode) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetDeviceModeRequest { device_id, mode, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetDeviceModeReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: xproto::GrabStatus, } impl TryParse for SetDeviceModeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = SetDeviceModeReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SelectExtensionEvent request pub const SELECT_EXTENSION_EVENT_REQUEST: u8 = 6; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SelectExtensionEventRequest<'input> { pub window: xproto::Window, pub classes: Cow<'input, [EventClass]>, } impl<'input> SelectExtensionEventRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let num_classes = u16::try_from(self.classes.len()).expect("`classes` has too many elements"); let num_classes_bytes = num_classes.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_EXTENSION_EVENT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], num_classes_bytes[0], num_classes_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let classes_bytes = self.classes.serialize(); let length_so_far = length_so_far + classes_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), classes_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SELECT_EXTENSION_EVENT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let _ = remaining; Ok(SelectExtensionEventRequest { window, classes: Cow::Owned(classes), }) } /// Clone all borrowed data in this SelectExtensionEventRequest. pub fn into_owned(self) -> SelectExtensionEventRequest<'static> { SelectExtensionEventRequest { window: self.window, classes: Cow::Owned(self.classes.into_owned()), } } } impl<'input> Request for SelectExtensionEventRequest<'input> { type Reply = (); } pub fn select_extension_event<'c, 'input, Conn>(conn: &'c Conn, window: xproto::Window, classes: &'input [EventClass]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SelectExtensionEventRequest { window, classes: Cow::Borrowed(classes), }; request0.send(conn) } /// Opcode for the GetSelectedExtensionEvents request pub const GET_SELECTED_EXTENSION_EVENTS_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetSelectedExtensionEventsRequest { pub window: xproto::Window, } impl GetSelectedExtensionEventsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SELECTED_EXTENSION_EVENTS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SELECTED_EXTENSION_EVENTS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetSelectedExtensionEventsRequest { window, }) } } impl Request for GetSelectedExtensionEventsRequest { type Reply = GetSelectedExtensionEventsReply; } pub fn get_selected_extension_events(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetSelectedExtensionEventsRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetSelectedExtensionEventsReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub this_classes: Vec, pub all_classes: Vec, } impl TryParse for GetSelectedExtensionEventsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_this_classes, remaining) = u16::try_parse(remaining)?; let (num_all_classes, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (this_classes, remaining) = crate::x11_utils::parse_list::(remaining, num_this_classes.try_to_usize()?)?; let (all_classes, remaining) = crate::x11_utils::parse_list::(remaining, num_all_classes.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetSelectedExtensionEventsReply { xi_reply_type, sequence, length, this_classes, all_classes }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetSelectedExtensionEventsReply { /// Get the value of the `num_this_classes` field. /// /// The `num_this_classes` field is used as the length field of the `this_classes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_this_classes(&self) -> u16 { self.this_classes.len() .try_into().unwrap() } /// Get the value of the `num_all_classes` field. /// /// The `num_all_classes` field is used as the length field of the `all_classes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_all_classes(&self) -> u16 { self.all_classes.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PropagateMode(u8); impl PropagateMode { pub const ADD_TO_LIST: Self = Self(0); pub const DELETE_FROM_LIST: Self = Self(1); } impl From for u8 { #[inline] fn from(input: PropagateMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PropagateMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: PropagateMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: PropagateMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: PropagateMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PropagateMode) -> Self { Some(u32::from(input.0)) } } impl From for PropagateMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for PropagateMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ADD_TO_LIST.0.into(), "ADD_TO_LIST", "AddToList"), (Self::DELETE_FROM_LIST.0.into(), "DELETE_FROM_LIST", "DeleteFromList"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the ChangeDeviceDontPropagateList request pub const CHANGE_DEVICE_DONT_PROPAGATE_LIST_REQUEST: u8 = 8; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeDeviceDontPropagateListRequest<'input> { pub window: xproto::Window, pub mode: PropagateMode, pub classes: Cow<'input, [EventClass]>, } impl<'input> ChangeDeviceDontPropagateListRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let num_classes = u16::try_from(self.classes.len()).expect("`classes` has too many elements"); let num_classes_bytes = num_classes.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_DEVICE_DONT_PROPAGATE_LIST_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], num_classes_bytes[0], num_classes_bytes[1], mode_bytes[0], 0, ]; let length_so_far = length_so_far + request0.len(); let classes_bytes = self.classes.serialize(); let length_so_far = length_so_far + classes_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), classes_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_DEVICE_DONT_PROPAGATE_LIST_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let _ = remaining; Ok(ChangeDeviceDontPropagateListRequest { window, mode, classes: Cow::Owned(classes), }) } /// Clone all borrowed data in this ChangeDeviceDontPropagateListRequest. pub fn into_owned(self) -> ChangeDeviceDontPropagateListRequest<'static> { ChangeDeviceDontPropagateListRequest { window: self.window, mode: self.mode, classes: Cow::Owned(self.classes.into_owned()), } } } impl<'input> Request for ChangeDeviceDontPropagateListRequest<'input> { type Reply = (); } pub fn change_device_dont_propagate_list<'c, 'input, Conn>(conn: &'c Conn, window: xproto::Window, mode: PropagateMode, classes: &'input [EventClass]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeDeviceDontPropagateListRequest { window, mode, classes: Cow::Borrowed(classes), }; request0.send(conn) } /// Opcode for the GetDeviceDontPropagateList request pub const GET_DEVICE_DONT_PROPAGATE_LIST_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceDontPropagateListRequest { pub window: xproto::Window, } impl GetDeviceDontPropagateListRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_DONT_PROPAGATE_LIST_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_DONT_PROPAGATE_LIST_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetDeviceDontPropagateListRequest { window, }) } } impl Request for GetDeviceDontPropagateListRequest { type Reply = GetDeviceDontPropagateListReply; } pub fn get_device_dont_propagate_list(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceDontPropagateListRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceDontPropagateListReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub classes: Vec, } impl TryParse for GetDeviceDontPropagateListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceDontPropagateListReply { xi_reply_type, sequence, length, classes }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceDontPropagateListReply { /// Get the value of the `num_classes` field. /// /// The `num_classes` field is used as the length field of the `classes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_classes(&self) -> u16 { self.classes.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceTimeCoord { pub time: xproto::Timestamp, pub axisvalues: Vec, } impl DeviceTimeCoord { pub fn try_parse(remaining: &[u8], num_axes: u8) -> Result<(Self, &[u8]), ParseError> { let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, num_axes.try_to_usize()?)?; let result = DeviceTimeCoord { time, axisvalues }; Ok((result, remaining)) } } impl DeviceTimeCoord { #[allow(dead_code)] fn serialize(&self, num_axes: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, num_axes); result } fn serialize_into(&self, bytes: &mut Vec, num_axes: u8) { self.time.serialize_into(bytes); assert_eq!(self.axisvalues.len(), usize::try_from(num_axes).unwrap(), "`axisvalues` has an incorrect length"); self.axisvalues.serialize_into(bytes); } } /// Opcode for the GetDeviceMotionEvents request pub const GET_DEVICE_MOTION_EVENTS_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceMotionEventsRequest { pub start: xproto::Timestamp, pub stop: xproto::Timestamp, pub device_id: u8, } impl GetDeviceMotionEventsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let start_bytes = self.start.serialize(); let stop_bytes = self.stop.serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_MOTION_EVENTS_REQUEST, 0, 0, start_bytes[0], start_bytes[1], start_bytes[2], start_bytes[3], stop_bytes[0], stop_bytes[1], stop_bytes[2], stop_bytes[3], device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_MOTION_EVENTS_REQUEST { return Err(ParseError::InvalidValue); } let (start, remaining) = xproto::Timestamp::try_parse(value)?; let (stop, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDeviceMotionEventsRequest { start, stop, device_id, }) } } impl Request for GetDeviceMotionEventsRequest { type Reply = GetDeviceMotionEventsReply; } pub fn get_device_motion_events(conn: &Conn, start: xproto::Timestamp, stop: A, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let stop: xproto::Timestamp = stop.into(); let request0 = GetDeviceMotionEventsRequest { start, stop, device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceMotionEventsReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub num_axes: u8, pub device_mode: ValuatorMode, pub events: Vec, } impl TryParse for GetDeviceMotionEventsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_events, remaining) = u32::try_parse(remaining)?; let (num_axes, remaining) = u8::try_parse(remaining)?; let (device_mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(18..).ok_or(ParseError::InsufficientData)?; let mut remaining = remaining; let list_length = num_events.try_to_usize()?; let mut events = Vec::with_capacity(list_length); for _ in 0..list_length { let (v, new_remaining) = DeviceTimeCoord::try_parse(remaining, num_axes)?; remaining = new_remaining; events.push(v); } if response_type != 1 { return Err(ParseError::InvalidValue); } let device_mode = device_mode.into(); let result = GetDeviceMotionEventsReply { xi_reply_type, sequence, length, num_axes, device_mode, events }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceMotionEventsReply { /// Get the value of the `num_events` field. /// /// The `num_events` field is used as the length field of the `events` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_events(&self) -> u32 { self.events.len() .try_into().unwrap() } } /// Opcode for the ChangeKeyboardDevice request pub const CHANGE_KEYBOARD_DEVICE_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangeKeyboardDeviceRequest { pub device_id: u8, } impl ChangeKeyboardDeviceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_KEYBOARD_DEVICE_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CHANGE_KEYBOARD_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(ChangeKeyboardDeviceRequest { device_id, }) } } impl Request for ChangeKeyboardDeviceRequest { type Reply = ChangeKeyboardDeviceReply; } pub fn change_keyboard_device(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeKeyboardDeviceRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangeKeyboardDeviceReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: xproto::GrabStatus, } impl TryParse for ChangeKeyboardDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = ChangeKeyboardDeviceReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the ChangePointerDevice request pub const CHANGE_POINTER_DEVICE_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangePointerDeviceRequest { pub x_axis: u8, pub y_axis: u8, pub device_id: u8, } impl ChangePointerDeviceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let x_axis_bytes = self.x_axis.serialize(); let y_axis_bytes = self.y_axis.serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_POINTER_DEVICE_REQUEST, 0, 0, x_axis_bytes[0], y_axis_bytes[0], device_id_bytes[0], 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CHANGE_POINTER_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (x_axis, remaining) = u8::try_parse(value)?; let (y_axis, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(ChangePointerDeviceRequest { x_axis, y_axis, device_id, }) } } impl Request for ChangePointerDeviceRequest { type Reply = ChangePointerDeviceReply; } pub fn change_pointer_device(conn: &Conn, x_axis: u8, y_axis: u8, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangePointerDeviceRequest { x_axis, y_axis, device_id, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangePointerDeviceReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: xproto::GrabStatus, } impl TryParse for ChangePointerDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = ChangePointerDeviceReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GrabDevice request pub const GRAB_DEVICE_REQUEST: u8 = 13; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GrabDeviceRequest<'input> { pub grab_window: xproto::Window, pub time: xproto::Timestamp, pub this_device_mode: xproto::GrabMode, pub other_device_mode: xproto::GrabMode, pub owner_events: bool, pub device_id: u8, pub classes: Cow<'input, [EventClass]>, } impl<'input> GrabDeviceRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let grab_window_bytes = self.grab_window.serialize(); let time_bytes = self.time.serialize(); let num_classes = u16::try_from(self.classes.len()).expect("`classes` has too many elements"); let num_classes_bytes = num_classes.serialize(); let this_device_mode_bytes = u8::from(self.this_device_mode).serialize(); let other_device_mode_bytes = u8::from(self.other_device_mode).serialize(); let owner_events_bytes = self.owner_events.serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GRAB_DEVICE_REQUEST, 0, 0, grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], num_classes_bytes[0], num_classes_bytes[1], this_device_mode_bytes[0], other_device_mode_bytes[0], owner_events_bytes[0], device_id_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let classes_bytes = self.classes.serialize(); let length_so_far = length_so_far + classes_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), classes_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != GRAB_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (grab_window, remaining) = xproto::Window::try_parse(value)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let (this_device_mode, remaining) = u8::try_parse(remaining)?; let this_device_mode = this_device_mode.into(); let (other_device_mode, remaining) = u8::try_parse(remaining)?; let other_device_mode = other_device_mode.into(); let (owner_events, remaining) = bool::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let _ = remaining; Ok(GrabDeviceRequest { grab_window, time, this_device_mode, other_device_mode, owner_events, device_id, classes: Cow::Owned(classes), }) } /// Clone all borrowed data in this GrabDeviceRequest. pub fn into_owned(self) -> GrabDeviceRequest<'static> { GrabDeviceRequest { grab_window: self.grab_window, time: self.time, this_device_mode: self.this_device_mode, other_device_mode: self.other_device_mode, owner_events: self.owner_events, device_id: self.device_id, classes: Cow::Owned(self.classes.into_owned()), } } } impl<'input> Request for GrabDeviceRequest<'input> { type Reply = GrabDeviceReply; } pub fn grab_device<'c, 'input, Conn, A>(conn: &'c Conn, grab_window: xproto::Window, time: A, this_device_mode: xproto::GrabMode, other_device_mode: xproto::GrabMode, owner_events: bool, device_id: u8, classes: &'input [EventClass]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let time: xproto::Timestamp = time.into(); let request0 = GrabDeviceRequest { grab_window, time, this_device_mode, other_device_mode, owner_events, device_id, classes: Cow::Borrowed(classes), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GrabDeviceReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: xproto::GrabStatus, } impl TryParse for GrabDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = GrabDeviceReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the UngrabDevice request pub const UNGRAB_DEVICE_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UngrabDeviceRequest { pub time: xproto::Timestamp, pub device_id: u8, } impl UngrabDeviceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let time_bytes = self.time.serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, UNGRAB_DEVICE_REQUEST, 0, 0, time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNGRAB_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (time, remaining) = xproto::Timestamp::try_parse(value)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(UngrabDeviceRequest { time, device_id, }) } } impl Request for UngrabDeviceRequest { type Reply = (); } pub fn ungrab_device(conn: &Conn, time: A, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let time: xproto::Timestamp = time.into(); let request0 = UngrabDeviceRequest { time, device_id, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ModifierDevice(u8); impl ModifierDevice { pub const USE_X_KEYBOARD: Self = Self(255); } impl From for u8 { #[inline] fn from(input: ModifierDevice) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ModifierDevice) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ModifierDevice) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ModifierDevice) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ModifierDevice) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ModifierDevice) -> Self { Some(u32::from(input.0)) } } impl From for ModifierDevice { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ModifierDevice { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::USE_X_KEYBOARD.0.into(), "USE_X_KEYBOARD", "UseXKeyboard"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the GrabDeviceKey request pub const GRAB_DEVICE_KEY_REQUEST: u8 = 15; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GrabDeviceKeyRequest<'input> { pub grab_window: xproto::Window, pub modifiers: u16, pub modifier_device: u8, pub grabbed_device: u8, pub key: u8, pub this_device_mode: xproto::GrabMode, pub other_device_mode: xproto::GrabMode, pub owner_events: bool, pub classes: Cow<'input, [EventClass]>, } impl<'input> GrabDeviceKeyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let grab_window_bytes = self.grab_window.serialize(); let num_classes = u16::try_from(self.classes.len()).expect("`classes` has too many elements"); let num_classes_bytes = num_classes.serialize(); let modifiers_bytes = self.modifiers.serialize(); let modifier_device_bytes = self.modifier_device.serialize(); let grabbed_device_bytes = self.grabbed_device.serialize(); let key_bytes = self.key.serialize(); let this_device_mode_bytes = u8::from(self.this_device_mode).serialize(); let other_device_mode_bytes = u8::from(self.other_device_mode).serialize(); let owner_events_bytes = self.owner_events.serialize(); let mut request0 = vec![ extension_information.major_opcode, GRAB_DEVICE_KEY_REQUEST, 0, 0, grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], num_classes_bytes[0], num_classes_bytes[1], modifiers_bytes[0], modifiers_bytes[1], modifier_device_bytes[0], grabbed_device_bytes[0], key_bytes[0], this_device_mode_bytes[0], other_device_mode_bytes[0], owner_events_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let classes_bytes = self.classes.serialize(); let length_so_far = length_so_far + classes_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), classes_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != GRAB_DEVICE_KEY_REQUEST { return Err(ParseError::InvalidValue); } let (grab_window, remaining) = xproto::Window::try_parse(value)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let (modifiers, remaining) = u16::try_parse(remaining)?; let (modifier_device, remaining) = u8::try_parse(remaining)?; let (grabbed_device, remaining) = u8::try_parse(remaining)?; let (key, remaining) = u8::try_parse(remaining)?; let (this_device_mode, remaining) = u8::try_parse(remaining)?; let this_device_mode = this_device_mode.into(); let (other_device_mode, remaining) = u8::try_parse(remaining)?; let other_device_mode = other_device_mode.into(); let (owner_events, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let _ = remaining; Ok(GrabDeviceKeyRequest { grab_window, modifiers, modifier_device, grabbed_device, key, this_device_mode, other_device_mode, owner_events, classes: Cow::Owned(classes), }) } /// Clone all borrowed data in this GrabDeviceKeyRequest. pub fn into_owned(self) -> GrabDeviceKeyRequest<'static> { GrabDeviceKeyRequest { grab_window: self.grab_window, modifiers: self.modifiers, modifier_device: self.modifier_device, grabbed_device: self.grabbed_device, key: self.key, this_device_mode: self.this_device_mode, other_device_mode: self.other_device_mode, owner_events: self.owner_events, classes: Cow::Owned(self.classes.into_owned()), } } } impl<'input> Request for GrabDeviceKeyRequest<'input> { type Reply = (); } pub fn grab_device_key<'c, 'input, Conn, A, B, C>(conn: &'c Conn, grab_window: xproto::Window, modifiers: A, modifier_device: B, grabbed_device: u8, key: C, this_device_mode: xproto::GrabMode, other_device_mode: xproto::GrabMode, owner_events: bool, classes: &'input [EventClass]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, { let modifiers: u16 = modifiers.into(); let modifier_device: u8 = modifier_device.into(); let key: u8 = key.into(); let request0 = GrabDeviceKeyRequest { grab_window, modifiers, modifier_device, grabbed_device, key, this_device_mode, other_device_mode, owner_events, classes: Cow::Borrowed(classes), }; request0.send(conn) } /// Opcode for the UngrabDeviceKey request pub const UNGRAB_DEVICE_KEY_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UngrabDeviceKeyRequest { pub grab_window: xproto::Window, pub modifiers: u16, pub modifier_device: u8, pub key: u8, pub grabbed_device: u8, } impl UngrabDeviceKeyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let grab_window_bytes = self.grab_window.serialize(); let modifiers_bytes = self.modifiers.serialize(); let modifier_device_bytes = self.modifier_device.serialize(); let key_bytes = self.key.serialize(); let grabbed_device_bytes = self.grabbed_device.serialize(); let mut request0 = vec![ extension_information.major_opcode, UNGRAB_DEVICE_KEY_REQUEST, 0, 0, grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], modifiers_bytes[0], modifiers_bytes[1], modifier_device_bytes[0], key_bytes[0], grabbed_device_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNGRAB_DEVICE_KEY_REQUEST { return Err(ParseError::InvalidValue); } let (grab_window, remaining) = xproto::Window::try_parse(value)?; let (modifiers, remaining) = u16::try_parse(remaining)?; let (modifier_device, remaining) = u8::try_parse(remaining)?; let (key, remaining) = u8::try_parse(remaining)?; let (grabbed_device, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(UngrabDeviceKeyRequest { grab_window, modifiers, modifier_device, key, grabbed_device, }) } } impl Request for UngrabDeviceKeyRequest { type Reply = (); } pub fn ungrab_device_key(conn: &Conn, grab_window: xproto::Window, modifiers: A, modifier_device: B, key: C, grabbed_device: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, { let modifiers: u16 = modifiers.into(); let modifier_device: u8 = modifier_device.into(); let key: u8 = key.into(); let request0 = UngrabDeviceKeyRequest { grab_window, modifiers, modifier_device, key, grabbed_device, }; request0.send(conn) } /// Opcode for the GrabDeviceButton request pub const GRAB_DEVICE_BUTTON_REQUEST: u8 = 17; #[derive(Debug, Clone, PartialEq, Eq)] pub struct GrabDeviceButtonRequest<'input> { pub grab_window: xproto::Window, pub grabbed_device: u8, pub modifier_device: u8, pub modifiers: u16, pub this_device_mode: xproto::GrabMode, pub other_device_mode: xproto::GrabMode, pub button: u8, pub owner_events: bool, pub classes: Cow<'input, [EventClass]>, } impl<'input> GrabDeviceButtonRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let grab_window_bytes = self.grab_window.serialize(); let grabbed_device_bytes = self.grabbed_device.serialize(); let modifier_device_bytes = self.modifier_device.serialize(); let num_classes = u16::try_from(self.classes.len()).expect("`classes` has too many elements"); let num_classes_bytes = num_classes.serialize(); let modifiers_bytes = self.modifiers.serialize(); let this_device_mode_bytes = u8::from(self.this_device_mode).serialize(); let other_device_mode_bytes = u8::from(self.other_device_mode).serialize(); let button_bytes = self.button.serialize(); let owner_events_bytes = self.owner_events.serialize(); let mut request0 = vec![ extension_information.major_opcode, GRAB_DEVICE_BUTTON_REQUEST, 0, 0, grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], grabbed_device_bytes[0], modifier_device_bytes[0], num_classes_bytes[0], num_classes_bytes[1], modifiers_bytes[0], modifiers_bytes[1], this_device_mode_bytes[0], other_device_mode_bytes[0], button_bytes[0], owner_events_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let classes_bytes = self.classes.serialize(); let length_so_far = length_so_far + classes_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), classes_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != GRAB_DEVICE_BUTTON_REQUEST { return Err(ParseError::InvalidValue); } let (grab_window, remaining) = xproto::Window::try_parse(value)?; let (grabbed_device, remaining) = u8::try_parse(remaining)?; let (modifier_device, remaining) = u8::try_parse(remaining)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let (modifiers, remaining) = u16::try_parse(remaining)?; let (this_device_mode, remaining) = u8::try_parse(remaining)?; let this_device_mode = this_device_mode.into(); let (other_device_mode, remaining) = u8::try_parse(remaining)?; let other_device_mode = other_device_mode.into(); let (button, remaining) = u8::try_parse(remaining)?; let (owner_events, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let _ = remaining; Ok(GrabDeviceButtonRequest { grab_window, grabbed_device, modifier_device, modifiers, this_device_mode, other_device_mode, button, owner_events, classes: Cow::Owned(classes), }) } /// Clone all borrowed data in this GrabDeviceButtonRequest. pub fn into_owned(self) -> GrabDeviceButtonRequest<'static> { GrabDeviceButtonRequest { grab_window: self.grab_window, grabbed_device: self.grabbed_device, modifier_device: self.modifier_device, modifiers: self.modifiers, this_device_mode: self.this_device_mode, other_device_mode: self.other_device_mode, button: self.button, owner_events: self.owner_events, classes: Cow::Owned(self.classes.into_owned()), } } } impl<'input> Request for GrabDeviceButtonRequest<'input> { type Reply = (); } pub fn grab_device_button<'c, 'input, Conn, A, B, C>(conn: &'c Conn, grab_window: xproto::Window, grabbed_device: u8, modifier_device: A, modifiers: B, this_device_mode: xproto::GrabMode, other_device_mode: xproto::GrabMode, button: C, owner_events: bool, classes: &'input [EventClass]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, { let modifier_device: u8 = modifier_device.into(); let modifiers: u16 = modifiers.into(); let button: u8 = button.into(); let request0 = GrabDeviceButtonRequest { grab_window, grabbed_device, modifier_device, modifiers, this_device_mode, other_device_mode, button, owner_events, classes: Cow::Borrowed(classes), }; request0.send(conn) } /// Opcode for the UngrabDeviceButton request pub const UNGRAB_DEVICE_BUTTON_REQUEST: u8 = 18; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UngrabDeviceButtonRequest { pub grab_window: xproto::Window, pub modifiers: u16, pub modifier_device: u8, pub button: u8, pub grabbed_device: u8, } impl UngrabDeviceButtonRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let grab_window_bytes = self.grab_window.serialize(); let modifiers_bytes = self.modifiers.serialize(); let modifier_device_bytes = self.modifier_device.serialize(); let button_bytes = self.button.serialize(); let grabbed_device_bytes = self.grabbed_device.serialize(); let mut request0 = vec![ extension_information.major_opcode, UNGRAB_DEVICE_BUTTON_REQUEST, 0, 0, grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], modifiers_bytes[0], modifiers_bytes[1], modifier_device_bytes[0], button_bytes[0], grabbed_device_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNGRAB_DEVICE_BUTTON_REQUEST { return Err(ParseError::InvalidValue); } let (grab_window, remaining) = xproto::Window::try_parse(value)?; let (modifiers, remaining) = u16::try_parse(remaining)?; let (modifier_device, remaining) = u8::try_parse(remaining)?; let (button, remaining) = u8::try_parse(remaining)?; let (grabbed_device, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(UngrabDeviceButtonRequest { grab_window, modifiers, modifier_device, button, grabbed_device, }) } } impl Request for UngrabDeviceButtonRequest { type Reply = (); } pub fn ungrab_device_button(conn: &Conn, grab_window: xproto::Window, modifiers: A, modifier_device: B, button: C, grabbed_device: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, { let modifiers: u16 = modifiers.into(); let modifier_device: u8 = modifier_device.into(); let button: u8 = button.into(); let request0 = UngrabDeviceButtonRequest { grab_window, modifiers, modifier_device, button, grabbed_device, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DeviceInputMode(u8); impl DeviceInputMode { pub const ASYNC_THIS_DEVICE: Self = Self(0); pub const SYNC_THIS_DEVICE: Self = Self(1); pub const REPLAY_THIS_DEVICE: Self = Self(2); pub const ASYNC_OTHER_DEVICES: Self = Self(3); pub const ASYNC_ALL: Self = Self(4); pub const SYNC_ALL: Self = Self(5); } impl From for u8 { #[inline] fn from(input: DeviceInputMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DeviceInputMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: DeviceInputMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceInputMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: DeviceInputMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceInputMode) -> Self { Some(u32::from(input.0)) } } impl From for DeviceInputMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for DeviceInputMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ASYNC_THIS_DEVICE.0.into(), "ASYNC_THIS_DEVICE", "AsyncThisDevice"), (Self::SYNC_THIS_DEVICE.0.into(), "SYNC_THIS_DEVICE", "SyncThisDevice"), (Self::REPLAY_THIS_DEVICE.0.into(), "REPLAY_THIS_DEVICE", "ReplayThisDevice"), (Self::ASYNC_OTHER_DEVICES.0.into(), "ASYNC_OTHER_DEVICES", "AsyncOtherDevices"), (Self::ASYNC_ALL.0.into(), "ASYNC_ALL", "AsyncAll"), (Self::SYNC_ALL.0.into(), "SYNC_ALL", "SyncAll"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the AllowDeviceEvents request pub const ALLOW_DEVICE_EVENTS_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AllowDeviceEventsRequest { pub time: xproto::Timestamp, pub mode: DeviceInputMode, pub device_id: u8, } impl AllowDeviceEventsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let time_bytes = self.time.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, ALLOW_DEVICE_EVENTS_REQUEST, 0, 0, time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], mode_bytes[0], device_id_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != ALLOW_DEVICE_EVENTS_REQUEST { return Err(ParseError::InvalidValue); } let (time, remaining) = xproto::Timestamp::try_parse(value)?; let (mode, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(AllowDeviceEventsRequest { time, mode, device_id, }) } } impl Request for AllowDeviceEventsRequest { type Reply = (); } pub fn allow_device_events(conn: &Conn, time: A, mode: DeviceInputMode, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let time: xproto::Timestamp = time.into(); let request0 = AllowDeviceEventsRequest { time, mode, device_id, }; request0.send(conn) } /// Opcode for the GetDeviceFocus request pub const GET_DEVICE_FOCUS_REQUEST: u8 = 20; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceFocusRequest { pub device_id: u8, } impl GetDeviceFocusRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_FOCUS_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_FOCUS_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDeviceFocusRequest { device_id, }) } } impl Request for GetDeviceFocusRequest { type Reply = GetDeviceFocusReply; } pub fn get_device_focus(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceFocusRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceFocusReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub focus: xproto::Window, pub time: xproto::Timestamp, pub revert_to: xproto::InputFocus, } impl TryParse for GetDeviceFocusReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (focus, remaining) = xproto::Window::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (revert_to, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(15..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let revert_to = revert_to.into(); let result = GetDeviceFocusReply { xi_reply_type, sequence, length, focus, time, revert_to }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetDeviceFocus request pub const SET_DEVICE_FOCUS_REQUEST: u8 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetDeviceFocusRequest { pub focus: xproto::Window, pub time: xproto::Timestamp, pub revert_to: xproto::InputFocus, pub device_id: u8, } impl SetDeviceFocusRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let focus_bytes = self.focus.serialize(); let time_bytes = self.time.serialize(); let revert_to_bytes = u8::from(self.revert_to).serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_FOCUS_REQUEST, 0, 0, focus_bytes[0], focus_bytes[1], focus_bytes[2], focus_bytes[3], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], revert_to_bytes[0], device_id_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_DEVICE_FOCUS_REQUEST { return Err(ParseError::InvalidValue); } let (focus, remaining) = xproto::Window::try_parse(value)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (revert_to, remaining) = u8::try_parse(remaining)?; let revert_to = revert_to.into(); let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SetDeviceFocusRequest { focus, time, revert_to, device_id, }) } } impl Request for SetDeviceFocusRequest { type Reply = (); } pub fn set_device_focus(conn: &Conn, focus: A, time: B, revert_to: xproto::InputFocus, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let focus: xproto::Window = focus.into(); let time: xproto::Timestamp = time.into(); let request0 = SetDeviceFocusRequest { focus, time, revert_to, device_id, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct FeedbackClass(u8); impl FeedbackClass { pub const KEYBOARD: Self = Self(0); pub const POINTER: Self = Self(1); pub const STRING: Self = Self(2); pub const INTEGER: Self = Self(3); pub const LED: Self = Self(4); pub const BELL: Self = Self(5); } impl From for u8 { #[inline] fn from(input: FeedbackClass) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: FeedbackClass) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: FeedbackClass) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: FeedbackClass) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: FeedbackClass) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: FeedbackClass) -> Self { Some(u32::from(input.0)) } } impl From for FeedbackClass { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for FeedbackClass { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEYBOARD.0.into(), "KEYBOARD", "Keyboard"), (Self::POINTER.0.into(), "POINTER", "Pointer"), (Self::STRING.0.into(), "STRING", "String"), (Self::INTEGER.0.into(), "INTEGER", "Integer"), (Self::LED.0.into(), "LED", "Led"), (Self::BELL.0.into(), "BELL", "Bell"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KbdFeedbackState { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub pitch: u16, pub duration: u16, pub led_mask: u32, pub led_values: u32, pub global_auto_repeat: bool, pub click: u8, pub percent: u8, pub auto_repeats: [u8; 32], } impl TryParse for KbdFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (pitch, remaining) = u16::try_parse(remaining)?; let (duration, remaining) = u16::try_parse(remaining)?; let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let (global_auto_repeat, remaining) = bool::try_parse(remaining)?; let (click, remaining) = u8::try_parse(remaining)?; let (percent, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (auto_repeats, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let auto_repeats = <[u8; 32]>::try_from(auto_repeats).unwrap(); let class_id = class_id.into(); let result = KbdFeedbackState { class_id, feedback_id, len, pitch, duration, led_mask, led_values, global_auto_repeat, click, percent, auto_repeats }; Ok((result, remaining)) } } impl Serialize for KbdFeedbackState { type Bytes = [u8; 52]; fn serialize(&self) -> [u8; 52] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let pitch_bytes = self.pitch.serialize(); let duration_bytes = self.duration.serialize(); let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); let global_auto_repeat_bytes = self.global_auto_repeat.serialize(); let click_bytes = self.click.serialize(); let percent_bytes = self.percent.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], global_auto_repeat_bytes[0], click_bytes[0], percent_bytes[0], 0, self.auto_repeats[0], self.auto_repeats[1], self.auto_repeats[2], self.auto_repeats[3], self.auto_repeats[4], self.auto_repeats[5], self.auto_repeats[6], self.auto_repeats[7], self.auto_repeats[8], self.auto_repeats[9], self.auto_repeats[10], self.auto_repeats[11], self.auto_repeats[12], self.auto_repeats[13], self.auto_repeats[14], self.auto_repeats[15], self.auto_repeats[16], self.auto_repeats[17], self.auto_repeats[18], self.auto_repeats[19], self.auto_repeats[20], self.auto_repeats[21], self.auto_repeats[22], self.auto_repeats[23], self.auto_repeats[24], self.auto_repeats[25], self.auto_repeats[26], self.auto_repeats[27], self.auto_repeats[28], self.auto_repeats[29], self.auto_repeats[30], self.auto_repeats[31], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(52); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.pitch.serialize_into(bytes); self.duration.serialize_into(bytes); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); self.global_auto_repeat.serialize_into(bytes); self.click.serialize_into(bytes); self.percent.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.auto_repeats); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PtrFeedbackState { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub accel_num: u16, pub accel_denom: u16, pub threshold: u16, } impl TryParse for PtrFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (accel_num, remaining) = u16::try_parse(remaining)?; let (accel_denom, remaining) = u16::try_parse(remaining)?; let (threshold, remaining) = u16::try_parse(remaining)?; let class_id = class_id.into(); let result = PtrFeedbackState { class_id, feedback_id, len, accel_num, accel_denom, threshold }; Ok((result, remaining)) } } impl Serialize for PtrFeedbackState { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let accel_num_bytes = self.accel_num.serialize(); let accel_denom_bytes = self.accel_denom.serialize(); let threshold_bytes = self.threshold.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], 0, 0, accel_num_bytes[0], accel_num_bytes[1], accel_denom_bytes[0], accel_denom_bytes[1], threshold_bytes[0], threshold_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.accel_num.serialize_into(bytes); self.accel_denom.serialize_into(bytes); self.threshold.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IntegerFeedbackState { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub resolution: u32, pub min_value: i32, pub max_value: i32, } impl TryParse for IntegerFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (resolution, remaining) = u32::try_parse(remaining)?; let (min_value, remaining) = i32::try_parse(remaining)?; let (max_value, remaining) = i32::try_parse(remaining)?; let class_id = class_id.into(); let result = IntegerFeedbackState { class_id, feedback_id, len, resolution, min_value, max_value }; Ok((result, remaining)) } } impl Serialize for IntegerFeedbackState { type Bytes = [u8; 16]; fn serialize(&self) -> [u8; 16] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let resolution_bytes = self.resolution.serialize(); let min_value_bytes = self.min_value.serialize(); let max_value_bytes = self.max_value.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], resolution_bytes[0], resolution_bytes[1], resolution_bytes[2], resolution_bytes[3], min_value_bytes[0], min_value_bytes[1], min_value_bytes[2], min_value_bytes[3], max_value_bytes[0], max_value_bytes[1], max_value_bytes[2], max_value_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.resolution.serialize_into(bytes); self.min_value.serialize_into(bytes); self.max_value.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct StringFeedbackState { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub max_symbols: u16, pub keysyms: Vec, } impl TryParse for StringFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (max_symbols, remaining) = u16::try_parse(remaining)?; let (num_keysyms, remaining) = u16::try_parse(remaining)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, num_keysyms.try_to_usize()?)?; let class_id = class_id.into(); let result = StringFeedbackState { class_id, feedback_id, len, max_symbols, keysyms }; Ok((result, remaining)) } } impl Serialize for StringFeedbackState { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.max_symbols.serialize_into(bytes); let num_keysyms = u16::try_from(self.keysyms.len()).expect("`keysyms` has too many elements"); num_keysyms.serialize_into(bytes); self.keysyms.serialize_into(bytes); } } impl StringFeedbackState { /// Get the value of the `num_keysyms` field. /// /// The `num_keysyms` field is used as the length field of the `keysyms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_keysyms(&self) -> u16 { self.keysyms.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BellFeedbackState { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub percent: u8, pub pitch: u16, pub duration: u16, } impl TryParse for BellFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (percent, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (pitch, remaining) = u16::try_parse(remaining)?; let (duration, remaining) = u16::try_parse(remaining)?; let class_id = class_id.into(); let result = BellFeedbackState { class_id, feedback_id, len, percent, pitch, duration }; Ok((result, remaining)) } } impl Serialize for BellFeedbackState { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let percent_bytes = self.percent.serialize(); let pitch_bytes = self.pitch.serialize(); let duration_bytes = self.duration.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], percent_bytes[0], 0, 0, 0, pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.percent.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.pitch.serialize_into(bytes); self.duration.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct LedFeedbackState { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub led_mask: u32, pub led_values: u32, } impl TryParse for LedFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let class_id = class_id.into(); let result = LedFeedbackState { class_id, feedback_id, len, led_mask, led_values }; Ok((result, remaining)) } } impl Serialize for LedFeedbackState { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackStateDataKeyboard { pub pitch: u16, pub duration: u16, pub led_mask: u32, pub led_values: u32, pub global_auto_repeat: bool, pub click: u8, pub percent: u8, pub auto_repeats: [u8; 32], } impl TryParse for FeedbackStateDataKeyboard { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (pitch, remaining) = u16::try_parse(remaining)?; let (duration, remaining) = u16::try_parse(remaining)?; let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let (global_auto_repeat, remaining) = bool::try_parse(remaining)?; let (click, remaining) = u8::try_parse(remaining)?; let (percent, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (auto_repeats, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let auto_repeats = <[u8; 32]>::try_from(auto_repeats).unwrap(); let result = FeedbackStateDataKeyboard { pitch, duration, led_mask, led_values, global_auto_repeat, click, percent, auto_repeats }; Ok((result, remaining)) } } impl Serialize for FeedbackStateDataKeyboard { type Bytes = [u8; 48]; fn serialize(&self) -> [u8; 48] { let pitch_bytes = self.pitch.serialize(); let duration_bytes = self.duration.serialize(); let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); let global_auto_repeat_bytes = self.global_auto_repeat.serialize(); let click_bytes = self.click.serialize(); let percent_bytes = self.percent.serialize(); [ pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], global_auto_repeat_bytes[0], click_bytes[0], percent_bytes[0], 0, self.auto_repeats[0], self.auto_repeats[1], self.auto_repeats[2], self.auto_repeats[3], self.auto_repeats[4], self.auto_repeats[5], self.auto_repeats[6], self.auto_repeats[7], self.auto_repeats[8], self.auto_repeats[9], self.auto_repeats[10], self.auto_repeats[11], self.auto_repeats[12], self.auto_repeats[13], self.auto_repeats[14], self.auto_repeats[15], self.auto_repeats[16], self.auto_repeats[17], self.auto_repeats[18], self.auto_repeats[19], self.auto_repeats[20], self.auto_repeats[21], self.auto_repeats[22], self.auto_repeats[23], self.auto_repeats[24], self.auto_repeats[25], self.auto_repeats[26], self.auto_repeats[27], self.auto_repeats[28], self.auto_repeats[29], self.auto_repeats[30], self.auto_repeats[31], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(48); self.pitch.serialize_into(bytes); self.duration.serialize_into(bytes); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); self.global_auto_repeat.serialize_into(bytes); self.click.serialize_into(bytes); self.percent.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.auto_repeats); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackStateDataPointer { pub accel_num: u16, pub accel_denom: u16, pub threshold: u16, } impl TryParse for FeedbackStateDataPointer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (accel_num, remaining) = u16::try_parse(remaining)?; let (accel_denom, remaining) = u16::try_parse(remaining)?; let (threshold, remaining) = u16::try_parse(remaining)?; let result = FeedbackStateDataPointer { accel_num, accel_denom, threshold }; Ok((result, remaining)) } } impl Serialize for FeedbackStateDataPointer { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let accel_num_bytes = self.accel_num.serialize(); let accel_denom_bytes = self.accel_denom.serialize(); let threshold_bytes = self.threshold.serialize(); [ 0, 0, accel_num_bytes[0], accel_num_bytes[1], accel_denom_bytes[0], accel_denom_bytes[1], threshold_bytes[0], threshold_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); bytes.extend_from_slice(&[0; 2]); self.accel_num.serialize_into(bytes); self.accel_denom.serialize_into(bytes); self.threshold.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FeedbackStateDataString { pub max_symbols: u16, pub keysyms: Vec, } impl TryParse for FeedbackStateDataString { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (max_symbols, remaining) = u16::try_parse(remaining)?; let (num_keysyms, remaining) = u16::try_parse(remaining)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, num_keysyms.try_to_usize()?)?; let result = FeedbackStateDataString { max_symbols, keysyms }; Ok((result, remaining)) } } impl Serialize for FeedbackStateDataString { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.max_symbols.serialize_into(bytes); let num_keysyms = u16::try_from(self.keysyms.len()).expect("`keysyms` has too many elements"); num_keysyms.serialize_into(bytes); self.keysyms.serialize_into(bytes); } } impl FeedbackStateDataString { /// Get the value of the `num_keysyms` field. /// /// The `num_keysyms` field is used as the length field of the `keysyms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_keysyms(&self) -> u16 { self.keysyms.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackStateDataInteger { pub resolution: u32, pub min_value: i32, pub max_value: i32, } impl TryParse for FeedbackStateDataInteger { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (resolution, remaining) = u32::try_parse(remaining)?; let (min_value, remaining) = i32::try_parse(remaining)?; let (max_value, remaining) = i32::try_parse(remaining)?; let result = FeedbackStateDataInteger { resolution, min_value, max_value }; Ok((result, remaining)) } } impl Serialize for FeedbackStateDataInteger { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let resolution_bytes = self.resolution.serialize(); let min_value_bytes = self.min_value.serialize(); let max_value_bytes = self.max_value.serialize(); [ resolution_bytes[0], resolution_bytes[1], resolution_bytes[2], resolution_bytes[3], min_value_bytes[0], min_value_bytes[1], min_value_bytes[2], min_value_bytes[3], max_value_bytes[0], max_value_bytes[1], max_value_bytes[2], max_value_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.resolution.serialize_into(bytes); self.min_value.serialize_into(bytes); self.max_value.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackStateDataLed { pub led_mask: u32, pub led_values: u32, } impl TryParse for FeedbackStateDataLed { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let result = FeedbackStateDataLed { led_mask, led_values }; Ok((result, remaining)) } } impl Serialize for FeedbackStateDataLed { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); [ led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackStateDataBell { pub percent: u8, pub pitch: u16, pub duration: u16, } impl TryParse for FeedbackStateDataBell { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (percent, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (pitch, remaining) = u16::try_parse(remaining)?; let (duration, remaining) = u16::try_parse(remaining)?; let result = FeedbackStateDataBell { percent, pitch, duration }; Ok((result, remaining)) } } impl Serialize for FeedbackStateDataBell { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let percent_bytes = self.percent.serialize(); let pitch_bytes = self.pitch.serialize(); let duration_bytes = self.duration.serialize(); [ percent_bytes[0], 0, 0, 0, pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.percent.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.pitch.serialize_into(bytes); self.duration.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum FeedbackStateData { Keyboard(FeedbackStateDataKeyboard), Pointer(FeedbackStateDataPointer), String(FeedbackStateDataString), Integer(FeedbackStateDataInteger), Led(FeedbackStateDataLed), Bell(FeedbackStateDataBell), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl FeedbackStateData { fn try_parse(value: &[u8], class_id: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(class_id); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(FeedbackClass::KEYBOARD) { let (keyboard, new_remaining) = FeedbackStateDataKeyboard::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackStateData::Keyboard(keyboard)); } if switch_expr == u32::from(FeedbackClass::POINTER) { let (pointer, new_remaining) = FeedbackStateDataPointer::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackStateData::Pointer(pointer)); } if switch_expr == u32::from(FeedbackClass::STRING) { let (string, new_remaining) = FeedbackStateDataString::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackStateData::String(string)); } if switch_expr == u32::from(FeedbackClass::INTEGER) { let (integer, new_remaining) = FeedbackStateDataInteger::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackStateData::Integer(integer)); } if switch_expr == u32::from(FeedbackClass::LED) { let (led, new_remaining) = FeedbackStateDataLed::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackStateData::Led(led)); } if switch_expr == u32::from(FeedbackClass::BELL) { let (bell, new_remaining) = FeedbackStateDataBell::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackStateData::Bell(bell)); } match parse_result { None => Ok((FeedbackStateData::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl FeedbackStateData { pub fn as_keyboard(&self) -> Option<&FeedbackStateDataKeyboard> { match self { FeedbackStateData::Keyboard(value) => Some(value), _ => None, } } pub fn as_pointer(&self) -> Option<&FeedbackStateDataPointer> { match self { FeedbackStateData::Pointer(value) => Some(value), _ => None, } } pub fn as_string(&self) -> Option<&FeedbackStateDataString> { match self { FeedbackStateData::String(value) => Some(value), _ => None, } } pub fn as_integer(&self) -> Option<&FeedbackStateDataInteger> { match self { FeedbackStateData::Integer(value) => Some(value), _ => None, } } pub fn as_led(&self) -> Option<&FeedbackStateDataLed> { match self { FeedbackStateData::Led(value) => Some(value), _ => None, } } pub fn as_bell(&self) -> Option<&FeedbackStateDataBell> { match self { FeedbackStateData::Bell(value) => Some(value), _ => None, } } } impl FeedbackStateData { #[allow(dead_code)] fn serialize(&self, class_id: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, class_id); result } fn serialize_into(&self, bytes: &mut Vec, class_id: u8) { assert_eq!(self.switch_expr(), u32::from(class_id), "switch `data` has an inconsistent discriminant"); match self { FeedbackStateData::Keyboard(keyboard) => keyboard.serialize_into(bytes), FeedbackStateData::Pointer(pointer) => pointer.serialize_into(bytes), FeedbackStateData::String(string) => string.serialize_into(bytes), FeedbackStateData::Integer(integer) => integer.serialize_into(bytes), FeedbackStateData::Led(led) => led.serialize_into(bytes), FeedbackStateData::Bell(bell) => bell.serialize_into(bytes), FeedbackStateData::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl FeedbackStateData { fn switch_expr(&self) -> u32 { match self { FeedbackStateData::Keyboard(_) => u32::from(FeedbackClass::KEYBOARD), FeedbackStateData::Pointer(_) => u32::from(FeedbackClass::POINTER), FeedbackStateData::String(_) => u32::from(FeedbackClass::STRING), FeedbackStateData::Integer(_) => u32::from(FeedbackClass::INTEGER), FeedbackStateData::Led(_) => u32::from(FeedbackClass::LED), FeedbackStateData::Bell(_) => u32::from(FeedbackClass::BELL), FeedbackStateData::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FeedbackState { pub feedback_id: u8, pub len: u16, pub data: FeedbackStateData, } impl TryParse for FeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = FeedbackStateData::try_parse(remaining, class_id)?; let result = FeedbackState { feedback_id, len, data }; Ok((result, remaining)) } } impl Serialize for FeedbackState { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); let class_id = u8::try_from(self.data.switch_expr()).unwrap(); class_id.serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.data.serialize_into(bytes, class_id); } } /// Opcode for the GetFeedbackControl request pub const GET_FEEDBACK_CONTROL_REQUEST: u8 = 22; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetFeedbackControlRequest { pub device_id: u8, } impl GetFeedbackControlRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_FEEDBACK_CONTROL_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_FEEDBACK_CONTROL_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetFeedbackControlRequest { device_id, }) } } impl Request for GetFeedbackControlRequest { type Reply = GetFeedbackControlReply; } pub fn get_feedback_control(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetFeedbackControlRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetFeedbackControlReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub feedbacks: Vec, } impl TryParse for GetFeedbackControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_feedbacks, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (feedbacks, remaining) = crate::x11_utils::parse_list::(remaining, num_feedbacks.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetFeedbackControlReply { xi_reply_type, sequence, length, feedbacks }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetFeedbackControlReply { /// Get the value of the `num_feedbacks` field. /// /// The `num_feedbacks` field is used as the length field of the `feedbacks` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_feedbacks(&self) -> u16 { self.feedbacks.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KbdFeedbackCtl { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub key: KeyCode, pub auto_repeat_mode: u8, pub key_click_percent: i8, pub bell_percent: i8, pub bell_pitch: i16, pub bell_duration: i16, pub led_mask: u32, pub led_values: u32, } impl TryParse for KbdFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (key, remaining) = KeyCode::try_parse(remaining)?; let (auto_repeat_mode, remaining) = u8::try_parse(remaining)?; let (key_click_percent, remaining) = i8::try_parse(remaining)?; let (bell_percent, remaining) = i8::try_parse(remaining)?; let (bell_pitch, remaining) = i16::try_parse(remaining)?; let (bell_duration, remaining) = i16::try_parse(remaining)?; let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let class_id = class_id.into(); let result = KbdFeedbackCtl { class_id, feedback_id, len, key, auto_repeat_mode, key_click_percent, bell_percent, bell_pitch, bell_duration, led_mask, led_values }; Ok((result, remaining)) } } impl Serialize for KbdFeedbackCtl { type Bytes = [u8; 20]; fn serialize(&self) -> [u8; 20] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let key_bytes = self.key.serialize(); let auto_repeat_mode_bytes = self.auto_repeat_mode.serialize(); let key_click_percent_bytes = self.key_click_percent.serialize(); let bell_percent_bytes = self.bell_percent.serialize(); let bell_pitch_bytes = self.bell_pitch.serialize(); let bell_duration_bytes = self.bell_duration.serialize(); let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], key_bytes[0], auto_repeat_mode_bytes[0], key_click_percent_bytes[0], bell_percent_bytes[0], bell_pitch_bytes[0], bell_pitch_bytes[1], bell_duration_bytes[0], bell_duration_bytes[1], led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(20); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.key.serialize_into(bytes); self.auto_repeat_mode.serialize_into(bytes); self.key_click_percent.serialize_into(bytes); self.bell_percent.serialize_into(bytes); self.bell_pitch.serialize_into(bytes); self.bell_duration.serialize_into(bytes); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PtrFeedbackCtl { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub num: i16, pub denom: i16, pub threshold: i16, } impl TryParse for PtrFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (num, remaining) = i16::try_parse(remaining)?; let (denom, remaining) = i16::try_parse(remaining)?; let (threshold, remaining) = i16::try_parse(remaining)?; let class_id = class_id.into(); let result = PtrFeedbackCtl { class_id, feedback_id, len, num, denom, threshold }; Ok((result, remaining)) } } impl Serialize for PtrFeedbackCtl { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let num_bytes = self.num.serialize(); let denom_bytes = self.denom.serialize(); let threshold_bytes = self.threshold.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], 0, 0, num_bytes[0], num_bytes[1], denom_bytes[0], denom_bytes[1], threshold_bytes[0], threshold_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.num.serialize_into(bytes); self.denom.serialize_into(bytes); self.threshold.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IntegerFeedbackCtl { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub int_to_display: i32, } impl TryParse for IntegerFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (int_to_display, remaining) = i32::try_parse(remaining)?; let class_id = class_id.into(); let result = IntegerFeedbackCtl { class_id, feedback_id, len, int_to_display }; Ok((result, remaining)) } } impl Serialize for IntegerFeedbackCtl { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let int_to_display_bytes = self.int_to_display.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], int_to_display_bytes[0], int_to_display_bytes[1], int_to_display_bytes[2], int_to_display_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.int_to_display.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct StringFeedbackCtl { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub keysyms: Vec, } impl TryParse for StringFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (num_keysyms, remaining) = u16::try_parse(remaining)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, num_keysyms.try_to_usize()?)?; let class_id = class_id.into(); let result = StringFeedbackCtl { class_id, feedback_id, len, keysyms }; Ok((result, remaining)) } } impl Serialize for StringFeedbackCtl { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); let num_keysyms = u16::try_from(self.keysyms.len()).expect("`keysyms` has too many elements"); num_keysyms.serialize_into(bytes); self.keysyms.serialize_into(bytes); } } impl StringFeedbackCtl { /// Get the value of the `num_keysyms` field. /// /// The `num_keysyms` field is used as the length field of the `keysyms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_keysyms(&self) -> u16 { self.keysyms.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BellFeedbackCtl { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub percent: i8, pub pitch: i16, pub duration: i16, } impl TryParse for BellFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (percent, remaining) = i8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (pitch, remaining) = i16::try_parse(remaining)?; let (duration, remaining) = i16::try_parse(remaining)?; let class_id = class_id.into(); let result = BellFeedbackCtl { class_id, feedback_id, len, percent, pitch, duration }; Ok((result, remaining)) } } impl Serialize for BellFeedbackCtl { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let percent_bytes = self.percent.serialize(); let pitch_bytes = self.pitch.serialize(); let duration_bytes = self.duration.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], percent_bytes[0], 0, 0, 0, pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.percent.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.pitch.serialize_into(bytes); self.duration.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct LedFeedbackCtl { pub class_id: FeedbackClass, pub feedback_id: u8, pub len: u16, pub led_mask: u32, pub led_values: u32, } impl TryParse for LedFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let class_id = class_id.into(); let result = LedFeedbackCtl { class_id, feedback_id, len, led_mask, led_values }; Ok((result, remaining)) } } impl Serialize for LedFeedbackCtl { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let class_id_bytes = u8::from(self.class_id).serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let len_bytes = self.len.serialize(); let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); [ class_id_bytes[0], feedback_id_bytes[0], len_bytes[0], len_bytes[1], led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u8::from(self.class_id).serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackCtlDataKeyboard { pub key: KeyCode, pub auto_repeat_mode: u8, pub key_click_percent: i8, pub bell_percent: i8, pub bell_pitch: i16, pub bell_duration: i16, pub led_mask: u32, pub led_values: u32, } impl TryParse for FeedbackCtlDataKeyboard { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (key, remaining) = KeyCode::try_parse(remaining)?; let (auto_repeat_mode, remaining) = u8::try_parse(remaining)?; let (key_click_percent, remaining) = i8::try_parse(remaining)?; let (bell_percent, remaining) = i8::try_parse(remaining)?; let (bell_pitch, remaining) = i16::try_parse(remaining)?; let (bell_duration, remaining) = i16::try_parse(remaining)?; let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let result = FeedbackCtlDataKeyboard { key, auto_repeat_mode, key_click_percent, bell_percent, bell_pitch, bell_duration, led_mask, led_values }; Ok((result, remaining)) } } impl Serialize for FeedbackCtlDataKeyboard { type Bytes = [u8; 16]; fn serialize(&self) -> [u8; 16] { let key_bytes = self.key.serialize(); let auto_repeat_mode_bytes = self.auto_repeat_mode.serialize(); let key_click_percent_bytes = self.key_click_percent.serialize(); let bell_percent_bytes = self.bell_percent.serialize(); let bell_pitch_bytes = self.bell_pitch.serialize(); let bell_duration_bytes = self.bell_duration.serialize(); let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); [ key_bytes[0], auto_repeat_mode_bytes[0], key_click_percent_bytes[0], bell_percent_bytes[0], bell_pitch_bytes[0], bell_pitch_bytes[1], bell_duration_bytes[0], bell_duration_bytes[1], led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); self.key.serialize_into(bytes); self.auto_repeat_mode.serialize_into(bytes); self.key_click_percent.serialize_into(bytes); self.bell_percent.serialize_into(bytes); self.bell_pitch.serialize_into(bytes); self.bell_duration.serialize_into(bytes); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackCtlDataPointer { pub num: i16, pub denom: i16, pub threshold: i16, } impl TryParse for FeedbackCtlDataPointer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (num, remaining) = i16::try_parse(remaining)?; let (denom, remaining) = i16::try_parse(remaining)?; let (threshold, remaining) = i16::try_parse(remaining)?; let result = FeedbackCtlDataPointer { num, denom, threshold }; Ok((result, remaining)) } } impl Serialize for FeedbackCtlDataPointer { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let num_bytes = self.num.serialize(); let denom_bytes = self.denom.serialize(); let threshold_bytes = self.threshold.serialize(); [ 0, 0, num_bytes[0], num_bytes[1], denom_bytes[0], denom_bytes[1], threshold_bytes[0], threshold_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); bytes.extend_from_slice(&[0; 2]); self.num.serialize_into(bytes); self.denom.serialize_into(bytes); self.threshold.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FeedbackCtlDataString { pub keysyms: Vec, } impl TryParse for FeedbackCtlDataString { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (num_keysyms, remaining) = u16::try_parse(remaining)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, num_keysyms.try_to_usize()?)?; let result = FeedbackCtlDataString { keysyms }; Ok((result, remaining)) } } impl Serialize for FeedbackCtlDataString { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); bytes.extend_from_slice(&[0; 2]); let num_keysyms = u16::try_from(self.keysyms.len()).expect("`keysyms` has too many elements"); num_keysyms.serialize_into(bytes); self.keysyms.serialize_into(bytes); } } impl FeedbackCtlDataString { /// Get the value of the `num_keysyms` field. /// /// The `num_keysyms` field is used as the length field of the `keysyms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_keysyms(&self) -> u16 { self.keysyms.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackCtlDataInteger { pub int_to_display: i32, } impl TryParse for FeedbackCtlDataInteger { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (int_to_display, remaining) = i32::try_parse(remaining)?; let result = FeedbackCtlDataInteger { int_to_display }; Ok((result, remaining)) } } impl Serialize for FeedbackCtlDataInteger { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let int_to_display_bytes = self.int_to_display.serialize(); [ int_to_display_bytes[0], int_to_display_bytes[1], int_to_display_bytes[2], int_to_display_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.int_to_display.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackCtlDataLed { pub led_mask: u32, pub led_values: u32, } impl TryParse for FeedbackCtlDataLed { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let result = FeedbackCtlDataLed { led_mask, led_values }; Ok((result, remaining)) } } impl Serialize for FeedbackCtlDataLed { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let led_mask_bytes = self.led_mask.serialize(); let led_values_bytes = self.led_values.serialize(); [ led_mask_bytes[0], led_mask_bytes[1], led_mask_bytes[2], led_mask_bytes[3], led_values_bytes[0], led_values_bytes[1], led_values_bytes[2], led_values_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.led_mask.serialize_into(bytes); self.led_values.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FeedbackCtlDataBell { pub percent: i8, pub pitch: i16, pub duration: i16, } impl TryParse for FeedbackCtlDataBell { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (percent, remaining) = i8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (pitch, remaining) = i16::try_parse(remaining)?; let (duration, remaining) = i16::try_parse(remaining)?; let result = FeedbackCtlDataBell { percent, pitch, duration }; Ok((result, remaining)) } } impl Serialize for FeedbackCtlDataBell { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let percent_bytes = self.percent.serialize(); let pitch_bytes = self.pitch.serialize(); let duration_bytes = self.duration.serialize(); [ percent_bytes[0], 0, 0, 0, pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.percent.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.pitch.serialize_into(bytes); self.duration.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum FeedbackCtlData { Keyboard(FeedbackCtlDataKeyboard), Pointer(FeedbackCtlDataPointer), String(FeedbackCtlDataString), Integer(FeedbackCtlDataInteger), Led(FeedbackCtlDataLed), Bell(FeedbackCtlDataBell), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl FeedbackCtlData { fn try_parse(value: &[u8], class_id: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(class_id); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(FeedbackClass::KEYBOARD) { let (keyboard, new_remaining) = FeedbackCtlDataKeyboard::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackCtlData::Keyboard(keyboard)); } if switch_expr == u32::from(FeedbackClass::POINTER) { let (pointer, new_remaining) = FeedbackCtlDataPointer::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackCtlData::Pointer(pointer)); } if switch_expr == u32::from(FeedbackClass::STRING) { let (string, new_remaining) = FeedbackCtlDataString::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackCtlData::String(string)); } if switch_expr == u32::from(FeedbackClass::INTEGER) { let (integer, new_remaining) = FeedbackCtlDataInteger::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackCtlData::Integer(integer)); } if switch_expr == u32::from(FeedbackClass::LED) { let (led, new_remaining) = FeedbackCtlDataLed::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackCtlData::Led(led)); } if switch_expr == u32::from(FeedbackClass::BELL) { let (bell, new_remaining) = FeedbackCtlDataBell::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(FeedbackCtlData::Bell(bell)); } match parse_result { None => Ok((FeedbackCtlData::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl FeedbackCtlData { pub fn as_keyboard(&self) -> Option<&FeedbackCtlDataKeyboard> { match self { FeedbackCtlData::Keyboard(value) => Some(value), _ => None, } } pub fn as_pointer(&self) -> Option<&FeedbackCtlDataPointer> { match self { FeedbackCtlData::Pointer(value) => Some(value), _ => None, } } pub fn as_string(&self) -> Option<&FeedbackCtlDataString> { match self { FeedbackCtlData::String(value) => Some(value), _ => None, } } pub fn as_integer(&self) -> Option<&FeedbackCtlDataInteger> { match self { FeedbackCtlData::Integer(value) => Some(value), _ => None, } } pub fn as_led(&self) -> Option<&FeedbackCtlDataLed> { match self { FeedbackCtlData::Led(value) => Some(value), _ => None, } } pub fn as_bell(&self) -> Option<&FeedbackCtlDataBell> { match self { FeedbackCtlData::Bell(value) => Some(value), _ => None, } } } impl FeedbackCtlData { #[allow(dead_code)] fn serialize(&self, class_id: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, class_id); result } fn serialize_into(&self, bytes: &mut Vec, class_id: u8) { assert_eq!(self.switch_expr(), u32::from(class_id), "switch `data` has an inconsistent discriminant"); match self { FeedbackCtlData::Keyboard(keyboard) => keyboard.serialize_into(bytes), FeedbackCtlData::Pointer(pointer) => pointer.serialize_into(bytes), FeedbackCtlData::String(string) => string.serialize_into(bytes), FeedbackCtlData::Integer(integer) => integer.serialize_into(bytes), FeedbackCtlData::Led(led) => led.serialize_into(bytes), FeedbackCtlData::Bell(bell) => bell.serialize_into(bytes), FeedbackCtlData::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl FeedbackCtlData { fn switch_expr(&self) -> u32 { match self { FeedbackCtlData::Keyboard(_) => u32::from(FeedbackClass::KEYBOARD), FeedbackCtlData::Pointer(_) => u32::from(FeedbackClass::POINTER), FeedbackCtlData::String(_) => u32::from(FeedbackClass::STRING), FeedbackCtlData::Integer(_) => u32::from(FeedbackClass::INTEGER), FeedbackCtlData::Led(_) => u32::from(FeedbackClass::LED), FeedbackCtlData::Bell(_) => u32::from(FeedbackClass::BELL), FeedbackCtlData::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct FeedbackCtl { pub feedback_id: u8, pub len: u16, pub data: FeedbackCtlData, } impl TryParse for FeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = FeedbackCtlData::try_parse(remaining, class_id)?; let result = FeedbackCtl { feedback_id, len, data }; Ok((result, remaining)) } } impl Serialize for FeedbackCtl { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); let class_id = u8::try_from(self.data.switch_expr()).unwrap(); class_id.serialize_into(bytes); self.feedback_id.serialize_into(bytes); self.len.serialize_into(bytes); self.data.serialize_into(bytes, class_id); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ChangeFeedbackControlMask(u8); impl ChangeFeedbackControlMask { pub const KEY_CLICK_PERCENT: Self = Self(1 << 0); pub const PERCENT: Self = Self(1 << 1); pub const PITCH: Self = Self(1 << 2); pub const DURATION: Self = Self(1 << 3); pub const LED: Self = Self(1 << 4); pub const LED_MODE: Self = Self(1 << 5); pub const KEY: Self = Self(1 << 6); pub const AUTO_REPEAT_MODE: Self = Self(1 << 7); pub const STRING: Self = Self(1 << 0); pub const INTEGER: Self = Self(1 << 0); pub const ACCEL_NUM: Self = Self(1 << 0); pub const ACCEL_DENOM: Self = Self(1 << 1); pub const THRESHOLD: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: ChangeFeedbackControlMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ChangeFeedbackControlMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ChangeFeedbackControlMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeFeedbackControlMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ChangeFeedbackControlMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeFeedbackControlMask) -> Self { Some(u32::from(input.0)) } } impl From for ChangeFeedbackControlMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ChangeFeedbackControlMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEY_CLICK_PERCENT.0.into(), "KEY_CLICK_PERCENT", "KeyClickPercent"), (Self::PERCENT.0.into(), "PERCENT", "Percent"), (Self::PITCH.0.into(), "PITCH", "Pitch"), (Self::DURATION.0.into(), "DURATION", "Duration"), (Self::LED.0.into(), "LED", "Led"), (Self::LED_MODE.0.into(), "LED_MODE", "LedMode"), (Self::KEY.0.into(), "KEY", "Key"), (Self::AUTO_REPEAT_MODE.0.into(), "AUTO_REPEAT_MODE", "AutoRepeatMode"), (Self::STRING.0.into(), "STRING", "String"), (Self::INTEGER.0.into(), "INTEGER", "Integer"), (Self::ACCEL_NUM.0.into(), "ACCEL_NUM", "AccelNum"), (Self::ACCEL_DENOM.0.into(), "ACCEL_DENOM", "AccelDenom"), (Self::THRESHOLD.0.into(), "THRESHOLD", "Threshold"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ChangeFeedbackControlMask, u8); /// Opcode for the ChangeFeedbackControl request pub const CHANGE_FEEDBACK_CONTROL_REQUEST: u8 = 23; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeFeedbackControlRequest { pub mask: u32, pub device_id: u8, pub feedback_id: u8, pub feedback: FeedbackCtl, } impl ChangeFeedbackControlRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mask_bytes = self.mask.serialize(); let device_id_bytes = self.device_id.serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_FEEDBACK_CONTROL_REQUEST, 0, 0, mask_bytes[0], mask_bytes[1], mask_bytes[2], mask_bytes[3], device_id_bytes[0], feedback_id_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let feedback_bytes = self.feedback.serialize(); let length_so_far = length_so_far + feedback_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), feedback_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CHANGE_FEEDBACK_CONTROL_REQUEST { return Err(ParseError::InvalidValue); } let (mask, remaining) = u32::try_parse(value)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (feedback, remaining) = FeedbackCtl::try_parse(remaining)?; let _ = remaining; Ok(ChangeFeedbackControlRequest { mask, device_id, feedback_id, feedback, }) } } impl Request for ChangeFeedbackControlRequest { type Reply = (); } pub fn change_feedback_control(conn: &Conn, mask: A, device_id: u8, feedback_id: u8, feedback: FeedbackCtl) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let mask: u32 = mask.into(); let request0 = ChangeFeedbackControlRequest { mask, device_id, feedback_id, feedback, }; request0.send(conn) } /// Opcode for the GetDeviceKeyMapping request pub const GET_DEVICE_KEY_MAPPING_REQUEST: u8 = 24; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceKeyMappingRequest { pub device_id: u8, pub first_keycode: KeyCode, pub count: u8, } impl GetDeviceKeyMappingRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let first_keycode_bytes = self.first_keycode.serialize(); let count_bytes = self.count.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_KEY_MAPPING_REQUEST, 0, 0, device_id_bytes[0], first_keycode_bytes[0], count_bytes[0], 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_KEY_MAPPING_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let (first_keycode, remaining) = KeyCode::try_parse(remaining)?; let (count, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDeviceKeyMappingRequest { device_id, first_keycode, count, }) } } impl Request for GetDeviceKeyMappingRequest { type Reply = GetDeviceKeyMappingReply; } pub fn get_device_key_mapping(conn: &Conn, device_id: u8, first_keycode: KeyCode, count: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceKeyMappingRequest { device_id, first_keycode, count, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceKeyMappingReply { pub xi_reply_type: u8, pub sequence: u16, pub keysyms_per_keycode: u8, pub keysyms: Vec, } impl TryParse for GetDeviceKeyMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (keysyms_per_keycode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceKeyMappingReply { xi_reply_type, sequence, keysyms_per_keycode, keysyms }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceKeyMappingReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `keysyms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.keysyms.len() .try_into().unwrap() } } /// Opcode for the ChangeDeviceKeyMapping request pub const CHANGE_DEVICE_KEY_MAPPING_REQUEST: u8 = 25; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeDeviceKeyMappingRequest<'input> { pub device_id: u8, pub first_keycode: KeyCode, pub keysyms_per_keycode: u8, pub keycode_count: u8, pub keysyms: Cow<'input, [xproto::Keysym]>, } impl<'input> ChangeDeviceKeyMappingRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let first_keycode_bytes = self.first_keycode.serialize(); let keysyms_per_keycode_bytes = self.keysyms_per_keycode.serialize(); let keycode_count_bytes = self.keycode_count.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_DEVICE_KEY_MAPPING_REQUEST, 0, 0, device_id_bytes[0], first_keycode_bytes[0], keysyms_per_keycode_bytes[0], keycode_count_bytes[0], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(self.keysyms.len(), usize::try_from(u32::from(self.keycode_count).checked_mul(u32::from(self.keysyms_per_keycode)).unwrap()).unwrap(), "`keysyms` has an incorrect length"); let keysyms_bytes = self.keysyms.serialize(); let length_so_far = length_so_far + keysyms_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), keysyms_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_DEVICE_KEY_MAPPING_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let (first_keycode, remaining) = KeyCode::try_parse(remaining)?; let (keysyms_per_keycode, remaining) = u8::try_parse(remaining)?; let (keycode_count, remaining) = u8::try_parse(remaining)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(keycode_count).checked_mul(u32::from(keysyms_per_keycode)).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(ChangeDeviceKeyMappingRequest { device_id, first_keycode, keysyms_per_keycode, keycode_count, keysyms: Cow::Owned(keysyms), }) } /// Clone all borrowed data in this ChangeDeviceKeyMappingRequest. pub fn into_owned(self) -> ChangeDeviceKeyMappingRequest<'static> { ChangeDeviceKeyMappingRequest { device_id: self.device_id, first_keycode: self.first_keycode, keysyms_per_keycode: self.keysyms_per_keycode, keycode_count: self.keycode_count, keysyms: Cow::Owned(self.keysyms.into_owned()), } } } impl<'input> Request for ChangeDeviceKeyMappingRequest<'input> { type Reply = (); } pub fn change_device_key_mapping<'c, 'input, Conn>(conn: &'c Conn, device_id: u8, first_keycode: KeyCode, keysyms_per_keycode: u8, keycode_count: u8, keysyms: &'input [xproto::Keysym]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeDeviceKeyMappingRequest { device_id, first_keycode, keysyms_per_keycode, keycode_count, keysyms: Cow::Borrowed(keysyms), }; request0.send(conn) } /// Opcode for the GetDeviceModifierMapping request pub const GET_DEVICE_MODIFIER_MAPPING_REQUEST: u8 = 26; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceModifierMappingRequest { pub device_id: u8, } impl GetDeviceModifierMappingRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_MODIFIER_MAPPING_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_MODIFIER_MAPPING_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDeviceModifierMappingRequest { device_id, }) } } impl Request for GetDeviceModifierMappingRequest { type Reply = GetDeviceModifierMappingReply; } pub fn get_device_modifier_mapping(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceModifierMappingRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceModifierMappingReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub keymaps: Vec, } impl TryParse for GetDeviceModifierMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (keycodes_per_modifier, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let (keymaps, remaining) = crate::x11_utils::parse_u8_list(remaining, u32::from(keycodes_per_modifier).checked_mul(8u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let keymaps = keymaps.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceModifierMappingReply { xi_reply_type, sequence, length, keymaps }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceModifierMappingReply { /// Get the value of the `keycodes_per_modifier` field. /// /// The `keycodes_per_modifier` field is used as the length field of the `keymaps` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn keycodes_per_modifier(&self) -> u8 { self.keymaps.len() .checked_div(8).unwrap() .try_into().unwrap() } } /// Opcode for the SetDeviceModifierMapping request pub const SET_DEVICE_MODIFIER_MAPPING_REQUEST: u8 = 27; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetDeviceModifierMappingRequest<'input> { pub device_id: u8, pub keymaps: Cow<'input, [u8]>, } impl<'input> SetDeviceModifierMappingRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); assert_eq!(self.keymaps.len() % 8, 0, "`keymaps` has an incorrect length, must be a multiple of 8"); let keycodes_per_modifier = u8::try_from(self.keymaps.len() / 8).expect("`keymaps` has too many elements"); let keycodes_per_modifier_bytes = keycodes_per_modifier.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_MODIFIER_MAPPING_REQUEST, 0, 0, device_id_bytes[0], keycodes_per_modifier_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.keymaps.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.keymaps, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_DEVICE_MODIFIER_MAPPING_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let (keycodes_per_modifier, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (keymaps, remaining) = crate::x11_utils::parse_u8_list(remaining, u32::from(keycodes_per_modifier).checked_mul(8u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let _ = remaining; Ok(SetDeviceModifierMappingRequest { device_id, keymaps: Cow::Borrowed(keymaps), }) } /// Clone all borrowed data in this SetDeviceModifierMappingRequest. pub fn into_owned(self) -> SetDeviceModifierMappingRequest<'static> { SetDeviceModifierMappingRequest { device_id: self.device_id, keymaps: Cow::Owned(self.keymaps.into_owned()), } } } impl<'input> Request for SetDeviceModifierMappingRequest<'input> { type Reply = SetDeviceModifierMappingReply; } pub fn set_device_modifier_mapping<'c, 'input, Conn>(conn: &'c Conn, device_id: u8, keymaps: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetDeviceModifierMappingRequest { device_id, keymaps: Cow::Borrowed(keymaps), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetDeviceModifierMappingReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: xproto::MappingStatus, } impl TryParse for SetDeviceModifierMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = SetDeviceModifierMappingReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetDeviceButtonMapping request pub const GET_DEVICE_BUTTON_MAPPING_REQUEST: u8 = 28; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceButtonMappingRequest { pub device_id: u8, } impl GetDeviceButtonMappingRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_BUTTON_MAPPING_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_BUTTON_MAPPING_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDeviceButtonMappingRequest { device_id, }) } } impl Request for GetDeviceButtonMappingRequest { type Reply = GetDeviceButtonMappingReply; } pub fn get_device_button_mapping(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceButtonMappingRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceButtonMappingReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub map: Vec, } impl TryParse for GetDeviceButtonMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (map_size, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let (map, remaining) = crate::x11_utils::parse_u8_list(remaining, map_size.try_to_usize()?)?; let map = map.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceButtonMappingReply { xi_reply_type, sequence, length, map }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceButtonMappingReply { /// Get the value of the `map_size` field. /// /// The `map_size` field is used as the length field of the `map` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn map_size(&self) -> u8 { self.map.len() .try_into().unwrap() } } /// Opcode for the SetDeviceButtonMapping request pub const SET_DEVICE_BUTTON_MAPPING_REQUEST: u8 = 29; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetDeviceButtonMappingRequest<'input> { pub device_id: u8, pub map: Cow<'input, [u8]>, } impl<'input> SetDeviceButtonMappingRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let map_size = u8::try_from(self.map.len()).expect("`map` has too many elements"); let map_size_bytes = map_size.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_BUTTON_MAPPING_REQUEST, 0, 0, device_id_bytes[0], map_size_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.map.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.map, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_DEVICE_BUTTON_MAPPING_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let (map_size, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (map, remaining) = crate::x11_utils::parse_u8_list(remaining, map_size.try_to_usize()?)?; let _ = remaining; Ok(SetDeviceButtonMappingRequest { device_id, map: Cow::Borrowed(map), }) } /// Clone all borrowed data in this SetDeviceButtonMappingRequest. pub fn into_owned(self) -> SetDeviceButtonMappingRequest<'static> { SetDeviceButtonMappingRequest { device_id: self.device_id, map: Cow::Owned(self.map.into_owned()), } } } impl<'input> Request for SetDeviceButtonMappingRequest<'input> { type Reply = SetDeviceButtonMappingReply; } pub fn set_device_button_mapping<'c, 'input, Conn>(conn: &'c Conn, device_id: u8, map: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetDeviceButtonMappingRequest { device_id, map: Cow::Borrowed(map), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetDeviceButtonMappingReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: xproto::MappingStatus, } impl TryParse for SetDeviceButtonMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = SetDeviceButtonMappingReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyState { pub class_id: InputClass, pub len: u8, pub num_keys: u8, pub keys: [u8; 32], } impl TryParse for KeyState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (keys, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let keys = <[u8; 32]>::try_from(keys).unwrap(); let class_id = class_id.into(); let result = KeyState { class_id, len, num_keys, keys }; Ok((result, remaining)) } } impl Serialize for KeyState { type Bytes = [u8; 36]; fn serialize(&self) -> [u8; 36] { let class_id_bytes = u8::from(self.class_id).serialize(); let len_bytes = self.len.serialize(); let num_keys_bytes = self.num_keys.serialize(); [ class_id_bytes[0], len_bytes[0], num_keys_bytes[0], 0, self.keys[0], self.keys[1], self.keys[2], self.keys[3], self.keys[4], self.keys[5], self.keys[6], self.keys[7], self.keys[8], self.keys[9], self.keys[10], self.keys[11], self.keys[12], self.keys[13], self.keys[14], self.keys[15], self.keys[16], self.keys[17], self.keys[18], self.keys[19], self.keys[20], self.keys[21], self.keys[22], self.keys[23], self.keys[24], self.keys[25], self.keys[26], self.keys[27], self.keys[28], self.keys[29], self.keys[30], self.keys[31], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(36); u8::from(self.class_id).serialize_into(bytes); self.len.serialize_into(bytes); self.num_keys.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.keys); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ButtonState { pub class_id: InputClass, pub len: u8, pub num_buttons: u8, pub buttons: [u8; 32], } impl TryParse for ButtonState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_buttons, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (buttons, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let buttons = <[u8; 32]>::try_from(buttons).unwrap(); let class_id = class_id.into(); let result = ButtonState { class_id, len, num_buttons, buttons }; Ok((result, remaining)) } } impl Serialize for ButtonState { type Bytes = [u8; 36]; fn serialize(&self) -> [u8; 36] { let class_id_bytes = u8::from(self.class_id).serialize(); let len_bytes = self.len.serialize(); let num_buttons_bytes = self.num_buttons.serialize(); [ class_id_bytes[0], len_bytes[0], num_buttons_bytes[0], 0, self.buttons[0], self.buttons[1], self.buttons[2], self.buttons[3], self.buttons[4], self.buttons[5], self.buttons[6], self.buttons[7], self.buttons[8], self.buttons[9], self.buttons[10], self.buttons[11], self.buttons[12], self.buttons[13], self.buttons[14], self.buttons[15], self.buttons[16], self.buttons[17], self.buttons[18], self.buttons[19], self.buttons[20], self.buttons[21], self.buttons[22], self.buttons[23], self.buttons[24], self.buttons[25], self.buttons[26], self.buttons[27], self.buttons[28], self.buttons[29], self.buttons[30], self.buttons[31], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(36); u8::from(self.class_id).serialize_into(bytes); self.len.serialize_into(bytes); self.num_buttons.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.buttons); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ValuatorStateModeMask(u8); impl ValuatorStateModeMask { pub const DEVICE_MODE_ABSOLUTE: Self = Self(1 << 0); pub const OUT_OF_PROXIMITY: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: ValuatorStateModeMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ValuatorStateModeMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ValuatorStateModeMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ValuatorStateModeMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ValuatorStateModeMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ValuatorStateModeMask) -> Self { Some(u32::from(input.0)) } } impl From for ValuatorStateModeMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ValuatorStateModeMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DEVICE_MODE_ABSOLUTE.0.into(), "DEVICE_MODE_ABSOLUTE", "DeviceModeAbsolute"), (Self::OUT_OF_PROXIMITY.0.into(), "OUT_OF_PROXIMITY", "OutOfProximity"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ValuatorStateModeMask, u8); #[derive(Debug, Clone, PartialEq, Eq)] pub struct ValuatorState { pub class_id: InputClass, pub len: u8, pub mode: u8, pub valuators: Vec, } impl TryParse for ValuatorState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (valuators, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let class_id = class_id.into(); let result = ValuatorState { class_id, len, mode, valuators }; Ok((result, remaining)) } } impl Serialize for ValuatorState { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); u8::from(self.class_id).serialize_into(bytes); self.len.serialize_into(bytes); let num_valuators = u8::try_from(self.valuators.len()).expect("`valuators` has too many elements"); num_valuators.serialize_into(bytes); self.mode.serialize_into(bytes); self.valuators.serialize_into(bytes); } } impl ValuatorState { /// Get the value of the `num_valuators` field. /// /// The `num_valuators` field is used as the length field of the `valuators` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_valuators(&self) -> u8 { self.valuators.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InputStateDataKey { pub num_keys: u8, pub keys: [u8; 32], } impl TryParse for InputStateDataKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (keys, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let keys = <[u8; 32]>::try_from(keys).unwrap(); let result = InputStateDataKey { num_keys, keys }; Ok((result, remaining)) } } impl Serialize for InputStateDataKey { type Bytes = [u8; 34]; fn serialize(&self) -> [u8; 34] { let num_keys_bytes = self.num_keys.serialize(); [ num_keys_bytes[0], 0, self.keys[0], self.keys[1], self.keys[2], self.keys[3], self.keys[4], self.keys[5], self.keys[6], self.keys[7], self.keys[8], self.keys[9], self.keys[10], self.keys[11], self.keys[12], self.keys[13], self.keys[14], self.keys[15], self.keys[16], self.keys[17], self.keys[18], self.keys[19], self.keys[20], self.keys[21], self.keys[22], self.keys[23], self.keys[24], self.keys[25], self.keys[26], self.keys[27], self.keys[28], self.keys[29], self.keys[30], self.keys[31], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(34); self.num_keys.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.keys); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InputStateDataButton { pub num_buttons: u8, pub buttons: [u8; 32], } impl TryParse for InputStateDataButton { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_buttons, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (buttons, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let buttons = <[u8; 32]>::try_from(buttons).unwrap(); let result = InputStateDataButton { num_buttons, buttons }; Ok((result, remaining)) } } impl Serialize for InputStateDataButton { type Bytes = [u8; 34]; fn serialize(&self) -> [u8; 34] { let num_buttons_bytes = self.num_buttons.serialize(); [ num_buttons_bytes[0], 0, self.buttons[0], self.buttons[1], self.buttons[2], self.buttons[3], self.buttons[4], self.buttons[5], self.buttons[6], self.buttons[7], self.buttons[8], self.buttons[9], self.buttons[10], self.buttons[11], self.buttons[12], self.buttons[13], self.buttons[14], self.buttons[15], self.buttons[16], self.buttons[17], self.buttons[18], self.buttons[19], self.buttons[20], self.buttons[21], self.buttons[22], self.buttons[23], self.buttons[24], self.buttons[25], self.buttons[26], self.buttons[27], self.buttons[28], self.buttons[29], self.buttons[30], self.buttons[31], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(34); self.num_buttons.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.buttons); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct InputStateDataValuator { pub mode: u8, pub valuators: Vec, } impl TryParse for InputStateDataValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_valuators, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (valuators, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let result = InputStateDataValuator { mode, valuators }; Ok((result, remaining)) } } impl Serialize for InputStateDataValuator { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); let num_valuators = u8::try_from(self.valuators.len()).expect("`valuators` has too many elements"); num_valuators.serialize_into(bytes); self.mode.serialize_into(bytes); self.valuators.serialize_into(bytes); } } impl InputStateDataValuator { /// Get the value of the `num_valuators` field. /// /// The `num_valuators` field is used as the length field of the `valuators` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_valuators(&self) -> u8 { self.valuators.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum InputStateData { Key(InputStateDataKey), Button(InputStateDataButton), Valuator(InputStateDataValuator), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl InputStateData { fn try_parse(value: &[u8], class_id: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(class_id); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(InputClass::KEY) { let (key, new_remaining) = InputStateDataKey::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(InputStateData::Key(key)); } if switch_expr == u32::from(InputClass::BUTTON) { let (button, new_remaining) = InputStateDataButton::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(InputStateData::Button(button)); } if switch_expr == u32::from(InputClass::VALUATOR) { let (valuator, new_remaining) = InputStateDataValuator::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(InputStateData::Valuator(valuator)); } match parse_result { None => Ok((InputStateData::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl InputStateData { pub fn as_key(&self) -> Option<&InputStateDataKey> { match self { InputStateData::Key(value) => Some(value), _ => None, } } pub fn as_button(&self) -> Option<&InputStateDataButton> { match self { InputStateData::Button(value) => Some(value), _ => None, } } pub fn as_valuator(&self) -> Option<&InputStateDataValuator> { match self { InputStateData::Valuator(value) => Some(value), _ => None, } } } impl InputStateData { #[allow(dead_code)] fn serialize(&self, class_id: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, class_id); result } fn serialize_into(&self, bytes: &mut Vec, class_id: u8) { assert_eq!(self.switch_expr(), u32::from(class_id), "switch `data` has an inconsistent discriminant"); match self { InputStateData::Key(key) => key.serialize_into(bytes), InputStateData::Button(button) => button.serialize_into(bytes), InputStateData::Valuator(valuator) => valuator.serialize_into(bytes), InputStateData::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl InputStateData { fn switch_expr(&self) -> u32 { match self { InputStateData::Key(_) => u32::from(InputClass::KEY), InputStateData::Button(_) => u32::from(InputClass::BUTTON), InputStateData::Valuator(_) => u32::from(InputClass::VALUATOR), InputStateData::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct InputState { pub len: u8, pub data: InputStateData, } impl TryParse for InputState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (data, remaining) = InputStateData::try_parse(remaining, class_id)?; let result = InputState { len, data }; Ok((result, remaining)) } } impl Serialize for InputState { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); let class_id = u8::try_from(self.data.switch_expr()).unwrap(); class_id.serialize_into(bytes); self.len.serialize_into(bytes); self.data.serialize_into(bytes, class_id); } } /// Opcode for the QueryDeviceState request pub const QUERY_DEVICE_STATE_REQUEST: u8 = 30; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryDeviceStateRequest { pub device_id: u8, } impl QueryDeviceStateRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_DEVICE_STATE_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_DEVICE_STATE_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(QueryDeviceStateRequest { device_id, }) } } impl Request for QueryDeviceStateRequest { type Reply = QueryDeviceStateReply; } pub fn query_device_state(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryDeviceStateRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryDeviceStateReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub classes: Vec, } impl TryParse for QueryDeviceStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_classes, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryDeviceStateReply { xi_reply_type, sequence, length, classes }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryDeviceStateReply { /// Get the value of the `num_classes` field. /// /// The `num_classes` field is used as the length field of the `classes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_classes(&self) -> u8 { self.classes.len() .try_into().unwrap() } } /// Opcode for the DeviceBell request pub const DEVICE_BELL_REQUEST: u8 = 32; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceBellRequest { pub device_id: u8, pub feedback_id: u8, pub feedback_class: u8, pub percent: i8, } impl DeviceBellRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let feedback_id_bytes = self.feedback_id.serialize(); let feedback_class_bytes = self.feedback_class.serialize(); let percent_bytes = self.percent.serialize(); let mut request0 = vec![ extension_information.major_opcode, DEVICE_BELL_REQUEST, 0, 0, device_id_bytes[0], feedback_id_bytes[0], feedback_class_bytes[0], percent_bytes[0], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DEVICE_BELL_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (feedback_class, remaining) = u8::try_parse(remaining)?; let (percent, remaining) = i8::try_parse(remaining)?; let _ = remaining; Ok(DeviceBellRequest { device_id, feedback_id, feedback_class, percent, }) } } impl Request for DeviceBellRequest { type Reply = (); } pub fn device_bell(conn: &Conn, device_id: u8, feedback_id: u8, feedback_class: u8, percent: i8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeviceBellRequest { device_id, feedback_id, feedback_class, percent, }; request0.send(conn) } /// Opcode for the SetDeviceValuators request pub const SET_DEVICE_VALUATORS_REQUEST: u8 = 33; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetDeviceValuatorsRequest<'input> { pub device_id: u8, pub first_valuator: u8, pub valuators: Cow<'input, [i32]>, } impl<'input> SetDeviceValuatorsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let first_valuator_bytes = self.first_valuator.serialize(); let num_valuators = u8::try_from(self.valuators.len()).expect("`valuators` has too many elements"); let num_valuators_bytes = num_valuators.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_VALUATORS_REQUEST, 0, 0, device_id_bytes[0], first_valuator_bytes[0], num_valuators_bytes[0], 0, ]; let length_so_far = length_so_far + request0.len(); let valuators_bytes = self.valuators.serialize(); let length_so_far = length_so_far + valuators_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), valuators_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_DEVICE_VALUATORS_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let (first_valuator, remaining) = u8::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (valuators, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let _ = remaining; Ok(SetDeviceValuatorsRequest { device_id, first_valuator, valuators: Cow::Owned(valuators), }) } /// Clone all borrowed data in this SetDeviceValuatorsRequest. pub fn into_owned(self) -> SetDeviceValuatorsRequest<'static> { SetDeviceValuatorsRequest { device_id: self.device_id, first_valuator: self.first_valuator, valuators: Cow::Owned(self.valuators.into_owned()), } } } impl<'input> Request for SetDeviceValuatorsRequest<'input> { type Reply = SetDeviceValuatorsReply; } pub fn set_device_valuators<'c, 'input, Conn>(conn: &'c Conn, device_id: u8, first_valuator: u8, valuators: &'input [i32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetDeviceValuatorsRequest { device_id, first_valuator, valuators: Cow::Borrowed(valuators), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetDeviceValuatorsReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: xproto::GrabStatus, } impl TryParse for SetDeviceValuatorsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = SetDeviceValuatorsReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DeviceControl(u16); impl DeviceControl { pub const RESOLUTION: Self = Self(1); pub const ABSCALIB: Self = Self(2); pub const CORE: Self = Self(3); pub const ENABLE: Self = Self(4); pub const ABSAREA: Self = Self(5); } impl From for u16 { #[inline] fn from(input: DeviceControl) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DeviceControl) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: DeviceControl) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceControl) -> Self { Some(u32::from(input.0)) } } impl From for DeviceControl { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for DeviceControl { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for DeviceControl { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::RESOLUTION.0.into(), "RESOLUTION", "Resolution"), (Self::ABSCALIB.0.into(), "ABSCALIB", "Abscalib"), (Self::CORE.0.into(), "CORE", "Core"), (Self::ENABLE.0.into(), "ENABLE", "Enable"), (Self::ABSAREA.0.into(), "ABSAREA", "Absarea"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceResolutionState { pub control_id: DeviceControl, pub len: u16, pub resolution_values: Vec, pub resolution_min: Vec, pub resolution_max: Vec, } impl TryParse for DeviceResolutionState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (num_valuators, remaining) = u32::try_parse(remaining)?; let (resolution_values, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let (resolution_min, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let (resolution_max, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let control_id = control_id.into(); let result = DeviceResolutionState { control_id, len, resolution_values, resolution_min, resolution_max }; Ok((result, remaining)) } } impl Serialize for DeviceResolutionState { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); let num_valuators = u32::try_from(self.resolution_values.len()).expect("`resolution_values` has too many elements"); num_valuators.serialize_into(bytes); self.resolution_values.serialize_into(bytes); assert_eq!(self.resolution_min.len(), usize::try_from(num_valuators).unwrap(), "`resolution_min` has an incorrect length"); self.resolution_min.serialize_into(bytes); assert_eq!(self.resolution_max.len(), usize::try_from(num_valuators).unwrap(), "`resolution_max` has an incorrect length"); self.resolution_max.serialize_into(bytes); } } impl DeviceResolutionState { /// Get the value of the `num_valuators` field. /// /// The `num_valuators` field is used as the length field of the `resolution_values` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_valuators(&self) -> u32 { self.resolution_values.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceAbsCalibState { pub control_id: DeviceControl, pub len: u16, pub min_x: i32, pub max_x: i32, pub min_y: i32, pub max_y: i32, pub flip_x: u32, pub flip_y: u32, pub rotation: u32, pub button_threshold: u32, } impl TryParse for DeviceAbsCalibState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (min_x, remaining) = i32::try_parse(remaining)?; let (max_x, remaining) = i32::try_parse(remaining)?; let (min_y, remaining) = i32::try_parse(remaining)?; let (max_y, remaining) = i32::try_parse(remaining)?; let (flip_x, remaining) = u32::try_parse(remaining)?; let (flip_y, remaining) = u32::try_parse(remaining)?; let (rotation, remaining) = u32::try_parse(remaining)?; let (button_threshold, remaining) = u32::try_parse(remaining)?; let control_id = control_id.into(); let result = DeviceAbsCalibState { control_id, len, min_x, max_x, min_y, max_y, flip_x, flip_y, rotation, button_threshold }; Ok((result, remaining)) } } impl Serialize for DeviceAbsCalibState { type Bytes = [u8; 36]; fn serialize(&self) -> [u8; 36] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let min_x_bytes = self.min_x.serialize(); let max_x_bytes = self.max_x.serialize(); let min_y_bytes = self.min_y.serialize(); let max_y_bytes = self.max_y.serialize(); let flip_x_bytes = self.flip_x.serialize(); let flip_y_bytes = self.flip_y.serialize(); let rotation_bytes = self.rotation.serialize(); let button_threshold_bytes = self.button_threshold.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], min_x_bytes[0], min_x_bytes[1], min_x_bytes[2], min_x_bytes[3], max_x_bytes[0], max_x_bytes[1], max_x_bytes[2], max_x_bytes[3], min_y_bytes[0], min_y_bytes[1], min_y_bytes[2], min_y_bytes[3], max_y_bytes[0], max_y_bytes[1], max_y_bytes[2], max_y_bytes[3], flip_x_bytes[0], flip_x_bytes[1], flip_x_bytes[2], flip_x_bytes[3], flip_y_bytes[0], flip_y_bytes[1], flip_y_bytes[2], flip_y_bytes[3], rotation_bytes[0], rotation_bytes[1], rotation_bytes[2], rotation_bytes[3], button_threshold_bytes[0], button_threshold_bytes[1], button_threshold_bytes[2], button_threshold_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(36); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.min_x.serialize_into(bytes); self.max_x.serialize_into(bytes); self.min_y.serialize_into(bytes); self.max_y.serialize_into(bytes); self.flip_x.serialize_into(bytes); self.flip_y.serialize_into(bytes); self.rotation.serialize_into(bytes); self.button_threshold.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceAbsAreaState { pub control_id: DeviceControl, pub len: u16, pub offset_x: u32, pub offset_y: u32, pub width: u32, pub height: u32, pub screen: u32, pub following: u32, } impl TryParse for DeviceAbsAreaState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (offset_x, remaining) = u32::try_parse(remaining)?; let (offset_y, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u32::try_parse(remaining)?; let (height, remaining) = u32::try_parse(remaining)?; let (screen, remaining) = u32::try_parse(remaining)?; let (following, remaining) = u32::try_parse(remaining)?; let control_id = control_id.into(); let result = DeviceAbsAreaState { control_id, len, offset_x, offset_y, width, height, screen, following }; Ok((result, remaining)) } } impl Serialize for DeviceAbsAreaState { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let offset_x_bytes = self.offset_x.serialize(); let offset_y_bytes = self.offset_y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let screen_bytes = self.screen.serialize(); let following_bytes = self.following.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], offset_x_bytes[0], offset_x_bytes[1], offset_x_bytes[2], offset_x_bytes[3], offset_y_bytes[0], offset_y_bytes[1], offset_y_bytes[2], offset_y_bytes[3], width_bytes[0], width_bytes[1], width_bytes[2], width_bytes[3], height_bytes[0], height_bytes[1], height_bytes[2], height_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], following_bytes[0], following_bytes[1], following_bytes[2], following_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.offset_x.serialize_into(bytes); self.offset_y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.screen.serialize_into(bytes); self.following.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceCoreState { pub control_id: DeviceControl, pub len: u16, pub status: u8, pub iscore: u8, } impl TryParse for DeviceCoreState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (iscore, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let control_id = control_id.into(); let result = DeviceCoreState { control_id, len, status, iscore }; Ok((result, remaining)) } } impl Serialize for DeviceCoreState { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let status_bytes = self.status.serialize(); let iscore_bytes = self.iscore.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], status_bytes[0], iscore_bytes[0], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.status.serialize_into(bytes); self.iscore.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceEnableState { pub control_id: DeviceControl, pub len: u16, pub enable: u8, } impl TryParse for DeviceEnableState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (enable, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let control_id = control_id.into(); let result = DeviceEnableState { control_id, len, enable }; Ok((result, remaining)) } } impl Serialize for DeviceEnableState { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let enable_bytes = self.enable.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], enable_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.enable.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceStateDataResolution { pub resolution_values: Vec, pub resolution_min: Vec, pub resolution_max: Vec, } impl TryParse for DeviceStateDataResolution { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_valuators, remaining) = u32::try_parse(remaining)?; let (resolution_values, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let (resolution_min, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let (resolution_max, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let result = DeviceStateDataResolution { resolution_values, resolution_min, resolution_max }; Ok((result, remaining)) } } impl Serialize for DeviceStateDataResolution { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let num_valuators = u32::try_from(self.resolution_values.len()).expect("`resolution_values` has too many elements"); num_valuators.serialize_into(bytes); self.resolution_values.serialize_into(bytes); assert_eq!(self.resolution_min.len(), usize::try_from(num_valuators).unwrap(), "`resolution_min` has an incorrect length"); self.resolution_min.serialize_into(bytes); assert_eq!(self.resolution_max.len(), usize::try_from(num_valuators).unwrap(), "`resolution_max` has an incorrect length"); self.resolution_max.serialize_into(bytes); } } impl DeviceStateDataResolution { /// Get the value of the `num_valuators` field. /// /// The `num_valuators` field is used as the length field of the `resolution_values` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_valuators(&self) -> u32 { self.resolution_values.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceStateDataAbsCalib { pub min_x: i32, pub max_x: i32, pub min_y: i32, pub max_y: i32, pub flip_x: u32, pub flip_y: u32, pub rotation: u32, pub button_threshold: u32, } impl TryParse for DeviceStateDataAbsCalib { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (min_x, remaining) = i32::try_parse(remaining)?; let (max_x, remaining) = i32::try_parse(remaining)?; let (min_y, remaining) = i32::try_parse(remaining)?; let (max_y, remaining) = i32::try_parse(remaining)?; let (flip_x, remaining) = u32::try_parse(remaining)?; let (flip_y, remaining) = u32::try_parse(remaining)?; let (rotation, remaining) = u32::try_parse(remaining)?; let (button_threshold, remaining) = u32::try_parse(remaining)?; let result = DeviceStateDataAbsCalib { min_x, max_x, min_y, max_y, flip_x, flip_y, rotation, button_threshold }; Ok((result, remaining)) } } impl Serialize for DeviceStateDataAbsCalib { type Bytes = [u8; 32]; fn serialize(&self) -> [u8; 32] { let min_x_bytes = self.min_x.serialize(); let max_x_bytes = self.max_x.serialize(); let min_y_bytes = self.min_y.serialize(); let max_y_bytes = self.max_y.serialize(); let flip_x_bytes = self.flip_x.serialize(); let flip_y_bytes = self.flip_y.serialize(); let rotation_bytes = self.rotation.serialize(); let button_threshold_bytes = self.button_threshold.serialize(); [ min_x_bytes[0], min_x_bytes[1], min_x_bytes[2], min_x_bytes[3], max_x_bytes[0], max_x_bytes[1], max_x_bytes[2], max_x_bytes[3], min_y_bytes[0], min_y_bytes[1], min_y_bytes[2], min_y_bytes[3], max_y_bytes[0], max_y_bytes[1], max_y_bytes[2], max_y_bytes[3], flip_x_bytes[0], flip_x_bytes[1], flip_x_bytes[2], flip_x_bytes[3], flip_y_bytes[0], flip_y_bytes[1], flip_y_bytes[2], flip_y_bytes[3], rotation_bytes[0], rotation_bytes[1], rotation_bytes[2], rotation_bytes[3], button_threshold_bytes[0], button_threshold_bytes[1], button_threshold_bytes[2], button_threshold_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(32); self.min_x.serialize_into(bytes); self.max_x.serialize_into(bytes); self.min_y.serialize_into(bytes); self.max_y.serialize_into(bytes); self.flip_x.serialize_into(bytes); self.flip_y.serialize_into(bytes); self.rotation.serialize_into(bytes); self.button_threshold.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceStateDataCore { pub status: u8, pub iscore: u8, } impl TryParse for DeviceStateDataCore { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (status, remaining) = u8::try_parse(remaining)?; let (iscore, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let result = DeviceStateDataCore { status, iscore }; Ok((result, remaining)) } } impl Serialize for DeviceStateDataCore { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let status_bytes = self.status.serialize(); let iscore_bytes = self.iscore.serialize(); [ status_bytes[0], iscore_bytes[0], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.status.serialize_into(bytes); self.iscore.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceStateDataAbsArea { pub offset_x: u32, pub offset_y: u32, pub width: u32, pub height: u32, pub screen: u32, pub following: u32, } impl TryParse for DeviceStateDataAbsArea { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (offset_x, remaining) = u32::try_parse(remaining)?; let (offset_y, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u32::try_parse(remaining)?; let (height, remaining) = u32::try_parse(remaining)?; let (screen, remaining) = u32::try_parse(remaining)?; let (following, remaining) = u32::try_parse(remaining)?; let result = DeviceStateDataAbsArea { offset_x, offset_y, width, height, screen, following }; Ok((result, remaining)) } } impl Serialize for DeviceStateDataAbsArea { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let offset_x_bytes = self.offset_x.serialize(); let offset_y_bytes = self.offset_y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let screen_bytes = self.screen.serialize(); let following_bytes = self.following.serialize(); [ offset_x_bytes[0], offset_x_bytes[1], offset_x_bytes[2], offset_x_bytes[3], offset_y_bytes[0], offset_y_bytes[1], offset_y_bytes[2], offset_y_bytes[3], width_bytes[0], width_bytes[1], width_bytes[2], width_bytes[3], height_bytes[0], height_bytes[1], height_bytes[2], height_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], following_bytes[0], following_bytes[1], following_bytes[2], following_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.offset_x.serialize_into(bytes); self.offset_y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.screen.serialize_into(bytes); self.following.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum DeviceStateData { Resolution(DeviceStateDataResolution), AbsCalib(DeviceStateDataAbsCalib), Core(DeviceStateDataCore), Enable(u8), AbsArea(DeviceStateDataAbsArea), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl DeviceStateData { fn try_parse(value: &[u8], control_id: u16) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(control_id); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(DeviceControl::RESOLUTION) { let (resolution, new_remaining) = DeviceStateDataResolution::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceStateData::Resolution(resolution)); } if switch_expr == u32::from(DeviceControl::ABSCALIB) { let (abs_calib, new_remaining) = DeviceStateDataAbsCalib::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceStateData::AbsCalib(abs_calib)); } if switch_expr == u32::from(DeviceControl::CORE) { let (core, new_remaining) = DeviceStateDataCore::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceStateData::Core(core)); } if switch_expr == u32::from(DeviceControl::ENABLE) { let remaining = outer_remaining; let (enable, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceStateData::Enable(enable)); } if switch_expr == u32::from(DeviceControl::ABSAREA) { let (abs_area, new_remaining) = DeviceStateDataAbsArea::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceStateData::AbsArea(abs_area)); } match parse_result { None => Ok((DeviceStateData::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl DeviceStateData { pub fn as_resolution(&self) -> Option<&DeviceStateDataResolution> { match self { DeviceStateData::Resolution(value) => Some(value), _ => None, } } pub fn as_abs_calib(&self) -> Option<&DeviceStateDataAbsCalib> { match self { DeviceStateData::AbsCalib(value) => Some(value), _ => None, } } pub fn as_core(&self) -> Option<&DeviceStateDataCore> { match self { DeviceStateData::Core(value) => Some(value), _ => None, } } pub fn as_enable(&self) -> Option<&u8> { match self { DeviceStateData::Enable(value) => Some(value), _ => None, } } pub fn as_abs_area(&self) -> Option<&DeviceStateDataAbsArea> { match self { DeviceStateData::AbsArea(value) => Some(value), _ => None, } } } impl DeviceStateData { #[allow(dead_code)] fn serialize(&self, control_id: u16) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, control_id); result } fn serialize_into(&self, bytes: &mut Vec, control_id: u16) { assert_eq!(self.switch_expr(), u32::from(control_id), "switch `data` has an inconsistent discriminant"); match self { DeviceStateData::Resolution(resolution) => resolution.serialize_into(bytes), DeviceStateData::AbsCalib(abs_calib) => abs_calib.serialize_into(bytes), DeviceStateData::Core(core) => core.serialize_into(bytes), DeviceStateData::Enable(enable) => { bytes.reserve(4); enable.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } DeviceStateData::AbsArea(abs_area) => abs_area.serialize_into(bytes), DeviceStateData::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl DeviceStateData { fn switch_expr(&self) -> u32 { match self { DeviceStateData::Resolution(_) => u32::from(DeviceControl::RESOLUTION), DeviceStateData::AbsCalib(_) => u32::from(DeviceControl::ABSCALIB), DeviceStateData::Core(_) => u32::from(DeviceControl::CORE), DeviceStateData::Enable(_) => u32::from(DeviceControl::ENABLE), DeviceStateData::AbsArea(_) => u32::from(DeviceControl::ABSAREA), DeviceStateData::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceState { pub len: u16, pub data: DeviceStateData, } impl TryParse for DeviceState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = DeviceStateData::try_parse(remaining, control_id)?; let result = DeviceState { len, data }; Ok((result, remaining)) } } impl Serialize for DeviceState { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); let control_id = u16::try_from(self.data.switch_expr()).unwrap(); control_id.serialize_into(bytes); self.len.serialize_into(bytes); self.data.serialize_into(bytes, control_id); } } /// Opcode for the GetDeviceControl request pub const GET_DEVICE_CONTROL_REQUEST: u8 = 34; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceControlRequest { pub control_id: DeviceControl, pub device_id: u8, } impl GetDeviceControlRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let control_id_bytes = u16::from(self.control_id).serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_CONTROL_REQUEST, 0, 0, control_id_bytes[0], control_id_bytes[1], device_id_bytes[0], 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_CONTROL_REQUEST { return Err(ParseError::InvalidValue); } let (control_id, remaining) = u16::try_parse(value)?; let control_id = control_id.into(); let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDeviceControlRequest { control_id, device_id, }) } } impl Request for GetDeviceControlRequest { type Reply = GetDeviceControlReply; } pub fn get_device_control(conn: &Conn, control_id: DeviceControl, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceControlRequest { control_id, device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceControlReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: u8, pub control: DeviceState, } impl TryParse for GetDeviceControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let (control, remaining) = DeviceState::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceControlReply { xi_reply_type, sequence, length, status, control }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceResolutionCtl { pub control_id: DeviceControl, pub len: u16, pub first_valuator: u8, pub resolution_values: Vec, } impl TryParse for DeviceResolutionCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (first_valuator, remaining) = u8::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (resolution_values, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let control_id = control_id.into(); let result = DeviceResolutionCtl { control_id, len, first_valuator, resolution_values }; Ok((result, remaining)) } } impl Serialize for DeviceResolutionCtl { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.first_valuator.serialize_into(bytes); let num_valuators = u8::try_from(self.resolution_values.len()).expect("`resolution_values` has too many elements"); num_valuators.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.resolution_values.serialize_into(bytes); } } impl DeviceResolutionCtl { /// Get the value of the `num_valuators` field. /// /// The `num_valuators` field is used as the length field of the `resolution_values` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_valuators(&self) -> u8 { self.resolution_values.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceAbsCalibCtl { pub control_id: DeviceControl, pub len: u16, pub min_x: i32, pub max_x: i32, pub min_y: i32, pub max_y: i32, pub flip_x: u32, pub flip_y: u32, pub rotation: u32, pub button_threshold: u32, } impl TryParse for DeviceAbsCalibCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (min_x, remaining) = i32::try_parse(remaining)?; let (max_x, remaining) = i32::try_parse(remaining)?; let (min_y, remaining) = i32::try_parse(remaining)?; let (max_y, remaining) = i32::try_parse(remaining)?; let (flip_x, remaining) = u32::try_parse(remaining)?; let (flip_y, remaining) = u32::try_parse(remaining)?; let (rotation, remaining) = u32::try_parse(remaining)?; let (button_threshold, remaining) = u32::try_parse(remaining)?; let control_id = control_id.into(); let result = DeviceAbsCalibCtl { control_id, len, min_x, max_x, min_y, max_y, flip_x, flip_y, rotation, button_threshold }; Ok((result, remaining)) } } impl Serialize for DeviceAbsCalibCtl { type Bytes = [u8; 36]; fn serialize(&self) -> [u8; 36] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let min_x_bytes = self.min_x.serialize(); let max_x_bytes = self.max_x.serialize(); let min_y_bytes = self.min_y.serialize(); let max_y_bytes = self.max_y.serialize(); let flip_x_bytes = self.flip_x.serialize(); let flip_y_bytes = self.flip_y.serialize(); let rotation_bytes = self.rotation.serialize(); let button_threshold_bytes = self.button_threshold.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], min_x_bytes[0], min_x_bytes[1], min_x_bytes[2], min_x_bytes[3], max_x_bytes[0], max_x_bytes[1], max_x_bytes[2], max_x_bytes[3], min_y_bytes[0], min_y_bytes[1], min_y_bytes[2], min_y_bytes[3], max_y_bytes[0], max_y_bytes[1], max_y_bytes[2], max_y_bytes[3], flip_x_bytes[0], flip_x_bytes[1], flip_x_bytes[2], flip_x_bytes[3], flip_y_bytes[0], flip_y_bytes[1], flip_y_bytes[2], flip_y_bytes[3], rotation_bytes[0], rotation_bytes[1], rotation_bytes[2], rotation_bytes[3], button_threshold_bytes[0], button_threshold_bytes[1], button_threshold_bytes[2], button_threshold_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(36); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.min_x.serialize_into(bytes); self.max_x.serialize_into(bytes); self.min_y.serialize_into(bytes); self.max_y.serialize_into(bytes); self.flip_x.serialize_into(bytes); self.flip_y.serialize_into(bytes); self.rotation.serialize_into(bytes); self.button_threshold.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceAbsAreaCtrl { pub control_id: DeviceControl, pub len: u16, pub offset_x: u32, pub offset_y: u32, pub width: i32, pub height: i32, pub screen: i32, pub following: u32, } impl TryParse for DeviceAbsAreaCtrl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (offset_x, remaining) = u32::try_parse(remaining)?; let (offset_y, remaining) = u32::try_parse(remaining)?; let (width, remaining) = i32::try_parse(remaining)?; let (height, remaining) = i32::try_parse(remaining)?; let (screen, remaining) = i32::try_parse(remaining)?; let (following, remaining) = u32::try_parse(remaining)?; let control_id = control_id.into(); let result = DeviceAbsAreaCtrl { control_id, len, offset_x, offset_y, width, height, screen, following }; Ok((result, remaining)) } } impl Serialize for DeviceAbsAreaCtrl { type Bytes = [u8; 28]; fn serialize(&self) -> [u8; 28] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let offset_x_bytes = self.offset_x.serialize(); let offset_y_bytes = self.offset_y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let screen_bytes = self.screen.serialize(); let following_bytes = self.following.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], offset_x_bytes[0], offset_x_bytes[1], offset_x_bytes[2], offset_x_bytes[3], offset_y_bytes[0], offset_y_bytes[1], offset_y_bytes[2], offset_y_bytes[3], width_bytes[0], width_bytes[1], width_bytes[2], width_bytes[3], height_bytes[0], height_bytes[1], height_bytes[2], height_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], following_bytes[0], following_bytes[1], following_bytes[2], following_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(28); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.offset_x.serialize_into(bytes); self.offset_y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.screen.serialize_into(bytes); self.following.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceCoreCtrl { pub control_id: DeviceControl, pub len: u16, pub status: u8, } impl TryParse for DeviceCoreCtrl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let control_id = control_id.into(); let result = DeviceCoreCtrl { control_id, len, status }; Ok((result, remaining)) } } impl Serialize for DeviceCoreCtrl { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let status_bytes = self.status.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], status_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.status.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceEnableCtrl { pub control_id: DeviceControl, pub len: u16, pub enable: u8, } impl TryParse for DeviceEnableCtrl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (enable, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let control_id = control_id.into(); let result = DeviceEnableCtrl { control_id, len, enable }; Ok((result, remaining)) } } impl Serialize for DeviceEnableCtrl { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let control_id_bytes = u16::from(self.control_id).serialize(); let len_bytes = self.len.serialize(); let enable_bytes = self.enable.serialize(); [ control_id_bytes[0], control_id_bytes[1], len_bytes[0], len_bytes[1], enable_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.control_id).serialize_into(bytes); self.len.serialize_into(bytes); self.enable.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceCtlDataResolution { pub first_valuator: u8, pub resolution_values: Vec, } impl TryParse for DeviceCtlDataResolution { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (first_valuator, remaining) = u8::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (resolution_values, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_to_usize()?)?; let result = DeviceCtlDataResolution { first_valuator, resolution_values }; Ok((result, remaining)) } } impl Serialize for DeviceCtlDataResolution { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.first_valuator.serialize_into(bytes); let num_valuators = u8::try_from(self.resolution_values.len()).expect("`resolution_values` has too many elements"); num_valuators.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.resolution_values.serialize_into(bytes); } } impl DeviceCtlDataResolution { /// Get the value of the `num_valuators` field. /// /// The `num_valuators` field is used as the length field of the `resolution_values` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_valuators(&self) -> u8 { self.resolution_values.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceCtlDataAbsCalib { pub min_x: i32, pub max_x: i32, pub min_y: i32, pub max_y: i32, pub flip_x: u32, pub flip_y: u32, pub rotation: u32, pub button_threshold: u32, } impl TryParse for DeviceCtlDataAbsCalib { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (min_x, remaining) = i32::try_parse(remaining)?; let (max_x, remaining) = i32::try_parse(remaining)?; let (min_y, remaining) = i32::try_parse(remaining)?; let (max_y, remaining) = i32::try_parse(remaining)?; let (flip_x, remaining) = u32::try_parse(remaining)?; let (flip_y, remaining) = u32::try_parse(remaining)?; let (rotation, remaining) = u32::try_parse(remaining)?; let (button_threshold, remaining) = u32::try_parse(remaining)?; let result = DeviceCtlDataAbsCalib { min_x, max_x, min_y, max_y, flip_x, flip_y, rotation, button_threshold }; Ok((result, remaining)) } } impl Serialize for DeviceCtlDataAbsCalib { type Bytes = [u8; 32]; fn serialize(&self) -> [u8; 32] { let min_x_bytes = self.min_x.serialize(); let max_x_bytes = self.max_x.serialize(); let min_y_bytes = self.min_y.serialize(); let max_y_bytes = self.max_y.serialize(); let flip_x_bytes = self.flip_x.serialize(); let flip_y_bytes = self.flip_y.serialize(); let rotation_bytes = self.rotation.serialize(); let button_threshold_bytes = self.button_threshold.serialize(); [ min_x_bytes[0], min_x_bytes[1], min_x_bytes[2], min_x_bytes[3], max_x_bytes[0], max_x_bytes[1], max_x_bytes[2], max_x_bytes[3], min_y_bytes[0], min_y_bytes[1], min_y_bytes[2], min_y_bytes[3], max_y_bytes[0], max_y_bytes[1], max_y_bytes[2], max_y_bytes[3], flip_x_bytes[0], flip_x_bytes[1], flip_x_bytes[2], flip_x_bytes[3], flip_y_bytes[0], flip_y_bytes[1], flip_y_bytes[2], flip_y_bytes[3], rotation_bytes[0], rotation_bytes[1], rotation_bytes[2], rotation_bytes[3], button_threshold_bytes[0], button_threshold_bytes[1], button_threshold_bytes[2], button_threshold_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(32); self.min_x.serialize_into(bytes); self.max_x.serialize_into(bytes); self.min_y.serialize_into(bytes); self.max_y.serialize_into(bytes); self.flip_x.serialize_into(bytes); self.flip_y.serialize_into(bytes); self.rotation.serialize_into(bytes); self.button_threshold.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceCtlDataCore { pub status: u8, } impl TryParse for DeviceCtlDataCore { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let result = DeviceCtlDataCore { status }; Ok((result, remaining)) } } impl Serialize for DeviceCtlDataCore { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let status_bytes = self.status.serialize(); [ status_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.status.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceCtlDataAbsArea { pub offset_x: u32, pub offset_y: u32, pub width: i32, pub height: i32, pub screen: i32, pub following: u32, } impl TryParse for DeviceCtlDataAbsArea { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (offset_x, remaining) = u32::try_parse(remaining)?; let (offset_y, remaining) = u32::try_parse(remaining)?; let (width, remaining) = i32::try_parse(remaining)?; let (height, remaining) = i32::try_parse(remaining)?; let (screen, remaining) = i32::try_parse(remaining)?; let (following, remaining) = u32::try_parse(remaining)?; let result = DeviceCtlDataAbsArea { offset_x, offset_y, width, height, screen, following }; Ok((result, remaining)) } } impl Serialize for DeviceCtlDataAbsArea { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let offset_x_bytes = self.offset_x.serialize(); let offset_y_bytes = self.offset_y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let screen_bytes = self.screen.serialize(); let following_bytes = self.following.serialize(); [ offset_x_bytes[0], offset_x_bytes[1], offset_x_bytes[2], offset_x_bytes[3], offset_y_bytes[0], offset_y_bytes[1], offset_y_bytes[2], offset_y_bytes[3], width_bytes[0], width_bytes[1], width_bytes[2], width_bytes[3], height_bytes[0], height_bytes[1], height_bytes[2], height_bytes[3], screen_bytes[0], screen_bytes[1], screen_bytes[2], screen_bytes[3], following_bytes[0], following_bytes[1], following_bytes[2], following_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.offset_x.serialize_into(bytes); self.offset_y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.screen.serialize_into(bytes); self.following.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum DeviceCtlData { Resolution(DeviceCtlDataResolution), AbsCalib(DeviceCtlDataAbsCalib), Core(DeviceCtlDataCore), Enable(u8), AbsArea(DeviceCtlDataAbsArea), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl DeviceCtlData { fn try_parse(value: &[u8], control_id: u16) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(control_id); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(DeviceControl::RESOLUTION) { let (resolution, new_remaining) = DeviceCtlDataResolution::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceCtlData::Resolution(resolution)); } if switch_expr == u32::from(DeviceControl::ABSCALIB) { let (abs_calib, new_remaining) = DeviceCtlDataAbsCalib::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceCtlData::AbsCalib(abs_calib)); } if switch_expr == u32::from(DeviceControl::CORE) { let (core, new_remaining) = DeviceCtlDataCore::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceCtlData::Core(core)); } if switch_expr == u32::from(DeviceControl::ENABLE) { let remaining = outer_remaining; let (enable, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceCtlData::Enable(enable)); } if switch_expr == u32::from(DeviceControl::ABSAREA) { let (abs_area, new_remaining) = DeviceCtlDataAbsArea::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceCtlData::AbsArea(abs_area)); } match parse_result { None => Ok((DeviceCtlData::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl DeviceCtlData { pub fn as_resolution(&self) -> Option<&DeviceCtlDataResolution> { match self { DeviceCtlData::Resolution(value) => Some(value), _ => None, } } pub fn as_abs_calib(&self) -> Option<&DeviceCtlDataAbsCalib> { match self { DeviceCtlData::AbsCalib(value) => Some(value), _ => None, } } pub fn as_core(&self) -> Option<&DeviceCtlDataCore> { match self { DeviceCtlData::Core(value) => Some(value), _ => None, } } pub fn as_enable(&self) -> Option<&u8> { match self { DeviceCtlData::Enable(value) => Some(value), _ => None, } } pub fn as_abs_area(&self) -> Option<&DeviceCtlDataAbsArea> { match self { DeviceCtlData::AbsArea(value) => Some(value), _ => None, } } } impl DeviceCtlData { #[allow(dead_code)] fn serialize(&self, control_id: u16) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, control_id); result } fn serialize_into(&self, bytes: &mut Vec, control_id: u16) { assert_eq!(self.switch_expr(), u32::from(control_id), "switch `data` has an inconsistent discriminant"); match self { DeviceCtlData::Resolution(resolution) => resolution.serialize_into(bytes), DeviceCtlData::AbsCalib(abs_calib) => abs_calib.serialize_into(bytes), DeviceCtlData::Core(core) => core.serialize_into(bytes), DeviceCtlData::Enable(enable) => { bytes.reserve(4); enable.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } DeviceCtlData::AbsArea(abs_area) => abs_area.serialize_into(bytes), DeviceCtlData::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl DeviceCtlData { fn switch_expr(&self) -> u32 { match self { DeviceCtlData::Resolution(_) => u32::from(DeviceControl::RESOLUTION), DeviceCtlData::AbsCalib(_) => u32::from(DeviceControl::ABSCALIB), DeviceCtlData::Core(_) => u32::from(DeviceControl::CORE), DeviceCtlData::Enable(_) => u32::from(DeviceControl::ENABLE), DeviceCtlData::AbsArea(_) => u32::from(DeviceControl::ABSAREA), DeviceCtlData::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceCtl { pub len: u16, pub data: DeviceCtlData, } impl TryParse for DeviceCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = DeviceCtlData::try_parse(remaining, control_id)?; let result = DeviceCtl { len, data }; Ok((result, remaining)) } } impl Serialize for DeviceCtl { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); let control_id = u16::try_from(self.data.switch_expr()).unwrap(); control_id.serialize_into(bytes); self.len.serialize_into(bytes); self.data.serialize_into(bytes, control_id); } } /// Opcode for the ChangeDeviceControl request pub const CHANGE_DEVICE_CONTROL_REQUEST: u8 = 35; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeDeviceControlRequest { pub control_id: DeviceControl, pub device_id: u8, pub control: DeviceCtl, } impl ChangeDeviceControlRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let control_id_bytes = u16::from(self.control_id).serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_DEVICE_CONTROL_REQUEST, 0, 0, control_id_bytes[0], control_id_bytes[1], device_id_bytes[0], 0, ]; let length_so_far = length_so_far + request0.len(); let control_bytes = self.control.serialize(); let length_so_far = length_so_far + control_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), control_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CHANGE_DEVICE_CONTROL_REQUEST { return Err(ParseError::InvalidValue); } let (control_id, remaining) = u16::try_parse(value)?; let control_id = control_id.into(); let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (control, remaining) = DeviceCtl::try_parse(remaining)?; let _ = remaining; Ok(ChangeDeviceControlRequest { control_id, device_id, control, }) } } impl Request for ChangeDeviceControlRequest { type Reply = ChangeDeviceControlReply; } pub fn change_device_control(conn: &Conn, control_id: DeviceControl, device_id: u8, control: DeviceCtl) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeDeviceControlRequest { control_id, device_id, control, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangeDeviceControlReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub status: u8, } impl TryParse for ChangeDeviceControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ChangeDeviceControlReply { xi_reply_type, sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the ListDeviceProperties request pub const LIST_DEVICE_PROPERTIES_REQUEST: u8 = 36; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListDevicePropertiesRequest { pub device_id: u8, } impl ListDevicePropertiesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_DEVICE_PROPERTIES_REQUEST, 0, 0, device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_DEVICE_PROPERTIES_REQUEST { return Err(ParseError::InvalidValue); } let (device_id, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(ListDevicePropertiesRequest { device_id, }) } } impl Request for ListDevicePropertiesRequest { type Reply = ListDevicePropertiesReply; } pub fn list_device_properties(conn: &Conn, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListDevicePropertiesRequest { device_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListDevicePropertiesReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub atoms: Vec, } impl TryParse for ListDevicePropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_atoms, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (atoms, remaining) = crate::x11_utils::parse_list::(remaining, num_atoms.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListDevicePropertiesReply { xi_reply_type, sequence, length, atoms }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListDevicePropertiesReply { /// Get the value of the `num_atoms` field. /// /// The `num_atoms` field is used as the length field of the `atoms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_atoms(&self) -> u16 { self.atoms.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PropertyFormat(u8); impl PropertyFormat { pub const M8_BITS: Self = Self(8); pub const M16_BITS: Self = Self(16); pub const M32_BITS: Self = Self(32); } impl From for u8 { #[inline] fn from(input: PropertyFormat) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PropertyFormat) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: PropertyFormat) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: PropertyFormat) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: PropertyFormat) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PropertyFormat) -> Self { Some(u32::from(input.0)) } } impl From for PropertyFormat { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for PropertyFormat { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::M8_BITS.0.into(), "M8_BITS", "M8Bits"), (Self::M16_BITS.0.into(), "M16_BITS", "M16Bits"), (Self::M32_BITS.0.into(), "M32_BITS", "M32Bits"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum ChangeDevicePropertyAux { Data8(Vec), Data16(Vec), Data32(Vec), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl ChangeDevicePropertyAux { fn try_parse(value: &[u8], format: u8, num_items: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(format); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(PropertyFormat::M8_BITS) { let remaining = outer_remaining; let value = remaining; let (data8, remaining) = crate::x11_utils::parse_u8_list(remaining, num_items.try_to_usize()?)?; let data8 = data8.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(ChangeDevicePropertyAux::Data8(data8)); } if switch_expr == u32::from(PropertyFormat::M16_BITS) { let remaining = outer_remaining; let value = remaining; let (data16, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(ChangeDevicePropertyAux::Data16(data16)); } if switch_expr == u32::from(PropertyFormat::M32_BITS) { let remaining = outer_remaining; let (data32, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(ChangeDevicePropertyAux::Data32(data32)); } match parse_result { None => Ok((ChangeDevicePropertyAux::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl ChangeDevicePropertyAux { pub fn as_data8(&self) -> Option<&Vec> { match self { ChangeDevicePropertyAux::Data8(value) => Some(value), _ => None, } } pub fn as_data16(&self) -> Option<&Vec> { match self { ChangeDevicePropertyAux::Data16(value) => Some(value), _ => None, } } pub fn as_data32(&self) -> Option<&Vec> { match self { ChangeDevicePropertyAux::Data32(value) => Some(value), _ => None, } } } impl ChangeDevicePropertyAux { #[allow(dead_code)] fn serialize(&self, format: u8, num_items: u32) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, format, num_items); result } fn serialize_into(&self, bytes: &mut Vec, format: u8, num_items: u32) { assert_eq!(self.switch_expr(), u32::from(format), "switch `items` has an inconsistent discriminant"); match self { ChangeDevicePropertyAux::Data8(data8) => { assert_eq!(data8.len(), usize::try_from(num_items).unwrap(), "`data8` has an incorrect length"); bytes.extend_from_slice(&data8); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } ChangeDevicePropertyAux::Data16(data16) => { assert_eq!(data16.len(), usize::try_from(num_items).unwrap(), "`data16` has an incorrect length"); data16.serialize_into(bytes); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } ChangeDevicePropertyAux::Data32(data32) => { assert_eq!(data32.len(), usize::try_from(num_items).unwrap(), "`data32` has an incorrect length"); data32.serialize_into(bytes); } ChangeDevicePropertyAux::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl ChangeDevicePropertyAux { fn switch_expr(&self) -> u32 { match self { ChangeDevicePropertyAux::Data8(_) => u32::from(PropertyFormat::M8_BITS), ChangeDevicePropertyAux::Data16(_) => u32::from(PropertyFormat::M16_BITS), ChangeDevicePropertyAux::Data32(_) => u32::from(PropertyFormat::M32_BITS), ChangeDevicePropertyAux::InvalidValue(switch_expr) => *switch_expr, } } } /// Opcode for the ChangeDeviceProperty request pub const CHANGE_DEVICE_PROPERTY_REQUEST: u8 = 37; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ChangeDevicePropertyRequest<'input> { pub property: xproto::Atom, pub type_: xproto::Atom, pub device_id: u8, pub mode: xproto::PropMode, pub num_items: u32, pub items: Cow<'input, ChangeDevicePropertyAux>, } impl<'input> ChangeDevicePropertyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let device_id_bytes = self.device_id.serialize(); let format = u8::try_from(self.items.switch_expr()).unwrap(); let format_bytes = format.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let num_items_bytes = self.num_items.serialize(); let mut request0 = vec![ extension_information.major_opcode, CHANGE_DEVICE_PROPERTY_REQUEST, 0, 0, property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], device_id_bytes[0], format_bytes[0], mode_bytes[0], 0, num_items_bytes[0], num_items_bytes[1], num_items_bytes[2], num_items_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let items_bytes = self.items.serialize(format, self.num_items); let length_so_far = length_so_far + items_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), items_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CHANGE_DEVICE_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (property, remaining) = xproto::Atom::try_parse(value)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (num_items, remaining) = u32::try_parse(remaining)?; let (items, remaining) = ChangeDevicePropertyAux::try_parse(remaining, format, num_items)?; let _ = remaining; Ok(ChangeDevicePropertyRequest { property, type_, device_id, mode, num_items, items: Cow::Owned(items), }) } /// Clone all borrowed data in this ChangeDevicePropertyRequest. pub fn into_owned(self) -> ChangeDevicePropertyRequest<'static> { ChangeDevicePropertyRequest { property: self.property, type_: self.type_, device_id: self.device_id, mode: self.mode, num_items: self.num_items, items: Cow::Owned(self.items.into_owned()), } } } impl<'input> Request for ChangeDevicePropertyRequest<'input> { type Reply = (); } pub fn change_device_property<'c, 'input, Conn>(conn: &'c Conn, property: xproto::Atom, type_: xproto::Atom, device_id: u8, mode: xproto::PropMode, num_items: u32, items: &'input ChangeDevicePropertyAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ChangeDevicePropertyRequest { property, type_, device_id, mode, num_items, items: Cow::Borrowed(items), }; request0.send(conn) } /// Opcode for the DeleteDeviceProperty request pub const DELETE_DEVICE_PROPERTY_REQUEST: u8 = 38; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeleteDevicePropertyRequest { pub property: xproto::Atom, pub device_id: u8, } impl DeleteDevicePropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let property_bytes = self.property.serialize(); let device_id_bytes = self.device_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, DELETE_DEVICE_PROPERTY_REQUEST, 0, 0, property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], device_id_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DELETE_DEVICE_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (property, remaining) = xproto::Atom::try_parse(value)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(DeleteDevicePropertyRequest { property, device_id, }) } } impl Request for DeleteDevicePropertyRequest { type Reply = (); } pub fn delete_device_property(conn: &Conn, property: xproto::Atom, device_id: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DeleteDevicePropertyRequest { property, device_id, }; request0.send(conn) } /// Opcode for the GetDeviceProperty request pub const GET_DEVICE_PROPERTY_REQUEST: u8 = 39; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDevicePropertyRequest { pub property: xproto::Atom, pub type_: xproto::Atom, pub offset: u32, pub len: u32, pub device_id: u8, pub delete: bool, } impl GetDevicePropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let offset_bytes = self.offset.serialize(); let len_bytes = self.len.serialize(); let device_id_bytes = self.device_id.serialize(); let delete_bytes = self.delete.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_PROPERTY_REQUEST, 0, 0, property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], offset_bytes[0], offset_bytes[1], offset_bytes[2], offset_bytes[3], len_bytes[0], len_bytes[1], len_bytes[2], len_bytes[3], device_id_bytes[0], delete_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (property, remaining) = xproto::Atom::try_parse(value)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (offset, remaining) = u32::try_parse(remaining)?; let (len, remaining) = u32::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (delete, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetDevicePropertyRequest { property, type_, offset, len, device_id, delete, }) } } impl Request for GetDevicePropertyRequest { type Reply = GetDevicePropertyReply; } pub fn get_device_property(conn: &Conn, property: xproto::Atom, type_: xproto::Atom, offset: u32, len: u32, device_id: u8, delete: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDevicePropertyRequest { property, type_, offset, len, device_id, delete, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub enum GetDevicePropertyItems { Data8(Vec), Data16(Vec), Data32(Vec), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl GetDevicePropertyItems { fn try_parse(value: &[u8], format: u8, num_items: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(format); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(PropertyFormat::M8_BITS) { let remaining = outer_remaining; let value = remaining; let (data8, remaining) = crate::x11_utils::parse_u8_list(remaining, num_items.try_to_usize()?)?; let data8 = data8.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(GetDevicePropertyItems::Data8(data8)); } if switch_expr == u32::from(PropertyFormat::M16_BITS) { let remaining = outer_remaining; let value = remaining; let (data16, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(GetDevicePropertyItems::Data16(data16)); } if switch_expr == u32::from(PropertyFormat::M32_BITS) { let remaining = outer_remaining; let (data32, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(GetDevicePropertyItems::Data32(data32)); } match parse_result { None => Ok((GetDevicePropertyItems::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl GetDevicePropertyItems { pub fn as_data8(&self) -> Option<&Vec> { match self { GetDevicePropertyItems::Data8(value) => Some(value), _ => None, } } pub fn as_data16(&self) -> Option<&Vec> { match self { GetDevicePropertyItems::Data16(value) => Some(value), _ => None, } } pub fn as_data32(&self) -> Option<&Vec> { match self { GetDevicePropertyItems::Data32(value) => Some(value), _ => None, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDevicePropertyReply { pub xi_reply_type: u8, pub sequence: u16, pub length: u32, pub type_: xproto::Atom, pub bytes_after: u32, pub num_items: u32, pub device_id: u8, pub items: GetDevicePropertyItems, } impl TryParse for GetDevicePropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (bytes_after, remaining) = u32::try_parse(remaining)?; let (num_items, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(10..).ok_or(ParseError::InsufficientData)?; let (items, remaining) = GetDevicePropertyItems::try_parse(remaining, format, num_items)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDevicePropertyReply { xi_reply_type, sequence, length, type_, bytes_after, num_items, device_id, items }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Device(bool); impl Device { pub const ALL: Self = Self(false); pub const ALL_MASTER: Self = Self(true); } impl From for bool { #[inline] fn from(input: Device) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Device) -> Self { Some(input.0) } } impl From for u8 { #[inline] fn from(input: Device) -> Self { u8::from(input.0) } } impl From for Option { #[inline] fn from(input: Device) -> Self { Some(u8::from(input.0)) } } impl From for u16 { #[inline] fn from(input: Device) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Device) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Device) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Device) -> Self { Some(u32::from(input.0)) } } impl From for Device { #[inline] fn from(value: bool) -> Self { Self(value) } } impl std::fmt::Debug for Device { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ALL.0.into(), "ALL", "All"), (Self::ALL_MASTER.0.into(), "ALL_MASTER", "AllMaster"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GroupInfo { pub base: u8, pub latched: u8, pub locked: u8, pub effective: u8, } impl TryParse for GroupInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (base, remaining) = u8::try_parse(remaining)?; let (latched, remaining) = u8::try_parse(remaining)?; let (locked, remaining) = u8::try_parse(remaining)?; let (effective, remaining) = u8::try_parse(remaining)?; let result = GroupInfo { base, latched, locked, effective }; Ok((result, remaining)) } } impl Serialize for GroupInfo { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let base_bytes = self.base.serialize(); let latched_bytes = self.latched.serialize(); let locked_bytes = self.locked.serialize(); let effective_bytes = self.effective.serialize(); [ base_bytes[0], latched_bytes[0], locked_bytes[0], effective_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.base.serialize_into(bytes); self.latched.serialize_into(bytes); self.locked.serialize_into(bytes); self.effective.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ModifierInfo { pub base: u32, pub latched: u32, pub locked: u32, pub effective: u32, } impl TryParse for ModifierInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (base, remaining) = u32::try_parse(remaining)?; let (latched, remaining) = u32::try_parse(remaining)?; let (locked, remaining) = u32::try_parse(remaining)?; let (effective, remaining) = u32::try_parse(remaining)?; let result = ModifierInfo { base, latched, locked, effective }; Ok((result, remaining)) } } impl Serialize for ModifierInfo { type Bytes = [u8; 16]; fn serialize(&self) -> [u8; 16] { let base_bytes = self.base.serialize(); let latched_bytes = self.latched.serialize(); let locked_bytes = self.locked.serialize(); let effective_bytes = self.effective.serialize(); [ base_bytes[0], base_bytes[1], base_bytes[2], base_bytes[3], latched_bytes[0], latched_bytes[1], latched_bytes[2], latched_bytes[3], locked_bytes[0], locked_bytes[1], locked_bytes[2], locked_bytes[3], effective_bytes[0], effective_bytes[1], effective_bytes[2], effective_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); self.base.serialize_into(bytes); self.latched.serialize_into(bytes); self.locked.serialize_into(bytes); self.effective.serialize_into(bytes); } } /// Opcode for the XIQueryPointer request pub const XI_QUERY_POINTER_REQUEST: u8 = 40; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIQueryPointerRequest { pub window: xproto::Window, pub deviceid: DeviceId, } impl XIQueryPointerRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_QUERY_POINTER_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_QUERY_POINTER_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XIQueryPointerRequest { window, deviceid, }) } } impl Request for XIQueryPointerRequest { type Reply = XIQueryPointerReply; } pub fn xi_query_pointer(conn: &Conn, window: xproto::Window, deviceid: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIQueryPointerRequest { window, deviceid, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIQueryPointerReply { pub sequence: u16, pub length: u32, pub root: xproto::Window, pub child: xproto::Window, pub root_x: Fp1616, pub root_y: Fp1616, pub win_x: Fp1616, pub win_y: Fp1616, pub same_screen: bool, pub mods: ModifierInfo, pub group: GroupInfo, pub buttons: Vec, } impl TryParse for XIQueryPointerReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (child, remaining) = xproto::Window::try_parse(remaining)?; let (root_x, remaining) = Fp1616::try_parse(remaining)?; let (root_y, remaining) = Fp1616::try_parse(remaining)?; let (win_x, remaining) = Fp1616::try_parse(remaining)?; let (win_y, remaining) = Fp1616::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (buttons_len, remaining) = u16::try_parse(remaining)?; let (mods, remaining) = ModifierInfo::try_parse(remaining)?; let (group, remaining) = GroupInfo::try_parse(remaining)?; let (buttons, remaining) = crate::x11_utils::parse_list::(remaining, buttons_len.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIQueryPointerReply { sequence, length, root, child, root_x, root_y, win_x, win_y, same_screen, mods, group, buttons }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl XIQueryPointerReply { /// Get the value of the `buttons_len` field. /// /// The `buttons_len` field is used as the length field of the `buttons` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn buttons_len(&self) -> u16 { self.buttons.len() .try_into().unwrap() } } /// Opcode for the XIWarpPointer request pub const XI_WARP_POINTER_REQUEST: u8 = 41; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIWarpPointerRequest { pub src_win: xproto::Window, pub dst_win: xproto::Window, pub src_x: Fp1616, pub src_y: Fp1616, pub src_width: u16, pub src_height: u16, pub dst_x: Fp1616, pub dst_y: Fp1616, pub deviceid: DeviceId, } impl XIWarpPointerRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let src_win_bytes = self.src_win.serialize(); let dst_win_bytes = self.dst_win.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let src_width_bytes = self.src_width.serialize(); let src_height_bytes = self.src_height.serialize(); let dst_x_bytes = self.dst_x.serialize(); let dst_y_bytes = self.dst_y.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_WARP_POINTER_REQUEST, 0, 0, src_win_bytes[0], src_win_bytes[1], src_win_bytes[2], src_win_bytes[3], dst_win_bytes[0], dst_win_bytes[1], dst_win_bytes[2], dst_win_bytes[3], src_x_bytes[0], src_x_bytes[1], src_x_bytes[2], src_x_bytes[3], src_y_bytes[0], src_y_bytes[1], src_y_bytes[2], src_y_bytes[3], src_width_bytes[0], src_width_bytes[1], src_height_bytes[0], src_height_bytes[1], dst_x_bytes[0], dst_x_bytes[1], dst_x_bytes[2], dst_x_bytes[3], dst_y_bytes[0], dst_y_bytes[1], dst_y_bytes[2], dst_y_bytes[3], deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_WARP_POINTER_REQUEST { return Err(ParseError::InvalidValue); } let (src_win, remaining) = xproto::Window::try_parse(value)?; let (dst_win, remaining) = xproto::Window::try_parse(remaining)?; let (src_x, remaining) = Fp1616::try_parse(remaining)?; let (src_y, remaining) = Fp1616::try_parse(remaining)?; let (src_width, remaining) = u16::try_parse(remaining)?; let (src_height, remaining) = u16::try_parse(remaining)?; let (dst_x, remaining) = Fp1616::try_parse(remaining)?; let (dst_y, remaining) = Fp1616::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XIWarpPointerRequest { src_win, dst_win, src_x, src_y, src_width, src_height, dst_x, dst_y, deviceid, }) } } impl Request for XIWarpPointerRequest { type Reply = (); } pub fn xi_warp_pointer(conn: &Conn, src_win: xproto::Window, dst_win: xproto::Window, src_x: Fp1616, src_y: Fp1616, src_width: u16, src_height: u16, dst_x: Fp1616, dst_y: Fp1616, deviceid: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIWarpPointerRequest { src_win, dst_win, src_x, src_y, src_width, src_height, dst_x, dst_y, deviceid, }; request0.send(conn) } /// Opcode for the XIChangeCursor request pub const XI_CHANGE_CURSOR_REQUEST: u8 = 42; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIChangeCursorRequest { pub window: xproto::Window, pub cursor: xproto::Cursor, pub deviceid: DeviceId, } impl XIChangeCursorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let cursor_bytes = self.cursor.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_CHANGE_CURSOR_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], cursor_bytes[0], cursor_bytes[1], cursor_bytes[2], cursor_bytes[3], deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_CHANGE_CURSOR_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XIChangeCursorRequest { window, cursor, deviceid, }) } } impl Request for XIChangeCursorRequest { type Reply = (); } pub fn xi_change_cursor(conn: &Conn, window: xproto::Window, cursor: xproto::Cursor, deviceid: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIChangeCursorRequest { window, cursor, deviceid, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct HierarchyChangeType(u16); impl HierarchyChangeType { pub const ADD_MASTER: Self = Self(1); pub const REMOVE_MASTER: Self = Self(2); pub const ATTACH_SLAVE: Self = Self(3); pub const DETACH_SLAVE: Self = Self(4); } impl From for u16 { #[inline] fn from(input: HierarchyChangeType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: HierarchyChangeType) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: HierarchyChangeType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: HierarchyChangeType) -> Self { Some(u32::from(input.0)) } } impl From for HierarchyChangeType { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for HierarchyChangeType { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for HierarchyChangeType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ADD_MASTER.0.into(), "ADD_MASTER", "AddMaster"), (Self::REMOVE_MASTER.0.into(), "REMOVE_MASTER", "RemoveMaster"), (Self::ATTACH_SLAVE.0.into(), "ATTACH_SLAVE", "AttachSlave"), (Self::DETACH_SLAVE.0.into(), "DETACH_SLAVE", "DetachSlave"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ChangeMode(u8); impl ChangeMode { pub const ATTACH: Self = Self(1); pub const FLOAT: Self = Self(2); } impl From for u8 { #[inline] fn from(input: ChangeMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ChangeMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ChangeMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ChangeMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeMode) -> Self { Some(u32::from(input.0)) } } impl From for ChangeMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ChangeMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ATTACH.0.into(), "ATTACH", "Attach"), (Self::FLOAT.0.into(), "FLOAT", "Float"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct AddMaster { pub type_: HierarchyChangeType, pub len: u16, pub send_core: bool, pub enable: bool, pub name: Vec, } impl TryParse for AddMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (name_len, remaining) = u16::try_parse(remaining)?; let (send_core, remaining) = bool::try_parse(remaining)?; let (enable, remaining) = bool::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = AddMaster { type_, len, send_core, enable, name }; Ok((result, remaining)) } } impl Serialize for AddMaster { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); let name_len = u16::try_from(self.name.len()).expect("`name` has too many elements"); name_len.serialize_into(bytes); self.send_core.serialize_into(bytes); self.enable.serialize_into(bytes); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl AddMaster { /// Get the value of the `name_len` field. /// /// The `name_len` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u16 { self.name.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct RemoveMaster { pub type_: HierarchyChangeType, pub len: u16, pub deviceid: DeviceId, pub return_mode: ChangeMode, pub return_pointer: DeviceId, pub return_keyboard: DeviceId, } impl TryParse for RemoveMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (return_mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (return_pointer, remaining) = DeviceId::try_parse(remaining)?; let (return_keyboard, remaining) = DeviceId::try_parse(remaining)?; let type_ = type_.into(); let return_mode = return_mode.into(); let result = RemoveMaster { type_, len, deviceid, return_mode, return_pointer, return_keyboard }; Ok((result, remaining)) } } impl Serialize for RemoveMaster { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let type_bytes = u16::from(self.type_).serialize(); let len_bytes = self.len.serialize(); let deviceid_bytes = self.deviceid.serialize(); let return_mode_bytes = u8::from(self.return_mode).serialize(); let return_pointer_bytes = self.return_pointer.serialize(); let return_keyboard_bytes = self.return_keyboard.serialize(); [ type_bytes[0], type_bytes[1], len_bytes[0], len_bytes[1], deviceid_bytes[0], deviceid_bytes[1], return_mode_bytes[0], 0, return_pointer_bytes[0], return_pointer_bytes[1], return_keyboard_bytes[0], return_keyboard_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.deviceid.serialize_into(bytes); u8::from(self.return_mode).serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.return_pointer.serialize_into(bytes); self.return_keyboard.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AttachSlave { pub type_: HierarchyChangeType, pub len: u16, pub deviceid: DeviceId, pub master: DeviceId, } impl TryParse for AttachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (master, remaining) = DeviceId::try_parse(remaining)?; let type_ = type_.into(); let result = AttachSlave { type_, len, deviceid, master }; Ok((result, remaining)) } } impl Serialize for AttachSlave { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u16::from(self.type_).serialize(); let len_bytes = self.len.serialize(); let deviceid_bytes = self.deviceid.serialize(); let master_bytes = self.master.serialize(); [ type_bytes[0], type_bytes[1], len_bytes[0], len_bytes[1], deviceid_bytes[0], deviceid_bytes[1], master_bytes[0], master_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.deviceid.serialize_into(bytes); self.master.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DetachSlave { pub type_: HierarchyChangeType, pub len: u16, pub deviceid: DeviceId, } impl TryParse for DetachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = DetachSlave { type_, len, deviceid }; Ok((result, remaining)) } } impl Serialize for DetachSlave { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u16::from(self.type_).serialize(); let len_bytes = self.len.serialize(); let deviceid_bytes = self.deviceid.serialize(); [ type_bytes[0], type_bytes[1], len_bytes[0], len_bytes[1], deviceid_bytes[0], deviceid_bytes[1], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.deviceid.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct HierarchyChangeDataAddMaster { pub send_core: bool, pub enable: bool, pub name: Vec, } impl TryParse for HierarchyChangeDataAddMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (name_len, remaining) = u16::try_parse(remaining)?; let (send_core, remaining) = bool::try_parse(remaining)?; let (enable, remaining) = bool::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = HierarchyChangeDataAddMaster { send_core, enable, name }; Ok((result, remaining)) } } impl Serialize for HierarchyChangeDataAddMaster { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); let name_len = u16::try_from(self.name.len()).expect("`name` has too many elements"); name_len.serialize_into(bytes); self.send_core.serialize_into(bytes); self.enable.serialize_into(bytes); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl HierarchyChangeDataAddMaster { /// Get the value of the `name_len` field. /// /// The `name_len` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u16 { self.name.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct HierarchyChangeDataRemoveMaster { pub deviceid: DeviceId, pub return_mode: ChangeMode, pub return_pointer: DeviceId, pub return_keyboard: DeviceId, } impl TryParse for HierarchyChangeDataRemoveMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (return_mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (return_pointer, remaining) = DeviceId::try_parse(remaining)?; let (return_keyboard, remaining) = DeviceId::try_parse(remaining)?; let return_mode = return_mode.into(); let result = HierarchyChangeDataRemoveMaster { deviceid, return_mode, return_pointer, return_keyboard }; Ok((result, remaining)) } } impl Serialize for HierarchyChangeDataRemoveMaster { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let deviceid_bytes = self.deviceid.serialize(); let return_mode_bytes = u8::from(self.return_mode).serialize(); let return_pointer_bytes = self.return_pointer.serialize(); let return_keyboard_bytes = self.return_keyboard.serialize(); [ deviceid_bytes[0], deviceid_bytes[1], return_mode_bytes[0], 0, return_pointer_bytes[0], return_pointer_bytes[1], return_keyboard_bytes[0], return_keyboard_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.deviceid.serialize_into(bytes); u8::from(self.return_mode).serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.return_pointer.serialize_into(bytes); self.return_keyboard.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct HierarchyChangeDataAttachSlave { pub deviceid: DeviceId, pub master: DeviceId, } impl TryParse for HierarchyChangeDataAttachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (master, remaining) = DeviceId::try_parse(remaining)?; let result = HierarchyChangeDataAttachSlave { deviceid, master }; Ok((result, remaining)) } } impl Serialize for HierarchyChangeDataAttachSlave { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let deviceid_bytes = self.deviceid.serialize(); let master_bytes = self.master.serialize(); [ deviceid_bytes[0], deviceid_bytes[1], master_bytes[0], master_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.deviceid.serialize_into(bytes); self.master.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct HierarchyChangeDataDetachSlave { pub deviceid: DeviceId, } impl TryParse for HierarchyChangeDataDetachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let result = HierarchyChangeDataDetachSlave { deviceid }; Ok((result, remaining)) } } impl Serialize for HierarchyChangeDataDetachSlave { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let deviceid_bytes = self.deviceid.serialize(); [ deviceid_bytes[0], deviceid_bytes[1], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.deviceid.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum HierarchyChangeData { AddMaster(HierarchyChangeDataAddMaster), RemoveMaster(HierarchyChangeDataRemoveMaster), AttachSlave(HierarchyChangeDataAttachSlave), DetachSlave(HierarchyChangeDataDetachSlave), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl HierarchyChangeData { fn try_parse(value: &[u8], type_: u16) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(type_); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(HierarchyChangeType::ADD_MASTER) { let (add_master, new_remaining) = HierarchyChangeDataAddMaster::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(HierarchyChangeData::AddMaster(add_master)); } if switch_expr == u32::from(HierarchyChangeType::REMOVE_MASTER) { let (remove_master, new_remaining) = HierarchyChangeDataRemoveMaster::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(HierarchyChangeData::RemoveMaster(remove_master)); } if switch_expr == u32::from(HierarchyChangeType::ATTACH_SLAVE) { let (attach_slave, new_remaining) = HierarchyChangeDataAttachSlave::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(HierarchyChangeData::AttachSlave(attach_slave)); } if switch_expr == u32::from(HierarchyChangeType::DETACH_SLAVE) { let (detach_slave, new_remaining) = HierarchyChangeDataDetachSlave::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(HierarchyChangeData::DetachSlave(detach_slave)); } match parse_result { None => Ok((HierarchyChangeData::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl HierarchyChangeData { pub fn as_add_master(&self) -> Option<&HierarchyChangeDataAddMaster> { match self { HierarchyChangeData::AddMaster(value) => Some(value), _ => None, } } pub fn as_remove_master(&self) -> Option<&HierarchyChangeDataRemoveMaster> { match self { HierarchyChangeData::RemoveMaster(value) => Some(value), _ => None, } } pub fn as_attach_slave(&self) -> Option<&HierarchyChangeDataAttachSlave> { match self { HierarchyChangeData::AttachSlave(value) => Some(value), _ => None, } } pub fn as_detach_slave(&self) -> Option<&HierarchyChangeDataDetachSlave> { match self { HierarchyChangeData::DetachSlave(value) => Some(value), _ => None, } } } impl HierarchyChangeData { #[allow(dead_code)] fn serialize(&self, type_: u16) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, type_); result } fn serialize_into(&self, bytes: &mut Vec, type_: u16) { assert_eq!(self.switch_expr(), u32::from(type_), "switch `data` has an inconsistent discriminant"); match self { HierarchyChangeData::AddMaster(add_master) => add_master.serialize_into(bytes), HierarchyChangeData::RemoveMaster(remove_master) => remove_master.serialize_into(bytes), HierarchyChangeData::AttachSlave(attach_slave) => attach_slave.serialize_into(bytes), HierarchyChangeData::DetachSlave(detach_slave) => detach_slave.serialize_into(bytes), HierarchyChangeData::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl HierarchyChangeData { fn switch_expr(&self) -> u32 { match self { HierarchyChangeData::AddMaster(_) => u32::from(HierarchyChangeType::ADD_MASTER), HierarchyChangeData::RemoveMaster(_) => u32::from(HierarchyChangeType::REMOVE_MASTER), HierarchyChangeData::AttachSlave(_) => u32::from(HierarchyChangeType::ATTACH_SLAVE), HierarchyChangeData::DetachSlave(_) => u32::from(HierarchyChangeType::DETACH_SLAVE), HierarchyChangeData::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct HierarchyChange { pub len: u16, pub data: HierarchyChangeData, } impl TryParse for HierarchyChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = HierarchyChangeData::try_parse(remaining, type_)?; let result = HierarchyChange { len, data }; Ok((result, remaining)) } } impl Serialize for HierarchyChange { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); let type_ = u16::try_from(self.data.switch_expr()).unwrap(); type_.serialize_into(bytes); self.len.serialize_into(bytes); self.data.serialize_into(bytes, type_); } } /// Opcode for the XIChangeHierarchy request pub const XI_CHANGE_HIERARCHY_REQUEST: u8 = 43; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIChangeHierarchyRequest<'input> { pub changes: Cow<'input, [HierarchyChange]>, } impl<'input> XIChangeHierarchyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let num_changes = u8::try_from(self.changes.len()).expect("`changes` has too many elements"); let num_changes_bytes = num_changes.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_CHANGE_HIERARCHY_REQUEST, 0, 0, num_changes_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); let changes_bytes = self.changes.serialize(); let length_so_far = length_so_far + changes_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), changes_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != XI_CHANGE_HIERARCHY_REQUEST { return Err(ParseError::InvalidValue); } let (num_changes, remaining) = u8::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (changes, remaining) = crate::x11_utils::parse_list::(remaining, num_changes.try_to_usize()?)?; let _ = remaining; Ok(XIChangeHierarchyRequest { changes: Cow::Owned(changes), }) } /// Clone all borrowed data in this XIChangeHierarchyRequest. pub fn into_owned(self) -> XIChangeHierarchyRequest<'static> { XIChangeHierarchyRequest { changes: Cow::Owned(self.changes.into_owned()), } } } impl<'input> Request for XIChangeHierarchyRequest<'input> { type Reply = (); } pub fn xi_change_hierarchy<'c, 'input, Conn>(conn: &'c Conn, changes: &'input [HierarchyChange]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = XIChangeHierarchyRequest { changes: Cow::Borrowed(changes), }; request0.send(conn) } /// Opcode for the XISetClientPointer request pub const XI_SET_CLIENT_POINTER_REQUEST: u8 = 44; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XISetClientPointerRequest { pub window: xproto::Window, pub deviceid: DeviceId, } impl XISetClientPointerRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_SET_CLIENT_POINTER_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_SET_CLIENT_POINTER_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XISetClientPointerRequest { window, deviceid, }) } } impl Request for XISetClientPointerRequest { type Reply = (); } pub fn xi_set_client_pointer(conn: &Conn, window: xproto::Window, deviceid: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XISetClientPointerRequest { window, deviceid, }; request0.send(conn) } /// Opcode for the XIGetClientPointer request pub const XI_GET_CLIENT_POINTER_REQUEST: u8 = 45; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIGetClientPointerRequest { pub window: xproto::Window, } impl XIGetClientPointerRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_GET_CLIENT_POINTER_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_GET_CLIENT_POINTER_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(XIGetClientPointerRequest { window, }) } } impl Request for XIGetClientPointerRequest { type Reply = XIGetClientPointerReply; } pub fn xi_get_client_pointer(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = XIGetClientPointerRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIGetClientPointerReply { pub sequence: u16, pub length: u32, pub set: bool, pub deviceid: DeviceId, } impl TryParse for XIGetClientPointerReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (set, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIGetClientPointerReply { sequence, length, set, deviceid }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct XIEventMask(u32); impl XIEventMask { pub const DEVICE_CHANGED: Self = Self(1 << 1); pub const KEY_PRESS: Self = Self(1 << 2); pub const KEY_RELEASE: Self = Self(1 << 3); pub const BUTTON_PRESS: Self = Self(1 << 4); pub const BUTTON_RELEASE: Self = Self(1 << 5); pub const MOTION: Self = Self(1 << 6); pub const ENTER: Self = Self(1 << 7); pub const LEAVE: Self = Self(1 << 8); pub const FOCUS_IN: Self = Self(1 << 9); pub const FOCUS_OUT: Self = Self(1 << 10); pub const HIERARCHY: Self = Self(1 << 11); pub const PROPERTY: Self = Self(1 << 12); pub const RAW_KEY_PRESS: Self = Self(1 << 13); pub const RAW_KEY_RELEASE: Self = Self(1 << 14); pub const RAW_BUTTON_PRESS: Self = Self(1 << 15); pub const RAW_BUTTON_RELEASE: Self = Self(1 << 16); pub const RAW_MOTION: Self = Self(1 << 17); pub const TOUCH_BEGIN: Self = Self(1 << 18); pub const TOUCH_UPDATE: Self = Self(1 << 19); pub const TOUCH_END: Self = Self(1 << 20); pub const TOUCH_OWNERSHIP: Self = Self(1 << 21); pub const RAW_TOUCH_BEGIN: Self = Self(1 << 22); pub const RAW_TOUCH_UPDATE: Self = Self(1 << 23); pub const RAW_TOUCH_END: Self = Self(1 << 24); pub const BARRIER_HIT: Self = Self(1 << 25); pub const BARRIER_LEAVE: Self = Self(1 << 26); } impl From for u32 { #[inline] fn from(input: XIEventMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: XIEventMask) -> Self { Some(input.0) } } impl From for XIEventMask { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for XIEventMask { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for XIEventMask { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for XIEventMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DEVICE_CHANGED.0, "DEVICE_CHANGED", "DeviceChanged"), (Self::KEY_PRESS.0, "KEY_PRESS", "KeyPress"), (Self::KEY_RELEASE.0, "KEY_RELEASE", "KeyRelease"), (Self::BUTTON_PRESS.0, "BUTTON_PRESS", "ButtonPress"), (Self::BUTTON_RELEASE.0, "BUTTON_RELEASE", "ButtonRelease"), (Self::MOTION.0, "MOTION", "Motion"), (Self::ENTER.0, "ENTER", "Enter"), (Self::LEAVE.0, "LEAVE", "Leave"), (Self::FOCUS_IN.0, "FOCUS_IN", "FocusIn"), (Self::FOCUS_OUT.0, "FOCUS_OUT", "FocusOut"), (Self::HIERARCHY.0, "HIERARCHY", "Hierarchy"), (Self::PROPERTY.0, "PROPERTY", "Property"), (Self::RAW_KEY_PRESS.0, "RAW_KEY_PRESS", "RawKeyPress"), (Self::RAW_KEY_RELEASE.0, "RAW_KEY_RELEASE", "RawKeyRelease"), (Self::RAW_BUTTON_PRESS.0, "RAW_BUTTON_PRESS", "RawButtonPress"), (Self::RAW_BUTTON_RELEASE.0, "RAW_BUTTON_RELEASE", "RawButtonRelease"), (Self::RAW_MOTION.0, "RAW_MOTION", "RawMotion"), (Self::TOUCH_BEGIN.0, "TOUCH_BEGIN", "TouchBegin"), (Self::TOUCH_UPDATE.0, "TOUCH_UPDATE", "TouchUpdate"), (Self::TOUCH_END.0, "TOUCH_END", "TouchEnd"), (Self::TOUCH_OWNERSHIP.0, "TOUCH_OWNERSHIP", "TouchOwnership"), (Self::RAW_TOUCH_BEGIN.0, "RAW_TOUCH_BEGIN", "RawTouchBegin"), (Self::RAW_TOUCH_UPDATE.0, "RAW_TOUCH_UPDATE", "RawTouchUpdate"), (Self::RAW_TOUCH_END.0, "RAW_TOUCH_END", "RawTouchEnd"), (Self::BARRIER_HIT.0, "BARRIER_HIT", "BarrierHit"), (Self::BARRIER_LEAVE.0, "BARRIER_LEAVE", "BarrierLeave"), ]; pretty_print_bitmask(fmt, self.0, &variants) } } bitmask_binop!(XIEventMask, u32); #[derive(Debug, Clone, PartialEq, Eq)] pub struct EventMask { pub deviceid: DeviceId, pub mask: Vec, } impl TryParse for EventMask { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (mask_len, remaining) = u16::try_parse(remaining)?; let (mask, remaining) = crate::x11_utils::parse_list::(remaining, mask_len.try_to_usize()?)?; let result = EventMask { deviceid, mask }; Ok((result, remaining)) } } impl Serialize for EventMask { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.deviceid.serialize_into(bytes); let mask_len = u16::try_from(self.mask.len()).expect("`mask` has too many elements"); mask_len.serialize_into(bytes); self.mask.serialize_into(bytes); } } impl EventMask { /// Get the value of the `mask_len` field. /// /// The `mask_len` field is used as the length field of the `mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn mask_len(&self) -> u16 { self.mask.len() .try_into().unwrap() } } /// Opcode for the XISelectEvents request pub const XI_SELECT_EVENTS_REQUEST: u8 = 46; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XISelectEventsRequest<'input> { pub window: xproto::Window, pub masks: Cow<'input, [EventMask]>, } impl<'input> XISelectEventsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let num_mask = u16::try_from(self.masks.len()).expect("`masks` has too many elements"); let num_mask_bytes = num_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_SELECT_EVENTS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], num_mask_bytes[0], num_mask_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let masks_bytes = self.masks.serialize(); let length_so_far = length_so_far + masks_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), masks_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != XI_SELECT_EVENTS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (num_mask, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (masks, remaining) = crate::x11_utils::parse_list::(remaining, num_mask.try_to_usize()?)?; let _ = remaining; Ok(XISelectEventsRequest { window, masks: Cow::Owned(masks), }) } /// Clone all borrowed data in this XISelectEventsRequest. pub fn into_owned(self) -> XISelectEventsRequest<'static> { XISelectEventsRequest { window: self.window, masks: Cow::Owned(self.masks.into_owned()), } } } impl<'input> Request for XISelectEventsRequest<'input> { type Reply = (); } pub fn xi_select_events<'c, 'input, Conn>(conn: &'c Conn, window: xproto::Window, masks: &'input [EventMask]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = XISelectEventsRequest { window, masks: Cow::Borrowed(masks), }; request0.send(conn) } /// Opcode for the XIQueryVersion request pub const XI_QUERY_VERSION_REQUEST: u8 = 47; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIQueryVersionRequest { pub major_version: u16, pub minor_version: u16, } impl XIQueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_QUERY_VERSION_REQUEST, 0, 0, major_version_bytes[0], major_version_bytes[1], minor_version_bytes[0], minor_version_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u16::try_parse(value)?; let (minor_version, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(XIQueryVersionRequest { major_version, minor_version, }) } } impl Request for XIQueryVersionRequest { type Reply = XIQueryVersionReply; } pub fn xi_query_version(conn: &Conn, major_version: u16, minor_version: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = XIQueryVersionRequest { major_version, minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIQueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u16, pub minor_version: u16, } impl TryParse for XIQueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u16::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIQueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DeviceClassType(u16); impl DeviceClassType { pub const KEY: Self = Self(0); pub const BUTTON: Self = Self(1); pub const VALUATOR: Self = Self(2); pub const SCROLL: Self = Self(3); pub const TOUCH: Self = Self(8); } impl From for u16 { #[inline] fn from(input: DeviceClassType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DeviceClassType) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: DeviceClassType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceClassType) -> Self { Some(u32::from(input.0)) } } impl From for DeviceClassType { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for DeviceClassType { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for DeviceClassType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEY.0.into(), "KEY", "Key"), (Self::BUTTON.0.into(), "BUTTON", "Button"), (Self::VALUATOR.0.into(), "VALUATOR", "Valuator"), (Self::SCROLL.0.into(), "SCROLL", "Scroll"), (Self::TOUCH.0.into(), "TOUCH", "Touch"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DeviceType(u16); impl DeviceType { pub const MASTER_POINTER: Self = Self(1); pub const MASTER_KEYBOARD: Self = Self(2); pub const SLAVE_POINTER: Self = Self(3); pub const SLAVE_KEYBOARD: Self = Self(4); pub const FLOATING_SLAVE: Self = Self(5); } impl From for u16 { #[inline] fn from(input: DeviceType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DeviceType) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: DeviceType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceType) -> Self { Some(u32::from(input.0)) } } impl From for DeviceType { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for DeviceType { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for DeviceType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::MASTER_POINTER.0.into(), "MASTER_POINTER", "MasterPointer"), (Self::MASTER_KEYBOARD.0.into(), "MASTER_KEYBOARD", "MasterKeyboard"), (Self::SLAVE_POINTER.0.into(), "SLAVE_POINTER", "SlavePointer"), (Self::SLAVE_KEYBOARD.0.into(), "SLAVE_KEYBOARD", "SlaveKeyboard"), (Self::FLOATING_SLAVE.0.into(), "FLOATING_SLAVE", "FloatingSlave"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ScrollFlags(u8); impl ScrollFlags { pub const NO_EMULATION: Self = Self(1 << 0); pub const PREFERRED: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: ScrollFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ScrollFlags) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ScrollFlags) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ScrollFlags) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ScrollFlags) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ScrollFlags) -> Self { Some(u32::from(input.0)) } } impl From for ScrollFlags { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ScrollFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_EMULATION.0.into(), "NO_EMULATION", "NoEmulation"), (Self::PREFERRED.0.into(), "PREFERRED", "Preferred"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ScrollFlags, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct ScrollType(u16); impl ScrollType { pub const VERTICAL: Self = Self(1); pub const HORIZONTAL: Self = Self(2); } impl From for u16 { #[inline] fn from(input: ScrollType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ScrollType) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: ScrollType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ScrollType) -> Self { Some(u32::from(input.0)) } } impl From for ScrollType { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for ScrollType { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for ScrollType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::VERTICAL.0.into(), "VERTICAL", "Vertical"), (Self::HORIZONTAL.0.into(), "HORIZONTAL", "Horizontal"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct TouchMode(u8); impl TouchMode { pub const DIRECT: Self = Self(1); pub const DEPENDENT: Self = Self(2); } impl From for u8 { #[inline] fn from(input: TouchMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: TouchMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: TouchMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: TouchMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: TouchMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: TouchMode) -> Self { Some(u32::from(input.0)) } } impl From for TouchMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for TouchMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DIRECT.0.into(), "DIRECT", "Direct"), (Self::DEPENDENT.0.into(), "DEPENDENT", "Dependent"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ButtonClass { pub type_: DeviceClassType, pub len: u16, pub sourceid: DeviceId, pub state: Vec, pub labels: Vec, } impl TryParse for ButtonClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (num_buttons, remaining) = u16::try_parse(remaining)?; let (state, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(num_buttons).checked_add(31u32).ok_or(ParseError::InvalidExpression)?.checked_div(32u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let (labels, remaining) = crate::x11_utils::parse_list::(remaining, num_buttons.try_to_usize()?)?; let type_ = type_.into(); let result = ButtonClass { type_, len, sourceid, state, labels }; Ok((result, remaining)) } } impl Serialize for ButtonClass { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.sourceid.serialize_into(bytes); let num_buttons = u16::try_from(self.labels.len()).expect("`labels` has too many elements"); num_buttons.serialize_into(bytes); assert_eq!(self.state.len(), usize::try_from(u32::from(num_buttons).checked_add(31u32).unwrap().checked_div(32u32).unwrap()).unwrap(), "`state` has an incorrect length"); self.state.serialize_into(bytes); self.labels.serialize_into(bytes); } } impl ButtonClass { /// Get the value of the `num_buttons` field. /// /// The `num_buttons` field is used as the length field of the `labels` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_buttons(&self) -> u16 { self.labels.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct KeyClass { pub type_: DeviceClassType, pub len: u16, pub sourceid: DeviceId, pub keys: Vec, } impl TryParse for KeyClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (num_keys, remaining) = u16::try_parse(remaining)?; let (keys, remaining) = crate::x11_utils::parse_list::(remaining, num_keys.try_to_usize()?)?; let type_ = type_.into(); let result = KeyClass { type_, len, sourceid, keys }; Ok((result, remaining)) } } impl Serialize for KeyClass { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.sourceid.serialize_into(bytes); let num_keys = u16::try_from(self.keys.len()).expect("`keys` has too many elements"); num_keys.serialize_into(bytes); self.keys.serialize_into(bytes); } } impl KeyClass { /// Get the value of the `num_keys` field. /// /// The `num_keys` field is used as the length field of the `keys` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_keys(&self) -> u16 { self.keys.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ScrollClass { pub type_: DeviceClassType, pub len: u16, pub sourceid: DeviceId, pub number: u16, pub scroll_type: ScrollType, pub flags: u32, pub increment: Fp3232, } impl TryParse for ScrollClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (number, remaining) = u16::try_parse(remaining)?; let (scroll_type, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let (increment, remaining) = Fp3232::try_parse(remaining)?; let type_ = type_.into(); let scroll_type = scroll_type.into(); let result = ScrollClass { type_, len, sourceid, number, scroll_type, flags, increment }; Ok((result, remaining)) } } impl Serialize for ScrollClass { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let type_bytes = u16::from(self.type_).serialize(); let len_bytes = self.len.serialize(); let sourceid_bytes = self.sourceid.serialize(); let number_bytes = self.number.serialize(); let scroll_type_bytes = u16::from(self.scroll_type).serialize(); let flags_bytes = self.flags.serialize(); let increment_bytes = self.increment.serialize(); [ type_bytes[0], type_bytes[1], len_bytes[0], len_bytes[1], sourceid_bytes[0], sourceid_bytes[1], number_bytes[0], number_bytes[1], scroll_type_bytes[0], scroll_type_bytes[1], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], increment_bytes[0], increment_bytes[1], increment_bytes[2], increment_bytes[3], increment_bytes[4], increment_bytes[5], increment_bytes[6], increment_bytes[7], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.sourceid.serialize_into(bytes); self.number.serialize_into(bytes); u16::from(self.scroll_type).serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.flags.serialize_into(bytes); self.increment.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct TouchClass { pub type_: DeviceClassType, pub len: u16, pub sourceid: DeviceId, pub mode: TouchMode, pub num_touches: u8, } impl TryParse for TouchClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (num_touches, remaining) = u8::try_parse(remaining)?; let type_ = type_.into(); let mode = mode.into(); let result = TouchClass { type_, len, sourceid, mode, num_touches }; Ok((result, remaining)) } } impl Serialize for TouchClass { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u16::from(self.type_).serialize(); let len_bytes = self.len.serialize(); let sourceid_bytes = self.sourceid.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let num_touches_bytes = self.num_touches.serialize(); [ type_bytes[0], type_bytes[1], len_bytes[0], len_bytes[1], sourceid_bytes[0], sourceid_bytes[1], mode_bytes[0], num_touches_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.sourceid.serialize_into(bytes); u8::from(self.mode).serialize_into(bytes); self.num_touches.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ValuatorClass { pub type_: DeviceClassType, pub len: u16, pub sourceid: DeviceId, pub number: u16, pub label: xproto::Atom, pub min: Fp3232, pub max: Fp3232, pub value: Fp3232, pub resolution: u32, pub mode: ValuatorMode, } impl TryParse for ValuatorClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (number, remaining) = u16::try_parse(remaining)?; let (label, remaining) = xproto::Atom::try_parse(remaining)?; let (min, remaining) = Fp3232::try_parse(remaining)?; let (max, remaining) = Fp3232::try_parse(remaining)?; let (value, remaining) = Fp3232::try_parse(remaining)?; let (resolution, remaining) = u32::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let mode = mode.into(); let result = ValuatorClass { type_, len, sourceid, number, label, min, max, value, resolution, mode }; Ok((result, remaining)) } } impl Serialize for ValuatorClass { type Bytes = [u8; 44]; fn serialize(&self) -> [u8; 44] { let type_bytes = u16::from(self.type_).serialize(); let len_bytes = self.len.serialize(); let sourceid_bytes = self.sourceid.serialize(); let number_bytes = self.number.serialize(); let label_bytes = self.label.serialize(); let min_bytes = self.min.serialize(); let max_bytes = self.max.serialize(); let value_bytes = self.value.serialize(); let resolution_bytes = self.resolution.serialize(); let mode_bytes = u8::from(self.mode).serialize(); [ type_bytes[0], type_bytes[1], len_bytes[0], len_bytes[1], sourceid_bytes[0], sourceid_bytes[1], number_bytes[0], number_bytes[1], label_bytes[0], label_bytes[1], label_bytes[2], label_bytes[3], min_bytes[0], min_bytes[1], min_bytes[2], min_bytes[3], min_bytes[4], min_bytes[5], min_bytes[6], min_bytes[7], max_bytes[0], max_bytes[1], max_bytes[2], max_bytes[3], max_bytes[4], max_bytes[5], max_bytes[6], max_bytes[7], value_bytes[0], value_bytes[1], value_bytes[2], value_bytes[3], value_bytes[4], value_bytes[5], value_bytes[6], value_bytes[7], resolution_bytes[0], resolution_bytes[1], resolution_bytes[2], resolution_bytes[3], mode_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(44); u16::from(self.type_).serialize_into(bytes); self.len.serialize_into(bytes); self.sourceid.serialize_into(bytes); self.number.serialize_into(bytes); self.label.serialize_into(bytes); self.min.serialize_into(bytes); self.max.serialize_into(bytes); self.value.serialize_into(bytes); self.resolution.serialize_into(bytes); u8::from(self.mode).serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceClassDataKey { pub keys: Vec, } impl TryParse for DeviceClassDataKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_keys, remaining) = u16::try_parse(remaining)?; let (keys, remaining) = crate::x11_utils::parse_list::(remaining, num_keys.try_to_usize()?)?; let result = DeviceClassDataKey { keys }; Ok((result, remaining)) } } impl Serialize for DeviceClassDataKey { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let num_keys = u16::try_from(self.keys.len()).expect("`keys` has too many elements"); num_keys.serialize_into(bytes); self.keys.serialize_into(bytes); } } impl DeviceClassDataKey { /// Get the value of the `num_keys` field. /// /// The `num_keys` field is used as the length field of the `keys` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_keys(&self) -> u16 { self.keys.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceClassDataButton { pub state: Vec, pub labels: Vec, } impl TryParse for DeviceClassDataButton { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (num_buttons, remaining) = u16::try_parse(remaining)?; let (state, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(num_buttons).checked_add(31u32).ok_or(ParseError::InvalidExpression)?.checked_div(32u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let (labels, remaining) = crate::x11_utils::parse_list::(remaining, num_buttons.try_to_usize()?)?; let result = DeviceClassDataButton { state, labels }; Ok((result, remaining)) } } impl Serialize for DeviceClassDataButton { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let num_buttons = u16::try_from(self.labels.len()).expect("`labels` has too many elements"); num_buttons.serialize_into(bytes); assert_eq!(self.state.len(), usize::try_from(u32::from(num_buttons).checked_add(31u32).unwrap().checked_div(32u32).unwrap()).unwrap(), "`state` has an incorrect length"); self.state.serialize_into(bytes); self.labels.serialize_into(bytes); } } impl DeviceClassDataButton { /// Get the value of the `num_buttons` field. /// /// The `num_buttons` field is used as the length field of the `labels` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_buttons(&self) -> u16 { self.labels.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceClassDataValuator { pub number: u16, pub label: xproto::Atom, pub min: Fp3232, pub max: Fp3232, pub value: Fp3232, pub resolution: u32, pub mode: ValuatorMode, } impl TryParse for DeviceClassDataValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (number, remaining) = u16::try_parse(remaining)?; let (label, remaining) = xproto::Atom::try_parse(remaining)?; let (min, remaining) = Fp3232::try_parse(remaining)?; let (max, remaining) = Fp3232::try_parse(remaining)?; let (value, remaining) = Fp3232::try_parse(remaining)?; let (resolution, remaining) = u32::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let mode = mode.into(); let result = DeviceClassDataValuator { number, label, min, max, value, resolution, mode }; Ok((result, remaining)) } } impl Serialize for DeviceClassDataValuator { type Bytes = [u8; 38]; fn serialize(&self) -> [u8; 38] { let number_bytes = self.number.serialize(); let label_bytes = self.label.serialize(); let min_bytes = self.min.serialize(); let max_bytes = self.max.serialize(); let value_bytes = self.value.serialize(); let resolution_bytes = self.resolution.serialize(); let mode_bytes = u8::from(self.mode).serialize(); [ number_bytes[0], number_bytes[1], label_bytes[0], label_bytes[1], label_bytes[2], label_bytes[3], min_bytes[0], min_bytes[1], min_bytes[2], min_bytes[3], min_bytes[4], min_bytes[5], min_bytes[6], min_bytes[7], max_bytes[0], max_bytes[1], max_bytes[2], max_bytes[3], max_bytes[4], max_bytes[5], max_bytes[6], max_bytes[7], value_bytes[0], value_bytes[1], value_bytes[2], value_bytes[3], value_bytes[4], value_bytes[5], value_bytes[6], value_bytes[7], resolution_bytes[0], resolution_bytes[1], resolution_bytes[2], resolution_bytes[3], mode_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(38); self.number.serialize_into(bytes); self.label.serialize_into(bytes); self.min.serialize_into(bytes); self.max.serialize_into(bytes); self.value.serialize_into(bytes); self.resolution.serialize_into(bytes); u8::from(self.mode).serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceClassDataScroll { pub number: u16, pub scroll_type: ScrollType, pub flags: u32, pub increment: Fp3232, } impl TryParse for DeviceClassDataScroll { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (number, remaining) = u16::try_parse(remaining)?; let (scroll_type, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let (increment, remaining) = Fp3232::try_parse(remaining)?; let scroll_type = scroll_type.into(); let result = DeviceClassDataScroll { number, scroll_type, flags, increment }; Ok((result, remaining)) } } impl Serialize for DeviceClassDataScroll { type Bytes = [u8; 18]; fn serialize(&self) -> [u8; 18] { let number_bytes = self.number.serialize(); let scroll_type_bytes = u16::from(self.scroll_type).serialize(); let flags_bytes = self.flags.serialize(); let increment_bytes = self.increment.serialize(); [ number_bytes[0], number_bytes[1], scroll_type_bytes[0], scroll_type_bytes[1], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], increment_bytes[0], increment_bytes[1], increment_bytes[2], increment_bytes[3], increment_bytes[4], increment_bytes[5], increment_bytes[6], increment_bytes[7], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(18); self.number.serialize_into(bytes); u16::from(self.scroll_type).serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.flags.serialize_into(bytes); self.increment.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceClassDataTouch { pub mode: TouchMode, pub num_touches: u8, } impl TryParse for DeviceClassDataTouch { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (mode, remaining) = u8::try_parse(remaining)?; let (num_touches, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let result = DeviceClassDataTouch { mode, num_touches }; Ok((result, remaining)) } } impl Serialize for DeviceClassDataTouch { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let mode_bytes = u8::from(self.mode).serialize(); let num_touches_bytes = self.num_touches.serialize(); [ mode_bytes[0], num_touches_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); u8::from(self.mode).serialize_into(bytes); self.num_touches.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum DeviceClassData { Key(DeviceClassDataKey), Button(DeviceClassDataButton), Valuator(DeviceClassDataValuator), Scroll(DeviceClassDataScroll), Touch(DeviceClassDataTouch), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl DeviceClassData { fn try_parse(value: &[u8], type_: u16) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(type_); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(DeviceClassType::KEY) { let (key, new_remaining) = DeviceClassDataKey::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceClassData::Key(key)); } if switch_expr == u32::from(DeviceClassType::BUTTON) { let (button, new_remaining) = DeviceClassDataButton::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceClassData::Button(button)); } if switch_expr == u32::from(DeviceClassType::VALUATOR) { let (valuator, new_remaining) = DeviceClassDataValuator::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceClassData::Valuator(valuator)); } if switch_expr == u32::from(DeviceClassType::SCROLL) { let (scroll, new_remaining) = DeviceClassDataScroll::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceClassData::Scroll(scroll)); } if switch_expr == u32::from(DeviceClassType::TOUCH) { let (touch, new_remaining) = DeviceClassDataTouch::try_parse(outer_remaining)?; outer_remaining = new_remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(DeviceClassData::Touch(touch)); } match parse_result { None => Ok((DeviceClassData::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl DeviceClassData { pub fn as_key(&self) -> Option<&DeviceClassDataKey> { match self { DeviceClassData::Key(value) => Some(value), _ => None, } } pub fn as_button(&self) -> Option<&DeviceClassDataButton> { match self { DeviceClassData::Button(value) => Some(value), _ => None, } } pub fn as_valuator(&self) -> Option<&DeviceClassDataValuator> { match self { DeviceClassData::Valuator(value) => Some(value), _ => None, } } pub fn as_scroll(&self) -> Option<&DeviceClassDataScroll> { match self { DeviceClassData::Scroll(value) => Some(value), _ => None, } } pub fn as_touch(&self) -> Option<&DeviceClassDataTouch> { match self { DeviceClassData::Touch(value) => Some(value), _ => None, } } } impl DeviceClassData { #[allow(dead_code)] fn serialize(&self, type_: u16) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, type_); result } fn serialize_into(&self, bytes: &mut Vec, type_: u16) { assert_eq!(self.switch_expr(), u32::from(type_), "switch `data` has an inconsistent discriminant"); match self { DeviceClassData::Key(key) => key.serialize_into(bytes), DeviceClassData::Button(button) => button.serialize_into(bytes), DeviceClassData::Valuator(valuator) => valuator.serialize_into(bytes), DeviceClassData::Scroll(scroll) => scroll.serialize_into(bytes), DeviceClassData::Touch(touch) => touch.serialize_into(bytes), DeviceClassData::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl DeviceClassData { fn switch_expr(&self) -> u32 { match self { DeviceClassData::Key(_) => u32::from(DeviceClassType::KEY), DeviceClassData::Button(_) => u32::from(DeviceClassType::BUTTON), DeviceClassData::Valuator(_) => u32::from(DeviceClassType::VALUATOR), DeviceClassData::Scroll(_) => u32::from(DeviceClassType::SCROLL), DeviceClassData::Touch(_) => u32::from(DeviceClassType::TOUCH), DeviceClassData::InvalidValue(switch_expr) => *switch_expr, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceClass { pub len: u16, pub sourceid: DeviceId, pub data: DeviceClassData, } impl TryParse for DeviceClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (data, remaining) = DeviceClassData::try_parse(remaining, type_)?; let result = DeviceClass { len, sourceid, data }; Ok((result, remaining)) } } impl Serialize for DeviceClass { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(6); let type_ = u16::try_from(self.data.switch_expr()).unwrap(); type_.serialize_into(bytes); self.len.serialize_into(bytes); self.sourceid.serialize_into(bytes); self.data.serialize_into(bytes, type_); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIDeviceInfo { pub deviceid: DeviceId, pub type_: DeviceType, pub attachment: DeviceId, pub enabled: bool, pub name: Vec, pub classes: Vec, } impl TryParse for XIDeviceInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (type_, remaining) = u16::try_parse(remaining)?; let (attachment, remaining) = DeviceId::try_parse(remaining)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let (name_len, remaining) = u16::try_parse(remaining)?; let (enabled, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let type_ = type_.into(); let result = XIDeviceInfo { deviceid, type_, attachment, enabled, name, classes }; Ok((result, remaining)) } } impl Serialize for XIDeviceInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.deviceid.serialize_into(bytes); u16::from(self.type_).serialize_into(bytes); self.attachment.serialize_into(bytes); let num_classes = u16::try_from(self.classes.len()).expect("`classes` has too many elements"); num_classes.serialize_into(bytes); let name_len = u16::try_from(self.name.len()).expect("`name` has too many elements"); name_len.serialize_into(bytes); self.enabled.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); self.classes.serialize_into(bytes); } } impl XIDeviceInfo { /// Get the value of the `num_classes` field. /// /// The `num_classes` field is used as the length field of the `classes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_classes(&self) -> u16 { self.classes.len() .try_into().unwrap() } /// Get the value of the `name_len` field. /// /// The `name_len` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u16 { self.name.len() .try_into().unwrap() } } /// Opcode for the XIQueryDevice request pub const XI_QUERY_DEVICE_REQUEST: u8 = 48; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIQueryDeviceRequest { pub deviceid: DeviceId, } impl XIQueryDeviceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_QUERY_DEVICE_REQUEST, 0, 0, deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_QUERY_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (deviceid, remaining) = DeviceId::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XIQueryDeviceRequest { deviceid, }) } } impl Request for XIQueryDeviceRequest { type Reply = XIQueryDeviceReply; } pub fn xi_query_device(conn: &Conn, deviceid: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIQueryDeviceRequest { deviceid, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIQueryDeviceReply { pub sequence: u16, pub length: u32, pub infos: Vec, } impl TryParse for XIQueryDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_infos, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (infos, remaining) = crate::x11_utils::parse_list::(remaining, num_infos.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIQueryDeviceReply { sequence, length, infos }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl XIQueryDeviceReply { /// Get the value of the `num_infos` field. /// /// The `num_infos` field is used as the length field of the `infos` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_infos(&self) -> u16 { self.infos.len() .try_into().unwrap() } } /// Opcode for the XISetFocus request pub const XI_SET_FOCUS_REQUEST: u8 = 49; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XISetFocusRequest { pub window: xproto::Window, pub time: xproto::Timestamp, pub deviceid: DeviceId, } impl XISetFocusRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let time_bytes = self.time.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_SET_FOCUS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_SET_FOCUS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XISetFocusRequest { window, time, deviceid, }) } } impl Request for XISetFocusRequest { type Reply = (); } pub fn xi_set_focus(conn: &Conn, window: xproto::Window, time: A, deviceid: B) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let time: xproto::Timestamp = time.into(); let deviceid: DeviceId = deviceid.into(); let request0 = XISetFocusRequest { window, time, deviceid, }; request0.send(conn) } /// Opcode for the XIGetFocus request pub const XI_GET_FOCUS_REQUEST: u8 = 50; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIGetFocusRequest { pub deviceid: DeviceId, } impl XIGetFocusRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_GET_FOCUS_REQUEST, 0, 0, deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_GET_FOCUS_REQUEST { return Err(ParseError::InvalidValue); } let (deviceid, remaining) = DeviceId::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XIGetFocusRequest { deviceid, }) } } impl Request for XIGetFocusRequest { type Reply = XIGetFocusReply; } pub fn xi_get_focus(conn: &Conn, deviceid: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIGetFocusRequest { deviceid, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIGetFocusReply { pub sequence: u16, pub length: u32, pub focus: xproto::Window, } impl TryParse for XIGetFocusReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (focus, remaining) = xproto::Window::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIGetFocusReply { sequence, length, focus }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct GrabOwner(bool); impl GrabOwner { pub const NO_OWNER: Self = Self(false); pub const OWNER: Self = Self(true); } impl From for bool { #[inline] fn from(input: GrabOwner) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GrabOwner) -> Self { Some(input.0) } } impl From for u8 { #[inline] fn from(input: GrabOwner) -> Self { u8::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabOwner) -> Self { Some(u8::from(input.0)) } } impl From for u16 { #[inline] fn from(input: GrabOwner) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabOwner) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: GrabOwner) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabOwner) -> Self { Some(u32::from(input.0)) } } impl From for GrabOwner { #[inline] fn from(value: bool) -> Self { Self(value) } } impl std::fmt::Debug for GrabOwner { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_OWNER.0.into(), "NO_OWNER", "NoOwner"), (Self::OWNER.0.into(), "OWNER", "Owner"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the XIGrabDevice request pub const XI_GRAB_DEVICE_REQUEST: u8 = 51; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIGrabDeviceRequest<'input> { pub window: xproto::Window, pub time: xproto::Timestamp, pub cursor: xproto::Cursor, pub deviceid: DeviceId, pub mode: xproto::GrabMode, pub paired_device_mode: xproto::GrabMode, pub owner_events: GrabOwner, pub mask: Cow<'input, [u32]>, } impl<'input> XIGrabDeviceRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let time_bytes = self.time.serialize(); let cursor_bytes = self.cursor.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let paired_device_mode_bytes = u8::from(self.paired_device_mode).serialize(); let owner_events_bytes = bool::from(self.owner_events).serialize(); let mask_len = u16::try_from(self.mask.len()).expect("`mask` has too many elements"); let mask_len_bytes = mask_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_GRAB_DEVICE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], cursor_bytes[0], cursor_bytes[1], cursor_bytes[2], cursor_bytes[3], deviceid_bytes[0], deviceid_bytes[1], mode_bytes[0], paired_device_mode_bytes[0], owner_events_bytes[0], 0, mask_len_bytes[0], mask_len_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let mask_bytes = self.mask.serialize(); let length_so_far = length_so_far + mask_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), mask_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != XI_GRAB_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let (paired_device_mode, remaining) = u8::try_parse(remaining)?; let paired_device_mode = paired_device_mode.into(); let (owner_events, remaining) = bool::try_parse(remaining)?; let owner_events = owner_events.into(); let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (mask_len, remaining) = u16::try_parse(remaining)?; let (mask, remaining) = crate::x11_utils::parse_list::(remaining, mask_len.try_to_usize()?)?; let _ = remaining; Ok(XIGrabDeviceRequest { window, time, cursor, deviceid, mode, paired_device_mode, owner_events, mask: Cow::Owned(mask), }) } /// Clone all borrowed data in this XIGrabDeviceRequest. pub fn into_owned(self) -> XIGrabDeviceRequest<'static> { XIGrabDeviceRequest { window: self.window, time: self.time, cursor: self.cursor, deviceid: self.deviceid, mode: self.mode, paired_device_mode: self.paired_device_mode, owner_events: self.owner_events, mask: Cow::Owned(self.mask.into_owned()), } } } impl<'input> Request for XIGrabDeviceRequest<'input> { type Reply = XIGrabDeviceReply; } pub fn xi_grab_device<'c, 'input, Conn, A, B>(conn: &'c Conn, window: xproto::Window, time: A, cursor: xproto::Cursor, deviceid: B, mode: xproto::GrabMode, paired_device_mode: xproto::GrabMode, owner_events: GrabOwner, mask: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let time: xproto::Timestamp = time.into(); let deviceid: DeviceId = deviceid.into(); let request0 = XIGrabDeviceRequest { window, time, cursor, deviceid, mode, paired_device_mode, owner_events, mask: Cow::Borrowed(mask), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIGrabDeviceReply { pub sequence: u16, pub length: u32, pub status: xproto::GrabStatus, } impl TryParse for XIGrabDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let status = status.into(); let result = XIGrabDeviceReply { sequence, length, status }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the XIUngrabDevice request pub const XI_UNGRAB_DEVICE_REQUEST: u8 = 52; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIUngrabDeviceRequest { pub time: xproto::Timestamp, pub deviceid: DeviceId, } impl XIUngrabDeviceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let time_bytes = self.time.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_UNGRAB_DEVICE_REQUEST, 0, 0, time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_UNGRAB_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (time, remaining) = xproto::Timestamp::try_parse(value)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XIUngrabDeviceRequest { time, deviceid, }) } } impl Request for XIUngrabDeviceRequest { type Reply = (); } pub fn xi_ungrab_device(conn: &Conn, time: A, deviceid: B) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let time: xproto::Timestamp = time.into(); let deviceid: DeviceId = deviceid.into(); let request0 = XIUngrabDeviceRequest { time, deviceid, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct EventMode(u8); impl EventMode { pub const ASYNC_DEVICE: Self = Self(0); pub const SYNC_DEVICE: Self = Self(1); pub const REPLAY_DEVICE: Self = Self(2); pub const ASYNC_PAIRED_DEVICE: Self = Self(3); pub const ASYNC_PAIR: Self = Self(4); pub const SYNC_PAIR: Self = Self(5); pub const ACCEPT_TOUCH: Self = Self(6); pub const REJECT_TOUCH: Self = Self(7); } impl From for u8 { #[inline] fn from(input: EventMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: EventMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: EventMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: EventMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: EventMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: EventMode) -> Self { Some(u32::from(input.0)) } } impl From for EventMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for EventMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ASYNC_DEVICE.0.into(), "ASYNC_DEVICE", "AsyncDevice"), (Self::SYNC_DEVICE.0.into(), "SYNC_DEVICE", "SyncDevice"), (Self::REPLAY_DEVICE.0.into(), "REPLAY_DEVICE", "ReplayDevice"), (Self::ASYNC_PAIRED_DEVICE.0.into(), "ASYNC_PAIRED_DEVICE", "AsyncPairedDevice"), (Self::ASYNC_PAIR.0.into(), "ASYNC_PAIR", "AsyncPair"), (Self::SYNC_PAIR.0.into(), "SYNC_PAIR", "SyncPair"), (Self::ACCEPT_TOUCH.0.into(), "ACCEPT_TOUCH", "AcceptTouch"), (Self::REJECT_TOUCH.0.into(), "REJECT_TOUCH", "RejectTouch"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the XIAllowEvents request pub const XI_ALLOW_EVENTS_REQUEST: u8 = 53; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIAllowEventsRequest { pub time: xproto::Timestamp, pub deviceid: DeviceId, pub event_mode: EventMode, pub touchid: u32, pub grab_window: xproto::Window, } impl XIAllowEventsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let time_bytes = self.time.serialize(); let deviceid_bytes = self.deviceid.serialize(); let event_mode_bytes = u8::from(self.event_mode).serialize(); let touchid_bytes = self.touchid.serialize(); let grab_window_bytes = self.grab_window.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_ALLOW_EVENTS_REQUEST, 0, 0, time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], deviceid_bytes[0], deviceid_bytes[1], event_mode_bytes[0], 0, touchid_bytes[0], touchid_bytes[1], touchid_bytes[2], touchid_bytes[3], grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_ALLOW_EVENTS_REQUEST { return Err(ParseError::InvalidValue); } let (time, remaining) = xproto::Timestamp::try_parse(value)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (event_mode, remaining) = u8::try_parse(remaining)?; let event_mode = event_mode.into(); let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (touchid, remaining) = u32::try_parse(remaining)?; let (grab_window, remaining) = xproto::Window::try_parse(remaining)?; let _ = remaining; Ok(XIAllowEventsRequest { time, deviceid, event_mode, touchid, grab_window, }) } } impl Request for XIAllowEventsRequest { type Reply = (); } pub fn xi_allow_events(conn: &Conn, time: A, deviceid: B, event_mode: EventMode, touchid: u32, grab_window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let time: xproto::Timestamp = time.into(); let deviceid: DeviceId = deviceid.into(); let request0 = XIAllowEventsRequest { time, deviceid, event_mode, touchid, grab_window, }; request0.send(conn) } #[derive(Clone, Copy, PartialEq, Eq)] pub struct GrabMode22(u8); impl GrabMode22 { pub const SYNC: Self = Self(0); pub const ASYNC: Self = Self(1); pub const TOUCH: Self = Self(2); } impl From for u8 { #[inline] fn from(input: GrabMode22) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GrabMode22) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: GrabMode22) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabMode22) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: GrabMode22) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabMode22) -> Self { Some(u32::from(input.0)) } } impl From for GrabMode22 { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for GrabMode22 { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SYNC.0.into(), "SYNC", "Sync"), (Self::ASYNC.0.into(), "ASYNC", "Async"), (Self::TOUCH.0.into(), "TOUCH", "Touch"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct GrabType(u8); impl GrabType { pub const BUTTON: Self = Self(0); pub const KEYCODE: Self = Self(1); pub const ENTER: Self = Self(2); pub const FOCUS_IN: Self = Self(3); pub const TOUCH_BEGIN: Self = Self(4); } impl From for u8 { #[inline] fn from(input: GrabType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GrabType) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: GrabType) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabType) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: GrabType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabType) -> Self { Some(u32::from(input.0)) } } impl From for GrabType { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for GrabType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::BUTTON.0.into(), "BUTTON", "Button"), (Self::KEYCODE.0.into(), "KEYCODE", "Keycode"), (Self::ENTER.0.into(), "ENTER", "Enter"), (Self::FOCUS_IN.0.into(), "FOCUS_IN", "FocusIn"), (Self::TOUCH_BEGIN.0.into(), "TOUCH_BEGIN", "TouchBegin"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ModifierMask(u32); impl ModifierMask { pub const ANY: Self = Self(1 << 31); } impl From for u32 { #[inline] fn from(input: ModifierMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ModifierMask) -> Self { Some(input.0) } } impl From for ModifierMask { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for ModifierMask { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for ModifierMask { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for ModifierMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ANY.0, "ANY", "Any"), ]; pretty_print_bitmask(fmt, self.0, &variants) } } bitmask_binop!(ModifierMask, u32); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GrabModifierInfo { pub modifiers: u32, pub status: xproto::GrabStatus, } impl TryParse for GrabModifierInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (modifiers, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let status = status.into(); let result = GrabModifierInfo { modifiers, status }; Ok((result, remaining)) } } impl Serialize for GrabModifierInfo { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let modifiers_bytes = self.modifiers.serialize(); let status_bytes = u8::from(self.status).serialize(); [ modifiers_bytes[0], modifiers_bytes[1], modifiers_bytes[2], modifiers_bytes[3], status_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.modifiers.serialize_into(bytes); u8::from(self.status).serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } /// Opcode for the XIPassiveGrabDevice request pub const XI_PASSIVE_GRAB_DEVICE_REQUEST: u8 = 54; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIPassiveGrabDeviceRequest<'input> { pub time: xproto::Timestamp, pub grab_window: xproto::Window, pub cursor: xproto::Cursor, pub detail: u32, pub deviceid: DeviceId, pub grab_type: GrabType, pub grab_mode: GrabMode22, pub paired_device_mode: xproto::GrabMode, pub owner_events: GrabOwner, pub mask: Cow<'input, [u32]>, pub modifiers: Cow<'input, [u32]>, } impl<'input> XIPassiveGrabDeviceRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let time_bytes = self.time.serialize(); let grab_window_bytes = self.grab_window.serialize(); let cursor_bytes = self.cursor.serialize(); let detail_bytes = self.detail.serialize(); let deviceid_bytes = self.deviceid.serialize(); let num_modifiers = u16::try_from(self.modifiers.len()).expect("`modifiers` has too many elements"); let num_modifiers_bytes = num_modifiers.serialize(); let mask_len = u16::try_from(self.mask.len()).expect("`mask` has too many elements"); let mask_len_bytes = mask_len.serialize(); let grab_type_bytes = u8::from(self.grab_type).serialize(); let grab_mode_bytes = u8::from(self.grab_mode).serialize(); let paired_device_mode_bytes = u8::from(self.paired_device_mode).serialize(); let owner_events_bytes = bool::from(self.owner_events).serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_PASSIVE_GRAB_DEVICE_REQUEST, 0, 0, time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], cursor_bytes[0], cursor_bytes[1], cursor_bytes[2], cursor_bytes[3], detail_bytes[0], detail_bytes[1], detail_bytes[2], detail_bytes[3], deviceid_bytes[0], deviceid_bytes[1], num_modifiers_bytes[0], num_modifiers_bytes[1], mask_len_bytes[0], mask_len_bytes[1], grab_type_bytes[0], grab_mode_bytes[0], paired_device_mode_bytes[0], owner_events_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let mask_bytes = self.mask.serialize(); let length_so_far = length_so_far + mask_bytes.len(); let modifiers_bytes = self.modifiers.serialize(); let length_so_far = length_so_far + modifiers_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), mask_bytes.into(), modifiers_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != XI_PASSIVE_GRAB_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (time, remaining) = xproto::Timestamp::try_parse(value)?; let (grab_window, remaining) = xproto::Window::try_parse(remaining)?; let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?; let (detail, remaining) = u32::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (num_modifiers, remaining) = u16::try_parse(remaining)?; let (mask_len, remaining) = u16::try_parse(remaining)?; let (grab_type, remaining) = u8::try_parse(remaining)?; let grab_type = grab_type.into(); let (grab_mode, remaining) = u8::try_parse(remaining)?; let grab_mode = grab_mode.into(); let (paired_device_mode, remaining) = u8::try_parse(remaining)?; let paired_device_mode = paired_device_mode.into(); let (owner_events, remaining) = bool::try_parse(remaining)?; let owner_events = owner_events.into(); let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (mask, remaining) = crate::x11_utils::parse_list::(remaining, mask_len.try_to_usize()?)?; let (modifiers, remaining) = crate::x11_utils::parse_list::(remaining, num_modifiers.try_to_usize()?)?; let _ = remaining; Ok(XIPassiveGrabDeviceRequest { time, grab_window, cursor, detail, deviceid, grab_type, grab_mode, paired_device_mode, owner_events, mask: Cow::Owned(mask), modifiers: Cow::Owned(modifiers), }) } /// Clone all borrowed data in this XIPassiveGrabDeviceRequest. pub fn into_owned(self) -> XIPassiveGrabDeviceRequest<'static> { XIPassiveGrabDeviceRequest { time: self.time, grab_window: self.grab_window, cursor: self.cursor, detail: self.detail, deviceid: self.deviceid, grab_type: self.grab_type, grab_mode: self.grab_mode, paired_device_mode: self.paired_device_mode, owner_events: self.owner_events, mask: Cow::Owned(self.mask.into_owned()), modifiers: Cow::Owned(self.modifiers.into_owned()), } } } impl<'input> Request for XIPassiveGrabDeviceRequest<'input> { type Reply = XIPassiveGrabDeviceReply; } pub fn xi_passive_grab_device<'c, 'input, Conn, A, B>(conn: &'c Conn, time: A, grab_window: xproto::Window, cursor: xproto::Cursor, detail: u32, deviceid: B, grab_type: GrabType, grab_mode: GrabMode22, paired_device_mode: xproto::GrabMode, owner_events: GrabOwner, mask: &'input [u32], modifiers: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let time: xproto::Timestamp = time.into(); let deviceid: DeviceId = deviceid.into(); let request0 = XIPassiveGrabDeviceRequest { time, grab_window, cursor, detail, deviceid, grab_type, grab_mode, paired_device_mode, owner_events, mask: Cow::Borrowed(mask), modifiers: Cow::Borrowed(modifiers), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIPassiveGrabDeviceReply { pub sequence: u16, pub length: u32, pub modifiers: Vec, } impl TryParse for XIPassiveGrabDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_modifiers, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (modifiers, remaining) = crate::x11_utils::parse_list::(remaining, num_modifiers.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIPassiveGrabDeviceReply { sequence, length, modifiers }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl XIPassiveGrabDeviceReply { /// Get the value of the `num_modifiers` field. /// /// The `num_modifiers` field is used as the length field of the `modifiers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_modifiers(&self) -> u16 { self.modifiers.len() .try_into().unwrap() } } /// Opcode for the XIPassiveUngrabDevice request pub const XI_PASSIVE_UNGRAB_DEVICE_REQUEST: u8 = 55; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIPassiveUngrabDeviceRequest<'input> { pub grab_window: xproto::Window, pub detail: u32, pub deviceid: DeviceId, pub grab_type: GrabType, pub modifiers: Cow<'input, [u32]>, } impl<'input> XIPassiveUngrabDeviceRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let grab_window_bytes = self.grab_window.serialize(); let detail_bytes = self.detail.serialize(); let deviceid_bytes = self.deviceid.serialize(); let num_modifiers = u16::try_from(self.modifiers.len()).expect("`modifiers` has too many elements"); let num_modifiers_bytes = num_modifiers.serialize(); let grab_type_bytes = u8::from(self.grab_type).serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_PASSIVE_UNGRAB_DEVICE_REQUEST, 0, 0, grab_window_bytes[0], grab_window_bytes[1], grab_window_bytes[2], grab_window_bytes[3], detail_bytes[0], detail_bytes[1], detail_bytes[2], detail_bytes[3], deviceid_bytes[0], deviceid_bytes[1], num_modifiers_bytes[0], num_modifiers_bytes[1], grab_type_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); let modifiers_bytes = self.modifiers.serialize(); let length_so_far = length_so_far + modifiers_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), modifiers_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != XI_PASSIVE_UNGRAB_DEVICE_REQUEST { return Err(ParseError::InvalidValue); } let (grab_window, remaining) = xproto::Window::try_parse(value)?; let (detail, remaining) = u32::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (num_modifiers, remaining) = u16::try_parse(remaining)?; let (grab_type, remaining) = u8::try_parse(remaining)?; let grab_type = grab_type.into(); let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (modifiers, remaining) = crate::x11_utils::parse_list::(remaining, num_modifiers.try_to_usize()?)?; let _ = remaining; Ok(XIPassiveUngrabDeviceRequest { grab_window, detail, deviceid, grab_type, modifiers: Cow::Owned(modifiers), }) } /// Clone all borrowed data in this XIPassiveUngrabDeviceRequest. pub fn into_owned(self) -> XIPassiveUngrabDeviceRequest<'static> { XIPassiveUngrabDeviceRequest { grab_window: self.grab_window, detail: self.detail, deviceid: self.deviceid, grab_type: self.grab_type, modifiers: Cow::Owned(self.modifiers.into_owned()), } } } impl<'input> Request for XIPassiveUngrabDeviceRequest<'input> { type Reply = (); } pub fn xi_passive_ungrab_device<'c, 'input, Conn, A>(conn: &'c Conn, grab_window: xproto::Window, detail: u32, deviceid: A, grab_type: GrabType, modifiers: &'input [u32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIPassiveUngrabDeviceRequest { grab_window, detail, deviceid, grab_type, modifiers: Cow::Borrowed(modifiers), }; request0.send(conn) } /// Opcode for the XIListProperties request pub const XI_LIST_PROPERTIES_REQUEST: u8 = 56; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIListPropertiesRequest { pub deviceid: DeviceId, } impl XIListPropertiesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_LIST_PROPERTIES_REQUEST, 0, 0, deviceid_bytes[0], deviceid_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_LIST_PROPERTIES_REQUEST { return Err(ParseError::InvalidValue); } let (deviceid, remaining) = DeviceId::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(XIListPropertiesRequest { deviceid, }) } } impl Request for XIListPropertiesRequest { type Reply = XIListPropertiesReply; } pub fn xi_list_properties(conn: &Conn, deviceid: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIListPropertiesRequest { deviceid, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIListPropertiesReply { pub sequence: u16, pub length: u32, pub properties: Vec, } impl TryParse for XIListPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_properties, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (properties, remaining) = crate::x11_utils::parse_list::(remaining, num_properties.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIListPropertiesReply { sequence, length, properties }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl XIListPropertiesReply { /// Get the value of the `num_properties` field. /// /// The `num_properties` field is used as the length field of the `properties` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_properties(&self) -> u16 { self.properties.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum XIChangePropertyAux { Data8(Vec), Data16(Vec), Data32(Vec), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl XIChangePropertyAux { fn try_parse(value: &[u8], format: u8, num_items: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(format); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(PropertyFormat::M8_BITS) { let remaining = outer_remaining; let value = remaining; let (data8, remaining) = crate::x11_utils::parse_u8_list(remaining, num_items.try_to_usize()?)?; let data8 = data8.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(XIChangePropertyAux::Data8(data8)); } if switch_expr == u32::from(PropertyFormat::M16_BITS) { let remaining = outer_remaining; let value = remaining; let (data16, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(XIChangePropertyAux::Data16(data16)); } if switch_expr == u32::from(PropertyFormat::M32_BITS) { let remaining = outer_remaining; let (data32, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(XIChangePropertyAux::Data32(data32)); } match parse_result { None => Ok((XIChangePropertyAux::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl XIChangePropertyAux { pub fn as_data8(&self) -> Option<&Vec> { match self { XIChangePropertyAux::Data8(value) => Some(value), _ => None, } } pub fn as_data16(&self) -> Option<&Vec> { match self { XIChangePropertyAux::Data16(value) => Some(value), _ => None, } } pub fn as_data32(&self) -> Option<&Vec> { match self { XIChangePropertyAux::Data32(value) => Some(value), _ => None, } } } impl XIChangePropertyAux { #[allow(dead_code)] fn serialize(&self, format: u8, num_items: u32) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, format, num_items); result } fn serialize_into(&self, bytes: &mut Vec, format: u8, num_items: u32) { assert_eq!(self.switch_expr(), u32::from(format), "switch `items` has an inconsistent discriminant"); match self { XIChangePropertyAux::Data8(data8) => { assert_eq!(data8.len(), usize::try_from(num_items).unwrap(), "`data8` has an incorrect length"); bytes.extend_from_slice(&data8); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } XIChangePropertyAux::Data16(data16) => { assert_eq!(data16.len(), usize::try_from(num_items).unwrap(), "`data16` has an incorrect length"); data16.serialize_into(bytes); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } XIChangePropertyAux::Data32(data32) => { assert_eq!(data32.len(), usize::try_from(num_items).unwrap(), "`data32` has an incorrect length"); data32.serialize_into(bytes); } XIChangePropertyAux::InvalidValue(_) => panic!("attempted to serialize invalid switch case"), } } } impl XIChangePropertyAux { fn switch_expr(&self) -> u32 { match self { XIChangePropertyAux::Data8(_) => u32::from(PropertyFormat::M8_BITS), XIChangePropertyAux::Data16(_) => u32::from(PropertyFormat::M16_BITS), XIChangePropertyAux::Data32(_) => u32::from(PropertyFormat::M32_BITS), XIChangePropertyAux::InvalidValue(switch_expr) => *switch_expr, } } } /// Opcode for the XIChangeProperty request pub const XI_CHANGE_PROPERTY_REQUEST: u8 = 57; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIChangePropertyRequest<'input> { pub deviceid: DeviceId, pub mode: xproto::PropMode, pub property: xproto::Atom, pub type_: xproto::Atom, pub num_items: u32, pub items: Cow<'input, XIChangePropertyAux>, } impl<'input> XIChangePropertyRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let deviceid_bytes = self.deviceid.serialize(); let mode_bytes = u8::from(self.mode).serialize(); let format = u8::try_from(self.items.switch_expr()).unwrap(); let format_bytes = format.serialize(); let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let num_items_bytes = self.num_items.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_CHANGE_PROPERTY_REQUEST, 0, 0, deviceid_bytes[0], deviceid_bytes[1], mode_bytes[0], format_bytes[0], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], num_items_bytes[0], num_items_bytes[1], num_items_bytes[2], num_items_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let items_bytes = self.items.serialize(format, self.num_items); let length_so_far = length_so_far + items_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), items_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != XI_CHANGE_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (deviceid, remaining) = DeviceId::try_parse(value)?; let (mode, remaining) = u8::try_parse(remaining)?; let mode = mode.into(); let (format, remaining) = u8::try_parse(remaining)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (num_items, remaining) = u32::try_parse(remaining)?; let (items, remaining) = XIChangePropertyAux::try_parse(remaining, format, num_items)?; let _ = remaining; Ok(XIChangePropertyRequest { deviceid, mode, property, type_, num_items, items: Cow::Owned(items), }) } /// Clone all borrowed data in this XIChangePropertyRequest. pub fn into_owned(self) -> XIChangePropertyRequest<'static> { XIChangePropertyRequest { deviceid: self.deviceid, mode: self.mode, property: self.property, type_: self.type_, num_items: self.num_items, items: Cow::Owned(self.items.into_owned()), } } } impl<'input> Request for XIChangePropertyRequest<'input> { type Reply = (); } pub fn xi_change_property<'c, 'input, Conn, A>(conn: &'c Conn, deviceid: A, mode: xproto::PropMode, property: xproto::Atom, type_: xproto::Atom, num_items: u32, items: &'input XIChangePropertyAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIChangePropertyRequest { deviceid, mode, property, type_, num_items, items: Cow::Borrowed(items), }; request0.send(conn) } /// Opcode for the XIDeleteProperty request pub const XI_DELETE_PROPERTY_REQUEST: u8 = 58; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIDeletePropertyRequest { pub deviceid: DeviceId, pub property: xproto::Atom, } impl XIDeletePropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let deviceid_bytes = self.deviceid.serialize(); let property_bytes = self.property.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_DELETE_PROPERTY_REQUEST, 0, 0, deviceid_bytes[0], deviceid_bytes[1], 0, 0, property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_DELETE_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (deviceid, remaining) = DeviceId::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(XIDeletePropertyRequest { deviceid, property, }) } } impl Request for XIDeletePropertyRequest { type Reply = (); } pub fn xi_delete_property(conn: &Conn, deviceid: A, property: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIDeletePropertyRequest { deviceid, property, }; request0.send(conn) } /// Opcode for the XIGetProperty request pub const XI_GET_PROPERTY_REQUEST: u8 = 59; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIGetPropertyRequest { pub deviceid: DeviceId, pub delete: bool, pub property: xproto::Atom, pub type_: xproto::Atom, pub offset: u32, pub len: u32, } impl XIGetPropertyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let deviceid_bytes = self.deviceid.serialize(); let delete_bytes = self.delete.serialize(); let property_bytes = self.property.serialize(); let type_bytes = self.type_.serialize(); let offset_bytes = self.offset.serialize(); let len_bytes = self.len.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_GET_PROPERTY_REQUEST, 0, 0, deviceid_bytes[0], deviceid_bytes[1], delete_bytes[0], 0, property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], type_bytes[0], type_bytes[1], type_bytes[2], type_bytes[3], offset_bytes[0], offset_bytes[1], offset_bytes[2], offset_bytes[3], len_bytes[0], len_bytes[1], len_bytes[2], len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_GET_PROPERTY_REQUEST { return Err(ParseError::InvalidValue); } let (deviceid, remaining) = DeviceId::try_parse(value)?; let (delete, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (offset, remaining) = u32::try_parse(remaining)?; let (len, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(XIGetPropertyRequest { deviceid, delete, property, type_, offset, len, }) } } impl Request for XIGetPropertyRequest { type Reply = XIGetPropertyReply; } pub fn xi_get_property(conn: &Conn, deviceid: A, delete: bool, property: xproto::Atom, type_: xproto::Atom, offset: u32, len: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let deviceid: DeviceId = deviceid.into(); let request0 = XIGetPropertyRequest { deviceid, delete, property, type_, offset, len, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub enum XIGetPropertyItems { Data8(Vec), Data16(Vec), Data32(Vec), /// This variant is returned when the server sends a discriminant /// value that does not match any of the defined by the protocol. /// /// Usually, this should be considered a parsing error, but there /// are some cases where the server violates the protocol. /// /// Trying to use `serialize` or `serialize_into` with this variant /// will raise a panic. InvalidValue(u32), } impl XIGetPropertyItems { fn try_parse(value: &[u8], format: u8, num_items: u32) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(format); let mut outer_remaining = value; let mut parse_result = None; if switch_expr == u32::from(PropertyFormat::M8_BITS) { let remaining = outer_remaining; let value = remaining; let (data8, remaining) = crate::x11_utils::parse_u8_list(remaining, num_items.try_to_usize()?)?; let data8 = data8.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(XIGetPropertyItems::Data8(data8)); } if switch_expr == u32::from(PropertyFormat::M16_BITS) { let remaining = outer_remaining; let value = remaining; let (data16, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(XIGetPropertyItems::Data16(data16)); } if switch_expr == u32::from(PropertyFormat::M32_BITS) { let remaining = outer_remaining; let (data32, remaining) = crate::x11_utils::parse_list::(remaining, num_items.try_to_usize()?)?; outer_remaining = remaining; assert!(parse_result.is_none(), "The XML should prevent more than one 'if' from matching"); parse_result = Some(XIGetPropertyItems::Data32(data32)); } match parse_result { None => Ok((XIGetPropertyItems::InvalidValue(switch_expr), &[])), Some(result) => Ok((result, outer_remaining)), } } } impl XIGetPropertyItems { pub fn as_data8(&self) -> Option<&Vec> { match self { XIGetPropertyItems::Data8(value) => Some(value), _ => None, } } pub fn as_data16(&self) -> Option<&Vec> { match self { XIGetPropertyItems::Data16(value) => Some(value), _ => None, } } pub fn as_data32(&self) -> Option<&Vec> { match self { XIGetPropertyItems::Data32(value) => Some(value), _ => None, } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIGetPropertyReply { pub sequence: u16, pub length: u32, pub type_: xproto::Atom, pub bytes_after: u32, pub num_items: u32, pub items: XIGetPropertyItems, } impl TryParse for XIGetPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = xproto::Atom::try_parse(remaining)?; let (bytes_after, remaining) = u32::try_parse(remaining)?; let (num_items, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(11..).ok_or(ParseError::InsufficientData)?; let (items, remaining) = XIGetPropertyItems::try_parse(remaining, format, num_items)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIGetPropertyReply { sequence, length, type_, bytes_after, num_items, items }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the XIGetSelectedEvents request pub const XI_GET_SELECTED_EVENTS_REQUEST: u8 = 60; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct XIGetSelectedEventsRequest { pub window: xproto::Window, } impl XIGetSelectedEventsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_GET_SELECTED_EVENTS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != XI_GET_SELECTED_EVENTS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(XIGetSelectedEventsRequest { window, }) } } impl Request for XIGetSelectedEventsRequest { type Reply = XIGetSelectedEventsReply; } pub fn xi_get_selected_events(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = XIGetSelectedEventsRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIGetSelectedEventsReply { pub sequence: u16, pub length: u32, pub masks: Vec, } impl TryParse for XIGetSelectedEventsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_masks, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (masks, remaining) = crate::x11_utils::parse_list::(remaining, num_masks.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = XIGetSelectedEventsReply { sequence, length, masks }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl XIGetSelectedEventsReply { /// Get the value of the `num_masks` field. /// /// The `num_masks` field is used as the length field of the `masks` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_masks(&self) -> u16 { self.masks.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BarrierReleasePointerInfo { pub deviceid: DeviceId, pub barrier: xfixes::Barrier, pub eventid: u32, } impl TryParse for BarrierReleasePointerInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (barrier, remaining) = xfixes::Barrier::try_parse(remaining)?; let (eventid, remaining) = u32::try_parse(remaining)?; let result = BarrierReleasePointerInfo { deviceid, barrier, eventid }; Ok((result, remaining)) } } impl Serialize for BarrierReleasePointerInfo { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let deviceid_bytes = self.deviceid.serialize(); let barrier_bytes = self.barrier.serialize(); let eventid_bytes = self.eventid.serialize(); [ deviceid_bytes[0], deviceid_bytes[1], 0, 0, barrier_bytes[0], barrier_bytes[1], barrier_bytes[2], barrier_bytes[3], eventid_bytes[0], eventid_bytes[1], eventid_bytes[2], eventid_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.deviceid.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.barrier.serialize_into(bytes); self.eventid.serialize_into(bytes); } } /// Opcode for the XIBarrierReleasePointer request pub const XI_BARRIER_RELEASE_POINTER_REQUEST: u8 = 61; #[derive(Debug, Clone, PartialEq, Eq)] pub struct XIBarrierReleasePointerRequest<'input> { pub barriers: Cow<'input, [BarrierReleasePointerInfo]>, } impl<'input> XIBarrierReleasePointerRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let num_barriers = u32::try_from(self.barriers.len()).expect("`barriers` has too many elements"); let num_barriers_bytes = num_barriers.serialize(); let mut request0 = vec![ extension_information.major_opcode, XI_BARRIER_RELEASE_POINTER_REQUEST, 0, 0, num_barriers_bytes[0], num_barriers_bytes[1], num_barriers_bytes[2], num_barriers_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let barriers_bytes = self.barriers.serialize(); let length_so_far = length_so_far + barriers_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), barriers_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != XI_BARRIER_RELEASE_POINTER_REQUEST { return Err(ParseError::InvalidValue); } let (num_barriers, remaining) = u32::try_parse(value)?; let (barriers, remaining) = crate::x11_utils::parse_list::(remaining, num_barriers.try_to_usize()?)?; let _ = remaining; Ok(XIBarrierReleasePointerRequest { barriers: Cow::Owned(barriers), }) } /// Clone all borrowed data in this XIBarrierReleasePointerRequest. pub fn into_owned(self) -> XIBarrierReleasePointerRequest<'static> { XIBarrierReleasePointerRequest { barriers: Cow::Owned(self.barriers.into_owned()), } } } impl<'input> Request for XIBarrierReleasePointerRequest<'input> { type Reply = (); } pub fn xi_barrier_release_pointer<'c, 'input, Conn>(conn: &'c Conn, barriers: &'input [BarrierReleasePointerInfo]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = XIBarrierReleasePointerRequest { barriers: Cow::Borrowed(barriers), }; request0.send(conn) } /// Opcode for the DeviceValuator event pub const DEVICE_VALUATOR_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceValuatorEvent { pub response_type: u8, pub device_id: u8, pub sequence: u16, pub device_state: u16, pub num_valuators: u8, pub first_valuator: u8, pub valuators: [i32; 6], } impl TryParse for DeviceValuatorEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (device_state, remaining) = u16::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; let (first_valuator, remaining) = u8::try_parse(remaining)?; let (valuators_0, remaining) = i32::try_parse(remaining)?; let (valuators_1, remaining) = i32::try_parse(remaining)?; let (valuators_2, remaining) = i32::try_parse(remaining)?; let (valuators_3, remaining) = i32::try_parse(remaining)?; let (valuators_4, remaining) = i32::try_parse(remaining)?; let (valuators_5, remaining) = i32::try_parse(remaining)?; let valuators = [ valuators_0, valuators_1, valuators_2, valuators_3, valuators_4, valuators_5, ]; let result = DeviceValuatorEvent { response_type, device_id, sequence, device_state, num_valuators, first_valuator, valuators }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DeviceValuatorEvent> for [u8; 32] { fn from(input: &DeviceValuatorEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let device_id_bytes = input.device_id.serialize(); let sequence_bytes = input.sequence.serialize(); let device_state_bytes = input.device_state.serialize(); let num_valuators_bytes = input.num_valuators.serialize(); let first_valuator_bytes = input.first_valuator.serialize(); let valuators_0_bytes = input.valuators[0].serialize(); let valuators_1_bytes = input.valuators[1].serialize(); let valuators_2_bytes = input.valuators[2].serialize(); let valuators_3_bytes = input.valuators[3].serialize(); let valuators_4_bytes = input.valuators[4].serialize(); let valuators_5_bytes = input.valuators[5].serialize(); [ response_type_bytes[0], device_id_bytes[0], sequence_bytes[0], sequence_bytes[1], device_state_bytes[0], device_state_bytes[1], num_valuators_bytes[0], first_valuator_bytes[0], valuators_0_bytes[0], valuators_0_bytes[1], valuators_0_bytes[2], valuators_0_bytes[3], valuators_1_bytes[0], valuators_1_bytes[1], valuators_1_bytes[2], valuators_1_bytes[3], valuators_2_bytes[0], valuators_2_bytes[1], valuators_2_bytes[2], valuators_2_bytes[3], valuators_3_bytes[0], valuators_3_bytes[1], valuators_3_bytes[2], valuators_3_bytes[3], valuators_4_bytes[0], valuators_4_bytes[1], valuators_4_bytes[2], valuators_4_bytes[3], valuators_5_bytes[0], valuators_5_bytes[1], valuators_5_bytes[2], valuators_5_bytes[3], ] } } impl From for [u8; 32] { fn from(input: DeviceValuatorEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct MoreEventsMask(u8); impl MoreEventsMask { pub const MORE_EVENTS: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: MoreEventsMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: MoreEventsMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: MoreEventsMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: MoreEventsMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: MoreEventsMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: MoreEventsMask) -> Self { Some(u32::from(input.0)) } } impl From for MoreEventsMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for MoreEventsMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::MORE_EVENTS.0.into(), "MORE_EVENTS", "MoreEvents"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(MoreEventsMask, u8); /// Opcode for the DeviceKeyPress event pub const DEVICE_KEY_PRESS_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceKeyPressEvent { pub response_type: u8, pub detail: u8, pub sequence: u16, pub time: xproto::Timestamp, pub root: xproto::Window, pub event: xproto::Window, pub child: xproto::Window, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub same_screen: bool, pub device_id: u8, } impl TryParse for DeviceKeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (event, remaining) = xproto::Window::try_parse(remaining)?; let (child, remaining) = xproto::Window::try_parse(remaining)?; let (root_x, remaining) = i16::try_parse(remaining)?; let (root_y, remaining) = i16::try_parse(remaining)?; let (event_x, remaining) = i16::try_parse(remaining)?; let (event_y, remaining) = i16::try_parse(remaining)?; let (state, remaining) = u16::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let result = DeviceKeyPressEvent { response_type, detail, sequence, time, root, event, child, root_x, root_y, event_x, event_y, state, same_screen, device_id }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DeviceKeyPressEvent> for [u8; 32] { fn from(input: &DeviceKeyPressEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = input.detail.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let root_bytes = input.root.serialize(); let event_bytes = input.event.serialize(); let child_bytes = input.child.serialize(); let root_x_bytes = input.root_x.serialize(); let root_y_bytes = input.root_y.serialize(); let event_x_bytes = input.event_x.serialize(); let event_y_bytes = input.event_y.serialize(); let state_bytes = input.state.serialize(); let same_screen_bytes = input.same_screen.serialize(); let device_id_bytes = input.device_id.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], child_bytes[0], child_bytes[1], child_bytes[2], child_bytes[3], root_x_bytes[0], root_x_bytes[1], root_y_bytes[0], root_y_bytes[1], event_x_bytes[0], event_x_bytes[1], event_y_bytes[0], event_y_bytes[1], state_bytes[0], state_bytes[1], same_screen_bytes[0], device_id_bytes[0], ] } } impl From for [u8; 32] { fn from(input: DeviceKeyPressEvent) -> Self { Self::from(&input) } } /// Opcode for the DeviceKeyRelease event pub const DEVICE_KEY_RELEASE_EVENT: u8 = 2; pub type DeviceKeyReleaseEvent = DeviceKeyPressEvent; /// Opcode for the DeviceButtonPress event pub const DEVICE_BUTTON_PRESS_EVENT: u8 = 3; pub type DeviceButtonPressEvent = DeviceKeyPressEvent; /// Opcode for the DeviceButtonRelease event pub const DEVICE_BUTTON_RELEASE_EVENT: u8 = 4; pub type DeviceButtonReleaseEvent = DeviceKeyPressEvent; /// Opcode for the DeviceMotionNotify event pub const DEVICE_MOTION_NOTIFY_EVENT: u8 = 5; pub type DeviceMotionNotifyEvent = DeviceKeyPressEvent; /// Opcode for the DeviceFocusIn event pub const DEVICE_FOCUS_IN_EVENT: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceFocusInEvent { pub response_type: u8, pub detail: xproto::NotifyDetail, pub sequence: u16, pub time: xproto::Timestamp, pub window: xproto::Window, pub mode: xproto::NotifyMode, pub device_id: u8, } impl TryParse for DeviceFocusInEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(18..).ok_or(ParseError::InsufficientData)?; let detail = detail.into(); let mode = mode.into(); let result = DeviceFocusInEvent { response_type, detail, sequence, time, window, mode, device_id }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DeviceFocusInEvent> for [u8; 32] { fn from(input: &DeviceFocusInEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = u8::from(input.detail).serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let window_bytes = input.window.serialize(); let mode_bytes = u8::from(input.mode).serialize(); let device_id_bytes = input.device_id.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], mode_bytes[0], device_id_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: DeviceFocusInEvent) -> Self { Self::from(&input) } } /// Opcode for the DeviceFocusOut event pub const DEVICE_FOCUS_OUT_EVENT: u8 = 7; pub type DeviceFocusOutEvent = DeviceFocusInEvent; /// Opcode for the ProximityIn event pub const PROXIMITY_IN_EVENT: u8 = 8; pub type ProximityInEvent = DeviceKeyPressEvent; /// Opcode for the ProximityOut event pub const PROXIMITY_OUT_EVENT: u8 = 9; pub type ProximityOutEvent = DeviceKeyPressEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct ClassesReportedMask(u8); impl ClassesReportedMask { pub const OUT_OF_PROXIMITY: Self = Self(1 << 7); pub const DEVICE_MODE_ABSOLUTE: Self = Self(1 << 6); pub const REPORTING_VALUATORS: Self = Self(1 << 2); pub const REPORTING_BUTTONS: Self = Self(1 << 1); pub const REPORTING_KEYS: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: ClassesReportedMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ClassesReportedMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ClassesReportedMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ClassesReportedMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ClassesReportedMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ClassesReportedMask) -> Self { Some(u32::from(input.0)) } } impl From for ClassesReportedMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ClassesReportedMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::OUT_OF_PROXIMITY.0.into(), "OUT_OF_PROXIMITY", "OutOfProximity"), (Self::DEVICE_MODE_ABSOLUTE.0.into(), "DEVICE_MODE_ABSOLUTE", "DeviceModeAbsolute"), (Self::REPORTING_VALUATORS.0.into(), "REPORTING_VALUATORS", "ReportingValuators"), (Self::REPORTING_BUTTONS.0.into(), "REPORTING_BUTTONS", "ReportingButtons"), (Self::REPORTING_KEYS.0.into(), "REPORTING_KEYS", "ReportingKeys"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ClassesReportedMask, u8); /// Opcode for the DeviceStateNotify event pub const DEVICE_STATE_NOTIFY_EVENT: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceStateNotifyEvent { pub response_type: u8, pub device_id: u8, pub sequence: u16, pub time: xproto::Timestamp, pub num_keys: u8, pub num_buttons: u8, pub num_valuators: u8, pub classes_reported: u8, pub buttons: [u8; 4], pub keys: [u8; 4], pub valuators: [u32; 3], } impl TryParse for DeviceStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (num_keys, remaining) = u8::try_parse(remaining)?; let (num_buttons, remaining) = u8::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; let (classes_reported, remaining) = u8::try_parse(remaining)?; let (buttons, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let buttons = <[u8; 4]>::try_from(buttons).unwrap(); let (keys, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let keys = <[u8; 4]>::try_from(keys).unwrap(); let (valuators_0, remaining) = u32::try_parse(remaining)?; let (valuators_1, remaining) = u32::try_parse(remaining)?; let (valuators_2, remaining) = u32::try_parse(remaining)?; let valuators = [ valuators_0, valuators_1, valuators_2, ]; let result = DeviceStateNotifyEvent { response_type, device_id, sequence, time, num_keys, num_buttons, num_valuators, classes_reported, buttons, keys, valuators }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DeviceStateNotifyEvent> for [u8; 32] { fn from(input: &DeviceStateNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let device_id_bytes = input.device_id.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let num_keys_bytes = input.num_keys.serialize(); let num_buttons_bytes = input.num_buttons.serialize(); let num_valuators_bytes = input.num_valuators.serialize(); let classes_reported_bytes = input.classes_reported.serialize(); let valuators_0_bytes = input.valuators[0].serialize(); let valuators_1_bytes = input.valuators[1].serialize(); let valuators_2_bytes = input.valuators[2].serialize(); [ response_type_bytes[0], device_id_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], num_keys_bytes[0], num_buttons_bytes[0], num_valuators_bytes[0], classes_reported_bytes[0], input.buttons[0], input.buttons[1], input.buttons[2], input.buttons[3], input.keys[0], input.keys[1], input.keys[2], input.keys[3], valuators_0_bytes[0], valuators_0_bytes[1], valuators_0_bytes[2], valuators_0_bytes[3], valuators_1_bytes[0], valuators_1_bytes[1], valuators_1_bytes[2], valuators_1_bytes[3], valuators_2_bytes[0], valuators_2_bytes[1], valuators_2_bytes[2], valuators_2_bytes[3], ] } } impl From for [u8; 32] { fn from(input: DeviceStateNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the DeviceMappingNotify event pub const DEVICE_MAPPING_NOTIFY_EVENT: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceMappingNotifyEvent { pub response_type: u8, pub device_id: u8, pub sequence: u16, pub request: xproto::Mapping, pub first_keycode: KeyCode, pub count: u8, pub time: xproto::Timestamp, } impl TryParse for DeviceMappingNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (request, remaining) = u8::try_parse(remaining)?; let (first_keycode, remaining) = KeyCode::try_parse(remaining)?; let (count, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let request = request.into(); let result = DeviceMappingNotifyEvent { response_type, device_id, sequence, request, first_keycode, count, time }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DeviceMappingNotifyEvent> for [u8; 32] { fn from(input: &DeviceMappingNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let device_id_bytes = input.device_id.serialize(); let sequence_bytes = input.sequence.serialize(); let request_bytes = u8::from(input.request).serialize(); let first_keycode_bytes = input.first_keycode.serialize(); let count_bytes = input.count.serialize(); let time_bytes = input.time.serialize(); [ response_type_bytes[0], device_id_bytes[0], sequence_bytes[0], sequence_bytes[1], request_bytes[0], first_keycode_bytes[0], count_bytes[0], 0, time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: DeviceMappingNotifyEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ChangeDevice(u8); impl ChangeDevice { pub const NEW_POINTER: Self = Self(0); pub const NEW_KEYBOARD: Self = Self(1); } impl From for u8 { #[inline] fn from(input: ChangeDevice) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ChangeDevice) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ChangeDevice) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeDevice) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ChangeDevice) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeDevice) -> Self { Some(u32::from(input.0)) } } impl From for ChangeDevice { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ChangeDevice { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NEW_POINTER.0.into(), "NEW_POINTER", "NewPointer"), (Self::NEW_KEYBOARD.0.into(), "NEW_KEYBOARD", "NewKeyboard"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the ChangeDeviceNotify event pub const CHANGE_DEVICE_NOTIFY_EVENT: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ChangeDeviceNotifyEvent { pub response_type: u8, pub device_id: u8, pub sequence: u16, pub time: xproto::Timestamp, pub request: ChangeDevice, } impl TryParse for ChangeDeviceNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (request, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(23..).ok_or(ParseError::InsufficientData)?; let request = request.into(); let result = ChangeDeviceNotifyEvent { response_type, device_id, sequence, time, request }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ChangeDeviceNotifyEvent> for [u8; 32] { fn from(input: &ChangeDeviceNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let device_id_bytes = input.device_id.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let request_bytes = u8::from(input.request).serialize(); [ response_type_bytes[0], device_id_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], request_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ChangeDeviceNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the DeviceKeyStateNotify event pub const DEVICE_KEY_STATE_NOTIFY_EVENT: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceKeyStateNotifyEvent { pub response_type: u8, pub device_id: u8, pub sequence: u16, pub keys: [u8; 28], } impl TryParse for DeviceKeyStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (keys, remaining) = crate::x11_utils::parse_u8_list(remaining, 28)?; let keys = <[u8; 28]>::try_from(keys).unwrap(); let result = DeviceKeyStateNotifyEvent { response_type, device_id, sequence, keys }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DeviceKeyStateNotifyEvent> for [u8; 32] { fn from(input: &DeviceKeyStateNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let device_id_bytes = input.device_id.serialize(); let sequence_bytes = input.sequence.serialize(); [ response_type_bytes[0], device_id_bytes[0], sequence_bytes[0], sequence_bytes[1], input.keys[0], input.keys[1], input.keys[2], input.keys[3], input.keys[4], input.keys[5], input.keys[6], input.keys[7], input.keys[8], input.keys[9], input.keys[10], input.keys[11], input.keys[12], input.keys[13], input.keys[14], input.keys[15], input.keys[16], input.keys[17], input.keys[18], input.keys[19], input.keys[20], input.keys[21], input.keys[22], input.keys[23], input.keys[24], input.keys[25], input.keys[26], input.keys[27], ] } } impl From for [u8; 32] { fn from(input: DeviceKeyStateNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the DeviceButtonStateNotify event pub const DEVICE_BUTTON_STATE_NOTIFY_EVENT: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DeviceButtonStateNotifyEvent { pub response_type: u8, pub device_id: u8, pub sequence: u16, pub buttons: [u8; 28], } impl TryParse for DeviceButtonStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (buttons, remaining) = crate::x11_utils::parse_u8_list(remaining, 28)?; let buttons = <[u8; 28]>::try_from(buttons).unwrap(); let result = DeviceButtonStateNotifyEvent { response_type, device_id, sequence, buttons }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DeviceButtonStateNotifyEvent> for [u8; 32] { fn from(input: &DeviceButtonStateNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let device_id_bytes = input.device_id.serialize(); let sequence_bytes = input.sequence.serialize(); [ response_type_bytes[0], device_id_bytes[0], sequence_bytes[0], sequence_bytes[1], input.buttons[0], input.buttons[1], input.buttons[2], input.buttons[3], input.buttons[4], input.buttons[5], input.buttons[6], input.buttons[7], input.buttons[8], input.buttons[9], input.buttons[10], input.buttons[11], input.buttons[12], input.buttons[13], input.buttons[14], input.buttons[15], input.buttons[16], input.buttons[17], input.buttons[18], input.buttons[19], input.buttons[20], input.buttons[21], input.buttons[22], input.buttons[23], input.buttons[24], input.buttons[25], input.buttons[26], input.buttons[27], ] } } impl From for [u8; 32] { fn from(input: DeviceButtonStateNotifyEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DeviceChange(u8); impl DeviceChange { pub const ADDED: Self = Self(0); pub const REMOVED: Self = Self(1); pub const ENABLED: Self = Self(2); pub const DISABLED: Self = Self(3); pub const UNRECOVERABLE: Self = Self(4); pub const CONTROL_CHANGED: Self = Self(5); } impl From for u8 { #[inline] fn from(input: DeviceChange) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DeviceChange) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: DeviceChange) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceChange) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: DeviceChange) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DeviceChange) -> Self { Some(u32::from(input.0)) } } impl From for DeviceChange { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for DeviceChange { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ADDED.0.into(), "ADDED", "Added"), (Self::REMOVED.0.into(), "REMOVED", "Removed"), (Self::ENABLED.0.into(), "ENABLED", "Enabled"), (Self::DISABLED.0.into(), "DISABLED", "Disabled"), (Self::UNRECOVERABLE.0.into(), "UNRECOVERABLE", "Unrecoverable"), (Self::CONTROL_CHANGED.0.into(), "CONTROL_CHANGED", "ControlChanged"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the DevicePresenceNotify event pub const DEVICE_PRESENCE_NOTIFY_EVENT: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DevicePresenceNotifyEvent { pub response_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub devchange: DeviceChange, pub device_id: u8, pub control: u16, } impl TryParse for DevicePresenceNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (devchange, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (control, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let devchange = devchange.into(); let result = DevicePresenceNotifyEvent { response_type, sequence, time, devchange, device_id, control }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DevicePresenceNotifyEvent> for [u8; 32] { fn from(input: &DevicePresenceNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let devchange_bytes = u8::from(input.devchange).serialize(); let device_id_bytes = input.device_id.serialize(); let control_bytes = input.control.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], devchange_bytes[0], device_id_bytes[0], control_bytes[0], control_bytes[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: DevicePresenceNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the DevicePropertyNotify event pub const DEVICE_PROPERTY_NOTIFY_EVENT: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DevicePropertyNotifyEvent { pub response_type: u8, pub state: xproto::Property, pub sequence: u16, pub time: xproto::Timestamp, pub property: xproto::Atom, pub device_id: u8, } impl TryParse for DevicePropertyNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let remaining = remaining.get(19..).ok_or(ParseError::InsufficientData)?; let (device_id, remaining) = u8::try_parse(remaining)?; let state = state.into(); let result = DevicePropertyNotifyEvent { response_type, state, sequence, time, property, device_id }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DevicePropertyNotifyEvent> for [u8; 32] { fn from(input: &DevicePropertyNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let state_bytes = u8::from(input.state).serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let property_bytes = input.property.serialize(); let device_id_bytes = input.device_id.serialize(); [ response_type_bytes[0], state_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, device_id_bytes[0], ] } } impl From for [u8; 32] { fn from(input: DevicePropertyNotifyEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ChangeReason(u8); impl ChangeReason { pub const SLAVE_SWITCH: Self = Self(1); pub const DEVICE_CHANGE: Self = Self(2); } impl From for u8 { #[inline] fn from(input: ChangeReason) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ChangeReason) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ChangeReason) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeReason) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ChangeReason) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ChangeReason) -> Self { Some(u32::from(input.0)) } } impl From for ChangeReason { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ChangeReason { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SLAVE_SWITCH.0.into(), "SLAVE_SWITCH", "SlaveSwitch"), (Self::DEVICE_CHANGE.0.into(), "DEVICE_CHANGE", "DeviceChange"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the DeviceChanged event pub const DEVICE_CHANGED_EVENT: u16 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceChangedEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub sourceid: DeviceId, pub reason: ChangeReason, pub classes: Vec, } impl TryParse for DeviceChangedEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (reason, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(11..).ok_or(ParseError::InsufficientData)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let reason = reason.into(); let result = DeviceChangedEvent { response_type, extension, sequence, length, event_type, deviceid, time, sourceid, reason, classes }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl DeviceChangedEvent { /// Get the value of the `num_classes` field. /// /// The `num_classes` field is used as the length field of the `classes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_classes(&self) -> u16 { self.classes.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct KeyEventFlags(u32); impl KeyEventFlags { pub const KEY_REPEAT: Self = Self(1 << 16); } impl From for u32 { #[inline] fn from(input: KeyEventFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: KeyEventFlags) -> Self { Some(input.0) } } impl From for KeyEventFlags { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for KeyEventFlags { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for KeyEventFlags { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for KeyEventFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEY_REPEAT.0, "KEY_REPEAT", "KeyRepeat"), ]; pretty_print_bitmask(fmt, self.0, &variants) } } bitmask_binop!(KeyEventFlags, u32); /// Opcode for the KeyPress event pub const KEY_PRESS_EVENT: u16 = 2; #[derive(Debug, Clone, PartialEq, Eq)] pub struct KeyPressEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub detail: u32, pub root: xproto::Window, pub event: xproto::Window, pub child: xproto::Window, pub root_x: Fp1616, pub root_y: Fp1616, pub event_x: Fp1616, pub event_y: Fp1616, pub sourceid: DeviceId, pub flags: u32, pub mods: ModifierInfo, pub group: GroupInfo, pub button_mask: Vec, pub valuator_mask: Vec, pub axisvalues: Vec, } impl TryParse for KeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (detail, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (event, remaining) = xproto::Window::try_parse(remaining)?; let (child, remaining) = xproto::Window::try_parse(remaining)?; let (root_x, remaining) = Fp1616::try_parse(remaining)?; let (root_y, remaining) = Fp1616::try_parse(remaining)?; let (event_x, remaining) = Fp1616::try_parse(remaining)?; let (event_y, remaining) = Fp1616::try_parse(remaining)?; let (buttons_len, remaining) = u16::try_parse(remaining)?; let (valuators_len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let (mods, remaining) = ModifierInfo::try_parse(remaining)?; let (group, remaining) = GroupInfo::try_parse(remaining)?; let (button_mask, remaining) = crate::x11_utils::parse_list::(remaining, buttons_len.try_to_usize()?)?; let (valuator_mask, remaining) = crate::x11_utils::parse_list::(remaining, valuators_len.try_to_usize()?)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = KeyPressEvent { response_type, extension, sequence, length, event_type, deviceid, time, detail, root, event, child, root_x, root_y, event_x, event_y, sourceid, flags, mods, group, button_mask, valuator_mask, axisvalues }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl KeyPressEvent { /// Get the value of the `buttons_len` field. /// /// The `buttons_len` field is used as the length field of the `button_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn buttons_len(&self) -> u16 { self.button_mask.len() .try_into().unwrap() } /// Get the value of the `valuators_len` field. /// /// The `valuators_len` field is used as the length field of the `valuator_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn valuators_len(&self) -> u16 { self.valuator_mask.len() .try_into().unwrap() } } /// Opcode for the KeyRelease event pub const KEY_RELEASE_EVENT: u16 = 3; pub type KeyReleaseEvent = KeyPressEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct PointerEventFlags(u32); impl PointerEventFlags { pub const POINTER_EMULATED: Self = Self(1 << 16); } impl From for u32 { #[inline] fn from(input: PointerEventFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PointerEventFlags) -> Self { Some(input.0) } } impl From for PointerEventFlags { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for PointerEventFlags { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for PointerEventFlags { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for PointerEventFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::POINTER_EMULATED.0, "POINTER_EMULATED", "PointerEmulated"), ]; pretty_print_bitmask(fmt, self.0, &variants) } } bitmask_binop!(PointerEventFlags, u32); /// Opcode for the ButtonPress event pub const BUTTON_PRESS_EVENT: u16 = 4; #[derive(Debug, Clone, PartialEq, Eq)] pub struct ButtonPressEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub detail: u32, pub root: xproto::Window, pub event: xproto::Window, pub child: xproto::Window, pub root_x: Fp1616, pub root_y: Fp1616, pub event_x: Fp1616, pub event_y: Fp1616, pub sourceid: DeviceId, pub flags: u32, pub mods: ModifierInfo, pub group: GroupInfo, pub button_mask: Vec, pub valuator_mask: Vec, pub axisvalues: Vec, } impl TryParse for ButtonPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (detail, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (event, remaining) = xproto::Window::try_parse(remaining)?; let (child, remaining) = xproto::Window::try_parse(remaining)?; let (root_x, remaining) = Fp1616::try_parse(remaining)?; let (root_y, remaining) = Fp1616::try_parse(remaining)?; let (event_x, remaining) = Fp1616::try_parse(remaining)?; let (event_y, remaining) = Fp1616::try_parse(remaining)?; let (buttons_len, remaining) = u16::try_parse(remaining)?; let (valuators_len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let (mods, remaining) = ModifierInfo::try_parse(remaining)?; let (group, remaining) = GroupInfo::try_parse(remaining)?; let (button_mask, remaining) = crate::x11_utils::parse_list::(remaining, buttons_len.try_to_usize()?)?; let (valuator_mask, remaining) = crate::x11_utils::parse_list::(remaining, valuators_len.try_to_usize()?)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = ButtonPressEvent { response_type, extension, sequence, length, event_type, deviceid, time, detail, root, event, child, root_x, root_y, event_x, event_y, sourceid, flags, mods, group, button_mask, valuator_mask, axisvalues }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ButtonPressEvent { /// Get the value of the `buttons_len` field. /// /// The `buttons_len` field is used as the length field of the `button_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn buttons_len(&self) -> u16 { self.button_mask.len() .try_into().unwrap() } /// Get the value of the `valuators_len` field. /// /// The `valuators_len` field is used as the length field of the `valuator_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn valuators_len(&self) -> u16 { self.valuator_mask.len() .try_into().unwrap() } } /// Opcode for the ButtonRelease event pub const BUTTON_RELEASE_EVENT: u16 = 5; pub type ButtonReleaseEvent = ButtonPressEvent; /// Opcode for the Motion event pub const MOTION_EVENT: u16 = 6; pub type MotionEvent = ButtonPressEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct NotifyMode(u8); impl NotifyMode { pub const NORMAL: Self = Self(0); pub const GRAB: Self = Self(1); pub const UNGRAB: Self = Self(2); pub const WHILE_GRABBED: Self = Self(3); pub const PASSIVE_GRAB: Self = Self(4); pub const PASSIVE_UNGRAB: Self = Self(5); } impl From for u8 { #[inline] fn from(input: NotifyMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: NotifyMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: NotifyMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: NotifyMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyMode) -> Self { Some(u32::from(input.0)) } } impl From for NotifyMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for NotifyMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NORMAL.0.into(), "NORMAL", "Normal"), (Self::GRAB.0.into(), "GRAB", "Grab"), (Self::UNGRAB.0.into(), "UNGRAB", "Ungrab"), (Self::WHILE_GRABBED.0.into(), "WHILE_GRABBED", "WhileGrabbed"), (Self::PASSIVE_GRAB.0.into(), "PASSIVE_GRAB", "PassiveGrab"), (Self::PASSIVE_UNGRAB.0.into(), "PASSIVE_UNGRAB", "PassiveUngrab"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct NotifyDetail(u8); impl NotifyDetail { pub const ANCESTOR: Self = Self(0); pub const VIRTUAL: Self = Self(1); pub const INFERIOR: Self = Self(2); pub const NONLINEAR: Self = Self(3); pub const NONLINEAR_VIRTUAL: Self = Self(4); pub const POINTER: Self = Self(5); pub const POINTER_ROOT: Self = Self(6); pub const NONE: Self = Self(7); } impl From for u8 { #[inline] fn from(input: NotifyDetail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: NotifyDetail) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: NotifyDetail) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyDetail) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: NotifyDetail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyDetail) -> Self { Some(u32::from(input.0)) } } impl From for NotifyDetail { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for NotifyDetail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ANCESTOR.0.into(), "ANCESTOR", "Ancestor"), (Self::VIRTUAL.0.into(), "VIRTUAL", "Virtual"), (Self::INFERIOR.0.into(), "INFERIOR", "Inferior"), (Self::NONLINEAR.0.into(), "NONLINEAR", "Nonlinear"), (Self::NONLINEAR_VIRTUAL.0.into(), "NONLINEAR_VIRTUAL", "NonlinearVirtual"), (Self::POINTER.0.into(), "POINTER", "Pointer"), (Self::POINTER_ROOT.0.into(), "POINTER_ROOT", "PointerRoot"), (Self::NONE.0.into(), "NONE", "None"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the Enter event pub const ENTER_EVENT: u16 = 7; #[derive(Debug, Clone, PartialEq, Eq)] pub struct EnterEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub sourceid: DeviceId, pub mode: NotifyMode, pub detail: NotifyDetail, pub root: xproto::Window, pub event: xproto::Window, pub child: xproto::Window, pub root_x: Fp1616, pub root_y: Fp1616, pub event_x: Fp1616, pub event_y: Fp1616, pub same_screen: bool, pub focus: bool, pub mods: ModifierInfo, pub group: GroupInfo, pub buttons: Vec, } impl TryParse for EnterEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (event, remaining) = xproto::Window::try_parse(remaining)?; let (child, remaining) = xproto::Window::try_parse(remaining)?; let (root_x, remaining) = Fp1616::try_parse(remaining)?; let (root_y, remaining) = Fp1616::try_parse(remaining)?; let (event_x, remaining) = Fp1616::try_parse(remaining)?; let (event_y, remaining) = Fp1616::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let (focus, remaining) = bool::try_parse(remaining)?; let (buttons_len, remaining) = u16::try_parse(remaining)?; let (mods, remaining) = ModifierInfo::try_parse(remaining)?; let (group, remaining) = GroupInfo::try_parse(remaining)?; let (buttons, remaining) = crate::x11_utils::parse_list::(remaining, buttons_len.try_to_usize()?)?; let mode = mode.into(); let detail = detail.into(); let result = EnterEvent { response_type, extension, sequence, length, event_type, deviceid, time, sourceid, mode, detail, root, event, child, root_x, root_y, event_x, event_y, same_screen, focus, mods, group, buttons }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl EnterEvent { /// Get the value of the `buttons_len` field. /// /// The `buttons_len` field is used as the length field of the `buttons` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn buttons_len(&self) -> u16 { self.buttons.len() .try_into().unwrap() } } /// Opcode for the Leave event pub const LEAVE_EVENT: u16 = 8; pub type LeaveEvent = EnterEvent; /// Opcode for the FocusIn event pub const FOCUS_IN_EVENT: u16 = 9; pub type FocusInEvent = EnterEvent; /// Opcode for the FocusOut event pub const FOCUS_OUT_EVENT: u16 = 10; pub type FocusOutEvent = EnterEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct HierarchyMask(u8); impl HierarchyMask { pub const MASTER_ADDED: Self = Self(1 << 0); pub const MASTER_REMOVED: Self = Self(1 << 1); pub const SLAVE_ADDED: Self = Self(1 << 2); pub const SLAVE_REMOVED: Self = Self(1 << 3); pub const SLAVE_ATTACHED: Self = Self(1 << 4); pub const SLAVE_DETACHED: Self = Self(1 << 5); pub const DEVICE_ENABLED: Self = Self(1 << 6); pub const DEVICE_DISABLED: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: HierarchyMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: HierarchyMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: HierarchyMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: HierarchyMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: HierarchyMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: HierarchyMask) -> Self { Some(u32::from(input.0)) } } impl From for HierarchyMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for HierarchyMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::MASTER_ADDED.0.into(), "MASTER_ADDED", "MasterAdded"), (Self::MASTER_REMOVED.0.into(), "MASTER_REMOVED", "MasterRemoved"), (Self::SLAVE_ADDED.0.into(), "SLAVE_ADDED", "SlaveAdded"), (Self::SLAVE_REMOVED.0.into(), "SLAVE_REMOVED", "SlaveRemoved"), (Self::SLAVE_ATTACHED.0.into(), "SLAVE_ATTACHED", "SlaveAttached"), (Self::SLAVE_DETACHED.0.into(), "SLAVE_DETACHED", "SlaveDetached"), (Self::DEVICE_ENABLED.0.into(), "DEVICE_ENABLED", "DeviceEnabled"), (Self::DEVICE_DISABLED.0.into(), "DEVICE_DISABLED", "DeviceDisabled"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(HierarchyMask, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct HierarchyInfo { pub deviceid: DeviceId, pub attachment: DeviceId, pub type_: DeviceType, pub enabled: bool, pub flags: u32, } impl TryParse for HierarchyInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (attachment, remaining) = DeviceId::try_parse(remaining)?; let (type_, remaining) = u8::try_parse(remaining)?; let (enabled, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let type_ = type_.into(); let result = HierarchyInfo { deviceid, attachment, type_, enabled, flags }; Ok((result, remaining)) } } impl Serialize for HierarchyInfo { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let deviceid_bytes = self.deviceid.serialize(); let attachment_bytes = self.attachment.serialize(); let type_bytes = (u16::from(self.type_) as u8).serialize(); let enabled_bytes = self.enabled.serialize(); let flags_bytes = self.flags.serialize(); [ deviceid_bytes[0], deviceid_bytes[1], attachment_bytes[0], attachment_bytes[1], type_bytes[0], enabled_bytes[0], 0, 0, flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.deviceid.serialize_into(bytes); self.attachment.serialize_into(bytes); (u16::from(self.type_) as u8).serialize_into(bytes); self.enabled.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.flags.serialize_into(bytes); } } /// Opcode for the Hierarchy event pub const HIERARCHY_EVENT: u16 = 11; #[derive(Debug, Clone, PartialEq, Eq)] pub struct HierarchyEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub flags: u32, pub infos: Vec, } impl TryParse for HierarchyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let (num_infos, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(10..).ok_or(ParseError::InsufficientData)?; let (infos, remaining) = crate::x11_utils::parse_list::(remaining, num_infos.try_to_usize()?)?; let result = HierarchyEvent { response_type, extension, sequence, length, event_type, deviceid, time, flags, infos }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl HierarchyEvent { /// Get the value of the `num_infos` field. /// /// The `num_infos` field is used as the length field of the `infos` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_infos(&self) -> u16 { self.infos.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct PropertyFlag(u8); impl PropertyFlag { pub const DELETED: Self = Self(0); pub const CREATED: Self = Self(1); pub const MODIFIED: Self = Self(2); } impl From for u8 { #[inline] fn from(input: PropertyFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PropertyFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: PropertyFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: PropertyFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: PropertyFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PropertyFlag) -> Self { Some(u32::from(input.0)) } } impl From for PropertyFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for PropertyFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DELETED.0.into(), "DELETED", "Deleted"), (Self::CREATED.0.into(), "CREATED", "Created"), (Self::MODIFIED.0.into(), "MODIFIED", "Modified"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the Property event pub const PROPERTY_EVENT: u16 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PropertyEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub property: xproto::Atom, pub what: PropertyFlag, } impl TryParse for PropertyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let (what, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(11..).ok_or(ParseError::InsufficientData)?; let what = what.into(); let result = PropertyEvent { response_type, extension, sequence, length, event_type, deviceid, time, property, what }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the RawKeyPress event pub const RAW_KEY_PRESS_EVENT: u16 = 13; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RawKeyPressEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub detail: u32, pub sourceid: DeviceId, pub flags: u32, pub valuator_mask: Vec, pub axisvalues: Vec, pub axisvalues_raw: Vec, } impl TryParse for RawKeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (detail, remaining) = u32::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (valuators_len, remaining) = u16::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (valuator_mask, remaining) = crate::x11_utils::parse_list::(remaining, valuators_len.try_to_usize()?)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let (axisvalues_raw, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = RawKeyPressEvent { response_type, extension, sequence, length, event_type, deviceid, time, detail, sourceid, flags, valuator_mask, axisvalues, axisvalues_raw }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl RawKeyPressEvent { /// Get the value of the `valuators_len` field. /// /// The `valuators_len` field is used as the length field of the `valuator_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn valuators_len(&self) -> u16 { self.valuator_mask.len() .try_into().unwrap() } } /// Opcode for the RawKeyRelease event pub const RAW_KEY_RELEASE_EVENT: u16 = 14; pub type RawKeyReleaseEvent = RawKeyPressEvent; /// Opcode for the RawButtonPress event pub const RAW_BUTTON_PRESS_EVENT: u16 = 15; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RawButtonPressEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub detail: u32, pub sourceid: DeviceId, pub flags: u32, pub valuator_mask: Vec, pub axisvalues: Vec, pub axisvalues_raw: Vec, } impl TryParse for RawButtonPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (detail, remaining) = u32::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (valuators_len, remaining) = u16::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (valuator_mask, remaining) = crate::x11_utils::parse_list::(remaining, valuators_len.try_to_usize()?)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let (axisvalues_raw, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = RawButtonPressEvent { response_type, extension, sequence, length, event_type, deviceid, time, detail, sourceid, flags, valuator_mask, axisvalues, axisvalues_raw }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl RawButtonPressEvent { /// Get the value of the `valuators_len` field. /// /// The `valuators_len` field is used as the length field of the `valuator_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn valuators_len(&self) -> u16 { self.valuator_mask.len() .try_into().unwrap() } } /// Opcode for the RawButtonRelease event pub const RAW_BUTTON_RELEASE_EVENT: u16 = 16; pub type RawButtonReleaseEvent = RawButtonPressEvent; /// Opcode for the RawMotion event pub const RAW_MOTION_EVENT: u16 = 17; pub type RawMotionEvent = RawButtonPressEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct TouchEventFlags(u32); impl TouchEventFlags { pub const TOUCH_PENDING_END: Self = Self(1 << 16); pub const TOUCH_EMULATING_POINTER: Self = Self(1 << 17); } impl From for u32 { #[inline] fn from(input: TouchEventFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: TouchEventFlags) -> Self { Some(input.0) } } impl From for TouchEventFlags { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for TouchEventFlags { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for TouchEventFlags { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for TouchEventFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::TOUCH_PENDING_END.0, "TOUCH_PENDING_END", "TouchPendingEnd"), (Self::TOUCH_EMULATING_POINTER.0, "TOUCH_EMULATING_POINTER", "TouchEmulatingPointer"), ]; pretty_print_bitmask(fmt, self.0, &variants) } } bitmask_binop!(TouchEventFlags, u32); /// Opcode for the TouchBegin event pub const TOUCH_BEGIN_EVENT: u16 = 18; #[derive(Debug, Clone, PartialEq, Eq)] pub struct TouchBeginEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub detail: u32, pub root: xproto::Window, pub event: xproto::Window, pub child: xproto::Window, pub root_x: Fp1616, pub root_y: Fp1616, pub event_x: Fp1616, pub event_y: Fp1616, pub sourceid: DeviceId, pub flags: u32, pub mods: ModifierInfo, pub group: GroupInfo, pub button_mask: Vec, pub valuator_mask: Vec, pub axisvalues: Vec, } impl TryParse for TouchBeginEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (detail, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (event, remaining) = xproto::Window::try_parse(remaining)?; let (child, remaining) = xproto::Window::try_parse(remaining)?; let (root_x, remaining) = Fp1616::try_parse(remaining)?; let (root_y, remaining) = Fp1616::try_parse(remaining)?; let (event_x, remaining) = Fp1616::try_parse(remaining)?; let (event_y, remaining) = Fp1616::try_parse(remaining)?; let (buttons_len, remaining) = u16::try_parse(remaining)?; let (valuators_len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let (mods, remaining) = ModifierInfo::try_parse(remaining)?; let (group, remaining) = GroupInfo::try_parse(remaining)?; let (button_mask, remaining) = crate::x11_utils::parse_list::(remaining, buttons_len.try_to_usize()?)?; let (valuator_mask, remaining) = crate::x11_utils::parse_list::(remaining, valuators_len.try_to_usize()?)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = TouchBeginEvent { response_type, extension, sequence, length, event_type, deviceid, time, detail, root, event, child, root_x, root_y, event_x, event_y, sourceid, flags, mods, group, button_mask, valuator_mask, axisvalues }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl TouchBeginEvent { /// Get the value of the `buttons_len` field. /// /// The `buttons_len` field is used as the length field of the `button_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn buttons_len(&self) -> u16 { self.button_mask.len() .try_into().unwrap() } /// Get the value of the `valuators_len` field. /// /// The `valuators_len` field is used as the length field of the `valuator_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn valuators_len(&self) -> u16 { self.valuator_mask.len() .try_into().unwrap() } } /// Opcode for the TouchUpdate event pub const TOUCH_UPDATE_EVENT: u16 = 19; pub type TouchUpdateEvent = TouchBeginEvent; /// Opcode for the TouchEnd event pub const TOUCH_END_EVENT: u16 = 20; pub type TouchEndEvent = TouchBeginEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct TouchOwnershipFlags(u32); impl TouchOwnershipFlags { pub const NONE: Self = Self(0); } impl From for u32 { #[inline] fn from(input: TouchOwnershipFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: TouchOwnershipFlags) -> Self { Some(input.0) } } impl From for TouchOwnershipFlags { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for TouchOwnershipFlags { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for TouchOwnershipFlags { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for TouchOwnershipFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NONE.0, "NONE", "None"), ]; pretty_print_enum(fmt, self.0, &variants) } } /// Opcode for the TouchOwnership event pub const TOUCH_OWNERSHIP_EVENT: u16 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct TouchOwnershipEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub touchid: u32, pub root: xproto::Window, pub event: xproto::Window, pub child: xproto::Window, pub sourceid: DeviceId, pub flags: TouchOwnershipFlags, } impl TryParse for TouchOwnershipEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (touchid, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (event, remaining) = xproto::Window::try_parse(remaining)?; let (child, remaining) = xproto::Window::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let flags = flags.into(); let result = TouchOwnershipEvent { response_type, extension, sequence, length, event_type, deviceid, time, touchid, root, event, child, sourceid, flags }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the RawTouchBegin event pub const RAW_TOUCH_BEGIN_EVENT: u16 = 22; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RawTouchBeginEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub detail: u32, pub sourceid: DeviceId, pub flags: u32, pub valuator_mask: Vec, pub axisvalues: Vec, pub axisvalues_raw: Vec, } impl TryParse for RawTouchBeginEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (detail, remaining) = u32::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let (valuators_len, remaining) = u16::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (valuator_mask, remaining) = crate::x11_utils::parse_list::(remaining, valuators_len.try_to_usize()?)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let (axisvalues_raw, remaining) = crate::x11_utils::parse_list::(remaining, valuator_mask.iter().try_fold(0u32, |acc, x| acc.checked_add((*x).count_ones()).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = RawTouchBeginEvent { response_type, extension, sequence, length, event_type, deviceid, time, detail, sourceid, flags, valuator_mask, axisvalues, axisvalues_raw }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl RawTouchBeginEvent { /// Get the value of the `valuators_len` field. /// /// The `valuators_len` field is used as the length field of the `valuator_mask` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn valuators_len(&self) -> u16 { self.valuator_mask.len() .try_into().unwrap() } } /// Opcode for the RawTouchUpdate event pub const RAW_TOUCH_UPDATE_EVENT: u16 = 23; pub type RawTouchUpdateEvent = RawTouchBeginEvent; /// Opcode for the RawTouchEnd event pub const RAW_TOUCH_END_EVENT: u16 = 24; pub type RawTouchEndEvent = RawTouchBeginEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct BarrierFlags(u8); impl BarrierFlags { pub const POINTER_RELEASED: Self = Self(1 << 0); pub const DEVICE_IS_GRABBED: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: BarrierFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BarrierFlags) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: BarrierFlags) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: BarrierFlags) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: BarrierFlags) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BarrierFlags) -> Self { Some(u32::from(input.0)) } } impl From for BarrierFlags { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for BarrierFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::POINTER_RELEASED.0.into(), "POINTER_RELEASED", "PointerReleased"), (Self::DEVICE_IS_GRABBED.0.into(), "DEVICE_IS_GRABBED", "DeviceIsGrabbed"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(BarrierFlags, u8); /// Opcode for the BarrierHit event pub const BARRIER_HIT_EVENT: u16 = 25; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BarrierHitEvent { pub response_type: u8, pub extension: u8, pub sequence: u16, pub length: u32, pub event_type: u16, pub deviceid: DeviceId, pub time: xproto::Timestamp, pub eventid: u32, pub root: xproto::Window, pub event: xproto::Window, pub barrier: xfixes::Barrier, pub dtime: u32, pub flags: u32, pub sourceid: DeviceId, pub root_x: Fp1616, pub root_y: Fp1616, pub dx: Fp3232, pub dy: Fp3232, } impl TryParse for BarrierHitEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_type, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (eventid, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let (event, remaining) = xproto::Window::try_parse(remaining)?; let (barrier, remaining) = xfixes::Barrier::try_parse(remaining)?; let (dtime, remaining) = u32::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (root_x, remaining) = Fp1616::try_parse(remaining)?; let (root_y, remaining) = Fp1616::try_parse(remaining)?; let (dx, remaining) = Fp3232::try_parse(remaining)?; let (dy, remaining) = Fp3232::try_parse(remaining)?; let result = BarrierHitEvent { response_type, extension, sequence, length, event_type, deviceid, time, eventid, root, event, barrier, dtime, flags, sourceid, root_x, root_y, dx, dy }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the BarrierLeave event pub const BARRIER_LEAVE_EVENT: u16 = 26; pub type BarrierLeaveEvent = BarrierHitEvent; #[derive(Debug, Copy, Clone)] pub struct EventForSend([u8; 32]); impl EventForSend { pub fn as_device_valuator_event(&self) -> DeviceValuatorEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceValuatorEvent::try_parse(value).unwrap().0 } pub fn as_device_key_press_event(&self) -> DeviceKeyPressEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceKeyPressEvent::try_parse(value).unwrap().0 } pub fn as_device_key_release_event(&self) -> DeviceKeyReleaseEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceKeyReleaseEvent::try_parse(value).unwrap().0 } pub fn as_device_button_press_event(&self) -> DeviceButtonPressEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceButtonPressEvent::try_parse(value).unwrap().0 } pub fn as_device_button_release_event(&self) -> DeviceButtonReleaseEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceButtonReleaseEvent::try_parse(value).unwrap().0 } pub fn as_device_motion_notify_event(&self) -> DeviceMotionNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceMotionNotifyEvent::try_parse(value).unwrap().0 } pub fn as_device_focus_in_event(&self) -> DeviceFocusInEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceFocusInEvent::try_parse(value).unwrap().0 } pub fn as_device_focus_out_event(&self) -> DeviceFocusOutEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceFocusOutEvent::try_parse(value).unwrap().0 } pub fn as_proximity_in_event(&self) -> ProximityInEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail ProximityInEvent::try_parse(value).unwrap().0 } pub fn as_proximity_out_event(&self) -> ProximityOutEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail ProximityOutEvent::try_parse(value).unwrap().0 } pub fn as_device_state_notify_event(&self) -> DeviceStateNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceStateNotifyEvent::try_parse(value).unwrap().0 } pub fn as_device_mapping_notify_event(&self) -> DeviceMappingNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceMappingNotifyEvent::try_parse(value).unwrap().0 } pub fn as_change_device_notify_event(&self) -> ChangeDeviceNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail ChangeDeviceNotifyEvent::try_parse(value).unwrap().0 } pub fn as_device_key_state_notify_event(&self) -> DeviceKeyStateNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceKeyStateNotifyEvent::try_parse(value).unwrap().0 } pub fn as_device_button_state_notify_event(&self) -> DeviceButtonStateNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DeviceButtonStateNotifyEvent::try_parse(value).unwrap().0 } pub fn as_device_presence_notify_event(&self) -> DevicePresenceNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DevicePresenceNotifyEvent::try_parse(value).unwrap().0 } pub fn as_device_property_notify_event(&self) -> DevicePropertyNotifyEvent { let value: &[u8] = &self.0; // FIXME: event parsing can fail DevicePropertyNotifyEvent::try_parse(value).unwrap().0 } } impl Serialize for EventForSend { type Bytes = [u8; 32]; fn serialize(&self) -> [u8; 32] { self.0 } fn serialize_into(&self, bytes: &mut Vec) { bytes.extend_from_slice(&self.0); } } impl TryParse for EventForSend { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let inner: [u8; 32] = value.get(..32) .ok_or(ParseError::InsufficientData)? .try_into() .unwrap(); let result = EventForSend(inner); Ok((result, &value[32..])) } } impl From for EventForSend { fn from(value: DeviceValuatorEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DeviceValuatorEvent> for EventForSend { fn from(value: &DeviceValuatorEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DeviceKeyPressEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DeviceKeyPressEvent> for EventForSend { fn from(value: &DeviceKeyPressEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DeviceFocusInEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DeviceFocusInEvent> for EventForSend { fn from(value: &DeviceFocusInEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DeviceStateNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DeviceStateNotifyEvent> for EventForSend { fn from(value: &DeviceStateNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DeviceMappingNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DeviceMappingNotifyEvent> for EventForSend { fn from(value: &DeviceMappingNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: ChangeDeviceNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&ChangeDeviceNotifyEvent> for EventForSend { fn from(value: &ChangeDeviceNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DeviceKeyStateNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DeviceKeyStateNotifyEvent> for EventForSend { fn from(value: &DeviceKeyStateNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DeviceButtonStateNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DeviceButtonStateNotifyEvent> for EventForSend { fn from(value: &DeviceButtonStateNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DevicePresenceNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DevicePresenceNotifyEvent> for EventForSend { fn from(value: &DevicePresenceNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From for EventForSend { fn from(value: DevicePropertyNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } impl From<&DevicePropertyNotifyEvent> for EventForSend { fn from(value: &DevicePropertyNotifyEvent) -> Self { Self(<[u8; 32]>::from(value)) } } /// Opcode for the SendExtensionEvent request pub const SEND_EXTENSION_EVENT_REQUEST: u8 = 31; #[derive(Debug, Clone)] pub struct SendExtensionEventRequest<'input> { pub destination: xproto::Window, pub device_id: u8, pub propagate: bool, pub events: Cow<'input, [EventForSend]>, pub classes: Cow<'input, [EventClass]>, } impl<'input> SendExtensionEventRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let destination_bytes = self.destination.serialize(); let device_id_bytes = self.device_id.serialize(); let propagate_bytes = self.propagate.serialize(); let num_classes = u16::try_from(self.classes.len()).expect("`classes` has too many elements"); let num_classes_bytes = num_classes.serialize(); let num_events = u8::try_from(self.events.len()).expect("`events` has too many elements"); let num_events_bytes = num_events.serialize(); let mut request0 = vec![ extension_information.major_opcode, SEND_EXTENSION_EVENT_REQUEST, 0, 0, destination_bytes[0], destination_bytes[1], destination_bytes[2], destination_bytes[3], device_id_bytes[0], propagate_bytes[0], num_classes_bytes[0], num_classes_bytes[1], num_events_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); let events_bytes = self.events.serialize(); let length_so_far = length_so_far + events_bytes.len(); let classes_bytes = self.classes.serialize(); let length_so_far = length_so_far + classes_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), events_bytes.into(), classes_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SEND_EXTENSION_EVENT_REQUEST { return Err(ParseError::InvalidValue); } let (destination, remaining) = xproto::Window::try_parse(value)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (propagate, remaining) = bool::try_parse(remaining)?; let (num_classes, remaining) = u16::try_parse(remaining)?; let (num_events, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (events, remaining) = crate::x11_utils::parse_list::(remaining, num_events.try_to_usize()?)?; let (classes, remaining) = crate::x11_utils::parse_list::(remaining, num_classes.try_to_usize()?)?; let _ = remaining; Ok(SendExtensionEventRequest { destination, device_id, propagate, events: Cow::Owned(events), classes: Cow::Owned(classes), }) } /// Clone all borrowed data in this SendExtensionEventRequest. pub fn into_owned(self) -> SendExtensionEventRequest<'static> { SendExtensionEventRequest { destination: self.destination, device_id: self.device_id, propagate: self.propagate, events: Cow::Owned(self.events.into_owned()), classes: Cow::Owned(self.classes.into_owned()), } } } impl<'input> Request for SendExtensionEventRequest<'input> { type Reply = (); } pub fn send_extension_event<'c, 'input, Conn>(conn: &'c Conn, destination: xproto::Window, device_id: u8, propagate: bool, events: &'input [EventForSend], classes: &'input [EventClass]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SendExtensionEventRequest { destination, device_id, propagate, events: Cow::Borrowed(events), classes: Cow::Borrowed(classes), }; request0.send(conn) } /// Opcode for the Device error pub const DEVICE_ERROR: u8 = 0; /// Opcode for the Event error pub const EVENT_ERROR: u8 = 1; /// Opcode for the Mode error pub const MODE_ERROR: u8 = 2; /// Opcode for the DeviceBusy error pub const DEVICE_BUSY_ERROR: u8 = 3; /// Opcode for the Class error pub const CLASS_ERROR: u8 = 4; /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xinput_get_extension_version<'c, 'input>(&'c self, name: &'input [u8]) -> Result, ConnectionError> { get_extension_version(self, name) } fn xinput_list_input_devices(&self) -> Result, ConnectionError> { list_input_devices(self) } fn xinput_open_device(&self, device_id: u8) -> Result, ConnectionError> { open_device(self, device_id) } fn xinput_close_device(&self, device_id: u8) -> Result, ConnectionError> { close_device(self, device_id) } fn xinput_set_device_mode(&self, device_id: u8, mode: ValuatorMode) -> Result, ConnectionError> { set_device_mode(self, device_id, mode) } fn xinput_select_extension_event<'c, 'input>(&'c self, window: xproto::Window, classes: &'input [EventClass]) -> Result, ConnectionError> { select_extension_event(self, window, classes) } fn xinput_get_selected_extension_events(&self, window: xproto::Window) -> Result, ConnectionError> { get_selected_extension_events(self, window) } fn xinput_change_device_dont_propagate_list<'c, 'input>(&'c self, window: xproto::Window, mode: PropagateMode, classes: &'input [EventClass]) -> Result, ConnectionError> { change_device_dont_propagate_list(self, window, mode, classes) } fn xinput_get_device_dont_propagate_list(&self, window: xproto::Window) -> Result, ConnectionError> { get_device_dont_propagate_list(self, window) } fn xinput_get_device_motion_events(&self, start: xproto::Timestamp, stop: A, device_id: u8) -> Result, ConnectionError> where A: Into, { get_device_motion_events(self, start, stop, device_id) } fn xinput_change_keyboard_device(&self, device_id: u8) -> Result, ConnectionError> { change_keyboard_device(self, device_id) } fn xinput_change_pointer_device(&self, x_axis: u8, y_axis: u8, device_id: u8) -> Result, ConnectionError> { change_pointer_device(self, x_axis, y_axis, device_id) } fn xinput_grab_device<'c, 'input, A>(&'c self, grab_window: xproto::Window, time: A, this_device_mode: xproto::GrabMode, other_device_mode: xproto::GrabMode, owner_events: bool, device_id: u8, classes: &'input [EventClass]) -> Result, ConnectionError> where A: Into, { grab_device(self, grab_window, time, this_device_mode, other_device_mode, owner_events, device_id, classes) } fn xinput_ungrab_device(&self, time: A, device_id: u8) -> Result, ConnectionError> where A: Into, { ungrab_device(self, time, device_id) } fn xinput_grab_device_key<'c, 'input, A, B, C>(&'c self, grab_window: xproto::Window, modifiers: A, modifier_device: B, grabbed_device: u8, key: C, this_device_mode: xproto::GrabMode, other_device_mode: xproto::GrabMode, owner_events: bool, classes: &'input [EventClass]) -> Result, ConnectionError> where A: Into, B: Into, C: Into, { grab_device_key(self, grab_window, modifiers, modifier_device, grabbed_device, key, this_device_mode, other_device_mode, owner_events, classes) } fn xinput_ungrab_device_key(&self, grab_window: xproto::Window, modifiers: A, modifier_device: B, key: C, grabbed_device: u8) -> Result, ConnectionError> where A: Into, B: Into, C: Into, { ungrab_device_key(self, grab_window, modifiers, modifier_device, key, grabbed_device) } fn xinput_grab_device_button<'c, 'input, A, B, C>(&'c self, grab_window: xproto::Window, grabbed_device: u8, modifier_device: A, modifiers: B, this_device_mode: xproto::GrabMode, other_device_mode: xproto::GrabMode, button: C, owner_events: bool, classes: &'input [EventClass]) -> Result, ConnectionError> where A: Into, B: Into, C: Into, { grab_device_button(self, grab_window, grabbed_device, modifier_device, modifiers, this_device_mode, other_device_mode, button, owner_events, classes) } fn xinput_ungrab_device_button(&self, grab_window: xproto::Window, modifiers: A, modifier_device: B, button: C, grabbed_device: u8) -> Result, ConnectionError> where A: Into, B: Into, C: Into, { ungrab_device_button(self, grab_window, modifiers, modifier_device, button, grabbed_device) } fn xinput_allow_device_events(&self, time: A, mode: DeviceInputMode, device_id: u8) -> Result, ConnectionError> where A: Into, { allow_device_events(self, time, mode, device_id) } fn xinput_get_device_focus(&self, device_id: u8) -> Result, ConnectionError> { get_device_focus(self, device_id) } fn xinput_set_device_focus(&self, focus: A, time: B, revert_to: xproto::InputFocus, device_id: u8) -> Result, ConnectionError> where A: Into, B: Into, { set_device_focus(self, focus, time, revert_to, device_id) } fn xinput_get_feedback_control(&self, device_id: u8) -> Result, ConnectionError> { get_feedback_control(self, device_id) } fn xinput_change_feedback_control(&self, mask: A, device_id: u8, feedback_id: u8, feedback: FeedbackCtl) -> Result, ConnectionError> where A: Into, { change_feedback_control(self, mask, device_id, feedback_id, feedback) } fn xinput_get_device_key_mapping(&self, device_id: u8, first_keycode: KeyCode, count: u8) -> Result, ConnectionError> { get_device_key_mapping(self, device_id, first_keycode, count) } fn xinput_change_device_key_mapping<'c, 'input>(&'c self, device_id: u8, first_keycode: KeyCode, keysyms_per_keycode: u8, keycode_count: u8, keysyms: &'input [xproto::Keysym]) -> Result, ConnectionError> { change_device_key_mapping(self, device_id, first_keycode, keysyms_per_keycode, keycode_count, keysyms) } fn xinput_get_device_modifier_mapping(&self, device_id: u8) -> Result, ConnectionError> { get_device_modifier_mapping(self, device_id) } fn xinput_set_device_modifier_mapping<'c, 'input>(&'c self, device_id: u8, keymaps: &'input [u8]) -> Result, ConnectionError> { set_device_modifier_mapping(self, device_id, keymaps) } fn xinput_get_device_button_mapping(&self, device_id: u8) -> Result, ConnectionError> { get_device_button_mapping(self, device_id) } fn xinput_set_device_button_mapping<'c, 'input>(&'c self, device_id: u8, map: &'input [u8]) -> Result, ConnectionError> { set_device_button_mapping(self, device_id, map) } fn xinput_query_device_state(&self, device_id: u8) -> Result, ConnectionError> { query_device_state(self, device_id) } fn xinput_device_bell(&self, device_id: u8, feedback_id: u8, feedback_class: u8, percent: i8) -> Result, ConnectionError> { device_bell(self, device_id, feedback_id, feedback_class, percent) } fn xinput_set_device_valuators<'c, 'input>(&'c self, device_id: u8, first_valuator: u8, valuators: &'input [i32]) -> Result, ConnectionError> { set_device_valuators(self, device_id, first_valuator, valuators) } fn xinput_get_device_control(&self, control_id: DeviceControl, device_id: u8) -> Result, ConnectionError> { get_device_control(self, control_id, device_id) } fn xinput_change_device_control(&self, control_id: DeviceControl, device_id: u8, control: DeviceCtl) -> Result, ConnectionError> { change_device_control(self, control_id, device_id, control) } fn xinput_list_device_properties(&self, device_id: u8) -> Result, ConnectionError> { list_device_properties(self, device_id) } fn xinput_change_device_property<'c, 'input>(&'c self, property: xproto::Atom, type_: xproto::Atom, device_id: u8, mode: xproto::PropMode, num_items: u32, items: &'input ChangeDevicePropertyAux) -> Result, ConnectionError> { change_device_property(self, property, type_, device_id, mode, num_items, items) } fn xinput_delete_device_property(&self, property: xproto::Atom, device_id: u8) -> Result, ConnectionError> { delete_device_property(self, property, device_id) } fn xinput_get_device_property(&self, property: xproto::Atom, type_: xproto::Atom, offset: u32, len: u32, device_id: u8, delete: bool) -> Result, ConnectionError> { get_device_property(self, property, type_, offset, len, device_id, delete) } fn xinput_xi_query_pointer(&self, window: xproto::Window, deviceid: A) -> Result, ConnectionError> where A: Into, { xi_query_pointer(self, window, deviceid) } fn xinput_xi_warp_pointer(&self, src_win: xproto::Window, dst_win: xproto::Window, src_x: Fp1616, src_y: Fp1616, src_width: u16, src_height: u16, dst_x: Fp1616, dst_y: Fp1616, deviceid: A) -> Result, ConnectionError> where A: Into, { xi_warp_pointer(self, src_win, dst_win, src_x, src_y, src_width, src_height, dst_x, dst_y, deviceid) } fn xinput_xi_change_cursor(&self, window: xproto::Window, cursor: xproto::Cursor, deviceid: A) -> Result, ConnectionError> where A: Into, { xi_change_cursor(self, window, cursor, deviceid) } fn xinput_xi_change_hierarchy<'c, 'input>(&'c self, changes: &'input [HierarchyChange]) -> Result, ConnectionError> { xi_change_hierarchy(self, changes) } fn xinput_xi_set_client_pointer(&self, window: xproto::Window, deviceid: A) -> Result, ConnectionError> where A: Into, { xi_set_client_pointer(self, window, deviceid) } fn xinput_xi_get_client_pointer(&self, window: xproto::Window) -> Result, ConnectionError> { xi_get_client_pointer(self, window) } fn xinput_xi_select_events<'c, 'input>(&'c self, window: xproto::Window, masks: &'input [EventMask]) -> Result, ConnectionError> { xi_select_events(self, window, masks) } fn xinput_xi_query_version(&self, major_version: u16, minor_version: u16) -> Result, ConnectionError> { xi_query_version(self, major_version, minor_version) } fn xinput_xi_query_device(&self, deviceid: A) -> Result, ConnectionError> where A: Into, { xi_query_device(self, deviceid) } fn xinput_xi_set_focus(&self, window: xproto::Window, time: A, deviceid: B) -> Result, ConnectionError> where A: Into, B: Into, { xi_set_focus(self, window, time, deviceid) } fn xinput_xi_get_focus(&self, deviceid: A) -> Result, ConnectionError> where A: Into, { xi_get_focus(self, deviceid) } fn xinput_xi_grab_device<'c, 'input, A, B>(&'c self, window: xproto::Window, time: A, cursor: xproto::Cursor, deviceid: B, mode: xproto::GrabMode, paired_device_mode: xproto::GrabMode, owner_events: GrabOwner, mask: &'input [u32]) -> Result, ConnectionError> where A: Into, B: Into, { xi_grab_device(self, window, time, cursor, deviceid, mode, paired_device_mode, owner_events, mask) } fn xinput_xi_ungrab_device(&self, time: A, deviceid: B) -> Result, ConnectionError> where A: Into, B: Into, { xi_ungrab_device(self, time, deviceid) } fn xinput_xi_allow_events(&self, time: A, deviceid: B, event_mode: EventMode, touchid: u32, grab_window: xproto::Window) -> Result, ConnectionError> where A: Into, B: Into, { xi_allow_events(self, time, deviceid, event_mode, touchid, grab_window) } fn xinput_xi_passive_grab_device<'c, 'input, A, B>(&'c self, time: A, grab_window: xproto::Window, cursor: xproto::Cursor, detail: u32, deviceid: B, grab_type: GrabType, grab_mode: GrabMode22, paired_device_mode: xproto::GrabMode, owner_events: GrabOwner, mask: &'input [u32], modifiers: &'input [u32]) -> Result, ConnectionError> where A: Into, B: Into, { xi_passive_grab_device(self, time, grab_window, cursor, detail, deviceid, grab_type, grab_mode, paired_device_mode, owner_events, mask, modifiers) } fn xinput_xi_passive_ungrab_device<'c, 'input, A>(&'c self, grab_window: xproto::Window, detail: u32, deviceid: A, grab_type: GrabType, modifiers: &'input [u32]) -> Result, ConnectionError> where A: Into, { xi_passive_ungrab_device(self, grab_window, detail, deviceid, grab_type, modifiers) } fn xinput_xi_list_properties(&self, deviceid: A) -> Result, ConnectionError> where A: Into, { xi_list_properties(self, deviceid) } fn xinput_xi_change_property<'c, 'input, A>(&'c self, deviceid: A, mode: xproto::PropMode, property: xproto::Atom, type_: xproto::Atom, num_items: u32, items: &'input XIChangePropertyAux) -> Result, ConnectionError> where A: Into, { xi_change_property(self, deviceid, mode, property, type_, num_items, items) } fn xinput_xi_delete_property(&self, deviceid: A, property: xproto::Atom) -> Result, ConnectionError> where A: Into, { xi_delete_property(self, deviceid, property) } fn xinput_xi_get_property(&self, deviceid: A, delete: bool, property: xproto::Atom, type_: xproto::Atom, offset: u32, len: u32) -> Result, ConnectionError> where A: Into, { xi_get_property(self, deviceid, delete, property, type_, offset, len) } fn xinput_xi_get_selected_events(&self, window: xproto::Window) -> Result, ConnectionError> { xi_get_selected_events(self, window) } fn xinput_xi_barrier_release_pointer<'c, 'input>(&'c self, barriers: &'input [BarrierReleasePointerInfo]) -> Result, ConnectionError> { xi_barrier_release_pointer(self, barriers) } fn xinput_send_extension_event<'c, 'input>(&'c self, destination: xproto::Window, device_id: u8, propagate: bool, events: &'input [EventForSend], classes: &'input [EventClass]) -> Result, ConnectionError> { send_extension_event(self, destination, device_id, propagate, events, classes) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xkb.rs010064400017500001750000016767251402220031600144360ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `xkb` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XKEYBOARD"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 0); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Const(u8); impl Const { pub const MAX_LEGAL_KEY_CODE: Self = Self(255); pub const PER_KEY_BIT_ARRAY_SIZE: Self = Self(32); pub const KEY_NAME_LENGTH: Self = Self(4); } impl From for u8 { #[inline] fn from(input: Const) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Const) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Const) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Const) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Const) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Const) -> Self { Some(u32::from(input.0)) } } impl From for Const { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Const { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::MAX_LEGAL_KEY_CODE.0.into(), "MAX_LEGAL_KEY_CODE", "MaxLegalKeyCode"), (Self::PER_KEY_BIT_ARRAY_SIZE.0.into(), "PER_KEY_BIT_ARRAY_SIZE", "PerKeyBitArraySize"), (Self::KEY_NAME_LENGTH.0.into(), "KEY_NAME_LENGTH", "KeyNameLength"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct EventType(u16); impl EventType { pub const NEW_KEYBOARD_NOTIFY: Self = Self(1 << 0); pub const MAP_NOTIFY: Self = Self(1 << 1); pub const STATE_NOTIFY: Self = Self(1 << 2); pub const CONTROLS_NOTIFY: Self = Self(1 << 3); pub const INDICATOR_STATE_NOTIFY: Self = Self(1 << 4); pub const INDICATOR_MAP_NOTIFY: Self = Self(1 << 5); pub const NAMES_NOTIFY: Self = Self(1 << 6); pub const COMPAT_MAP_NOTIFY: Self = Self(1 << 7); pub const BELL_NOTIFY: Self = Self(1 << 8); pub const ACTION_MESSAGE: Self = Self(1 << 9); pub const ACCESS_X_NOTIFY: Self = Self(1 << 10); pub const EXTENSION_DEVICE_NOTIFY: Self = Self(1 << 11); } impl From for u16 { #[inline] fn from(input: EventType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: EventType) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: EventType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: EventType) -> Self { Some(u32::from(input.0)) } } impl From for EventType { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for EventType { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for EventType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NEW_KEYBOARD_NOTIFY.0.into(), "NEW_KEYBOARD_NOTIFY", "NewKeyboardNotify"), (Self::MAP_NOTIFY.0.into(), "MAP_NOTIFY", "MapNotify"), (Self::STATE_NOTIFY.0.into(), "STATE_NOTIFY", "StateNotify"), (Self::CONTROLS_NOTIFY.0.into(), "CONTROLS_NOTIFY", "ControlsNotify"), (Self::INDICATOR_STATE_NOTIFY.0.into(), "INDICATOR_STATE_NOTIFY", "IndicatorStateNotify"), (Self::INDICATOR_MAP_NOTIFY.0.into(), "INDICATOR_MAP_NOTIFY", "IndicatorMapNotify"), (Self::NAMES_NOTIFY.0.into(), "NAMES_NOTIFY", "NamesNotify"), (Self::COMPAT_MAP_NOTIFY.0.into(), "COMPAT_MAP_NOTIFY", "CompatMapNotify"), (Self::BELL_NOTIFY.0.into(), "BELL_NOTIFY", "BellNotify"), (Self::ACTION_MESSAGE.0.into(), "ACTION_MESSAGE", "ActionMessage"), (Self::ACCESS_X_NOTIFY.0.into(), "ACCESS_X_NOTIFY", "AccessXNotify"), (Self::EXTENSION_DEVICE_NOTIFY.0.into(), "EXTENSION_DEVICE_NOTIFY", "ExtensionDeviceNotify"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(EventType, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct NKNDetail(u8); impl NKNDetail { pub const KEYCODES: Self = Self(1 << 0); pub const GEOMETRY: Self = Self(1 << 1); pub const DEVICE_ID: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: NKNDetail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: NKNDetail) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: NKNDetail) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: NKNDetail) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: NKNDetail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: NKNDetail) -> Self { Some(u32::from(input.0)) } } impl From for NKNDetail { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for NKNDetail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEYCODES.0.into(), "KEYCODES", "Keycodes"), (Self::GEOMETRY.0.into(), "GEOMETRY", "Geometry"), (Self::DEVICE_ID.0.into(), "DEVICE_ID", "DeviceID"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(NKNDetail, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct AXNDetail(u8); impl AXNDetail { pub const SK_PRESS: Self = Self(1 << 0); pub const SK_ACCEPT: Self = Self(1 << 1); pub const SK_REJECT: Self = Self(1 << 2); pub const SK_RELEASE: Self = Self(1 << 3); pub const BK_ACCEPT: Self = Self(1 << 4); pub const BK_REJECT: Self = Self(1 << 5); pub const AXK_WARNING: Self = Self(1 << 6); } impl From for u8 { #[inline] fn from(input: AXNDetail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: AXNDetail) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: AXNDetail) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: AXNDetail) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: AXNDetail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: AXNDetail) -> Self { Some(u32::from(input.0)) } } impl From for AXNDetail { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for AXNDetail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SK_PRESS.0.into(), "SK_PRESS", "SKPress"), (Self::SK_ACCEPT.0.into(), "SK_ACCEPT", "SKAccept"), (Self::SK_REJECT.0.into(), "SK_REJECT", "SKReject"), (Self::SK_RELEASE.0.into(), "SK_RELEASE", "SKRelease"), (Self::BK_ACCEPT.0.into(), "BK_ACCEPT", "BKAccept"), (Self::BK_REJECT.0.into(), "BK_REJECT", "BKReject"), (Self::AXK_WARNING.0.into(), "AXK_WARNING", "AXKWarning"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(AXNDetail, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct MapPart(u8); impl MapPart { pub const KEY_TYPES: Self = Self(1 << 0); pub const KEY_SYMS: Self = Self(1 << 1); pub const MODIFIER_MAP: Self = Self(1 << 2); pub const EXPLICIT_COMPONENTS: Self = Self(1 << 3); pub const KEY_ACTIONS: Self = Self(1 << 4); pub const KEY_BEHAVIORS: Self = Self(1 << 5); pub const VIRTUAL_MODS: Self = Self(1 << 6); pub const VIRTUAL_MOD_MAP: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: MapPart) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: MapPart) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: MapPart) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: MapPart) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: MapPart) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: MapPart) -> Self { Some(u32::from(input.0)) } } impl From for MapPart { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for MapPart { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEY_TYPES.0.into(), "KEY_TYPES", "KeyTypes"), (Self::KEY_SYMS.0.into(), "KEY_SYMS", "KeySyms"), (Self::MODIFIER_MAP.0.into(), "MODIFIER_MAP", "ModifierMap"), (Self::EXPLICIT_COMPONENTS.0.into(), "EXPLICIT_COMPONENTS", "ExplicitComponents"), (Self::KEY_ACTIONS.0.into(), "KEY_ACTIONS", "KeyActions"), (Self::KEY_BEHAVIORS.0.into(), "KEY_BEHAVIORS", "KeyBehaviors"), (Self::VIRTUAL_MODS.0.into(), "VIRTUAL_MODS", "VirtualMods"), (Self::VIRTUAL_MOD_MAP.0.into(), "VIRTUAL_MOD_MAP", "VirtualModMap"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(MapPart, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct SetMapFlags(u8); impl SetMapFlags { pub const RESIZE_TYPES: Self = Self(1 << 0); pub const RECOMPUTE_ACTIONS: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: SetMapFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SetMapFlags) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SetMapFlags) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SetMapFlags) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SetMapFlags) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SetMapFlags) -> Self { Some(u32::from(input.0)) } } impl From for SetMapFlags { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SetMapFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::RESIZE_TYPES.0.into(), "RESIZE_TYPES", "ResizeTypes"), (Self::RECOMPUTE_ACTIONS.0.into(), "RECOMPUTE_ACTIONS", "RecomputeActions"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SetMapFlags, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct StatePart(u16); impl StatePart { pub const MODIFIER_STATE: Self = Self(1 << 0); pub const MODIFIER_BASE: Self = Self(1 << 1); pub const MODIFIER_LATCH: Self = Self(1 << 2); pub const MODIFIER_LOCK: Self = Self(1 << 3); pub const GROUP_STATE: Self = Self(1 << 4); pub const GROUP_BASE: Self = Self(1 << 5); pub const GROUP_LATCH: Self = Self(1 << 6); pub const GROUP_LOCK: Self = Self(1 << 7); pub const COMPAT_STATE: Self = Self(1 << 8); pub const GRAB_MODS: Self = Self(1 << 9); pub const COMPAT_GRAB_MODS: Self = Self(1 << 10); pub const LOOKUP_MODS: Self = Self(1 << 11); pub const COMPAT_LOOKUP_MODS: Self = Self(1 << 12); pub const POINTER_BUTTONS: Self = Self(1 << 13); } impl From for u16 { #[inline] fn from(input: StatePart) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: StatePart) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: StatePart) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: StatePart) -> Self { Some(u32::from(input.0)) } } impl From for StatePart { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for StatePart { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for StatePart { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::MODIFIER_STATE.0.into(), "MODIFIER_STATE", "ModifierState"), (Self::MODIFIER_BASE.0.into(), "MODIFIER_BASE", "ModifierBase"), (Self::MODIFIER_LATCH.0.into(), "MODIFIER_LATCH", "ModifierLatch"), (Self::MODIFIER_LOCK.0.into(), "MODIFIER_LOCK", "ModifierLock"), (Self::GROUP_STATE.0.into(), "GROUP_STATE", "GroupState"), (Self::GROUP_BASE.0.into(), "GROUP_BASE", "GroupBase"), (Self::GROUP_LATCH.0.into(), "GROUP_LATCH", "GroupLatch"), (Self::GROUP_LOCK.0.into(), "GROUP_LOCK", "GroupLock"), (Self::COMPAT_STATE.0.into(), "COMPAT_STATE", "CompatState"), (Self::GRAB_MODS.0.into(), "GRAB_MODS", "GrabMods"), (Self::COMPAT_GRAB_MODS.0.into(), "COMPAT_GRAB_MODS", "CompatGrabMods"), (Self::LOOKUP_MODS.0.into(), "LOOKUP_MODS", "LookupMods"), (Self::COMPAT_LOOKUP_MODS.0.into(), "COMPAT_LOOKUP_MODS", "CompatLookupMods"), (Self::POINTER_BUTTONS.0.into(), "POINTER_BUTTONS", "PointerButtons"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(StatePart, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct BoolCtrl(u16); impl BoolCtrl { pub const REPEAT_KEYS: Self = Self(1 << 0); pub const SLOW_KEYS: Self = Self(1 << 1); pub const BOUNCE_KEYS: Self = Self(1 << 2); pub const STICKY_KEYS: Self = Self(1 << 3); pub const MOUSE_KEYS: Self = Self(1 << 4); pub const MOUSE_KEYS_ACCEL: Self = Self(1 << 5); pub const ACCESS_X_KEYS: Self = Self(1 << 6); pub const ACCESS_X_TIMEOUT_MASK: Self = Self(1 << 7); pub const ACCESS_X_FEEDBACK_MASK: Self = Self(1 << 8); pub const AUDIBLE_BELL_MASK: Self = Self(1 << 9); pub const OVERLAY1_MASK: Self = Self(1 << 10); pub const OVERLAY2_MASK: Self = Self(1 << 11); pub const IGNORE_GROUP_LOCK_MASK: Self = Self(1 << 12); } impl From for u16 { #[inline] fn from(input: BoolCtrl) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BoolCtrl) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: BoolCtrl) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BoolCtrl) -> Self { Some(u32::from(input.0)) } } impl From for BoolCtrl { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for BoolCtrl { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for BoolCtrl { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::REPEAT_KEYS.0.into(), "REPEAT_KEYS", "RepeatKeys"), (Self::SLOW_KEYS.0.into(), "SLOW_KEYS", "SlowKeys"), (Self::BOUNCE_KEYS.0.into(), "BOUNCE_KEYS", "BounceKeys"), (Self::STICKY_KEYS.0.into(), "STICKY_KEYS", "StickyKeys"), (Self::MOUSE_KEYS.0.into(), "MOUSE_KEYS", "MouseKeys"), (Self::MOUSE_KEYS_ACCEL.0.into(), "MOUSE_KEYS_ACCEL", "MouseKeysAccel"), (Self::ACCESS_X_KEYS.0.into(), "ACCESS_X_KEYS", "AccessXKeys"), (Self::ACCESS_X_TIMEOUT_MASK.0.into(), "ACCESS_X_TIMEOUT_MASK", "AccessXTimeoutMask"), (Self::ACCESS_X_FEEDBACK_MASK.0.into(), "ACCESS_X_FEEDBACK_MASK", "AccessXFeedbackMask"), (Self::AUDIBLE_BELL_MASK.0.into(), "AUDIBLE_BELL_MASK", "AudibleBellMask"), (Self::OVERLAY1_MASK.0.into(), "OVERLAY1_MASK", "Overlay1Mask"), (Self::OVERLAY2_MASK.0.into(), "OVERLAY2_MASK", "Overlay2Mask"), (Self::IGNORE_GROUP_LOCK_MASK.0.into(), "IGNORE_GROUP_LOCK_MASK", "IgnoreGroupLockMask"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(BoolCtrl, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Control(u32); impl Control { pub const GROUPS_WRAP: Self = Self(1 << 27); pub const INTERNAL_MODS: Self = Self(1 << 28); pub const IGNORE_LOCK_MODS: Self = Self(1 << 29); pub const PER_KEY_REPEAT: Self = Self(1 << 30); pub const CONTROLS_ENABLED: Self = Self(1 << 31); } impl From for u32 { #[inline] fn from(input: Control) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Control) -> Self { Some(input.0) } } impl From for Control { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for Control { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for Control { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for Control { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::GROUPS_WRAP.0, "GROUPS_WRAP", "GroupsWrap"), (Self::INTERNAL_MODS.0, "INTERNAL_MODS", "InternalMods"), (Self::IGNORE_LOCK_MODS.0, "IGNORE_LOCK_MODS", "IgnoreLockMods"), (Self::PER_KEY_REPEAT.0, "PER_KEY_REPEAT", "PerKeyRepeat"), (Self::CONTROLS_ENABLED.0, "CONTROLS_ENABLED", "ControlsEnabled"), ]; pretty_print_bitmask(fmt, self.0, &variants) } } bitmask_binop!(Control, u32); #[derive(Clone, Copy, PartialEq, Eq)] pub struct AXOption(u16); impl AXOption { pub const SK_PRESS_FB: Self = Self(1 << 0); pub const SK_ACCEPT_FB: Self = Self(1 << 1); pub const FEATURE_FB: Self = Self(1 << 2); pub const SLOW_WARN_FB: Self = Self(1 << 3); pub const INDICATOR_FB: Self = Self(1 << 4); pub const STICKY_KEYS_FB: Self = Self(1 << 5); pub const TWO_KEYS: Self = Self(1 << 6); pub const LATCH_TO_LOCK: Self = Self(1 << 7); pub const SK_RELEASE_FB: Self = Self(1 << 8); pub const SK_REJECT_FB: Self = Self(1 << 9); pub const BK_REJECT_FB: Self = Self(1 << 10); pub const DUMB_BELL: Self = Self(1 << 11); } impl From for u16 { #[inline] fn from(input: AXOption) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: AXOption) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: AXOption) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: AXOption) -> Self { Some(u32::from(input.0)) } } impl From for AXOption { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for AXOption { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for AXOption { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SK_PRESS_FB.0.into(), "SK_PRESS_FB", "SKPressFB"), (Self::SK_ACCEPT_FB.0.into(), "SK_ACCEPT_FB", "SKAcceptFB"), (Self::FEATURE_FB.0.into(), "FEATURE_FB", "FeatureFB"), (Self::SLOW_WARN_FB.0.into(), "SLOW_WARN_FB", "SlowWarnFB"), (Self::INDICATOR_FB.0.into(), "INDICATOR_FB", "IndicatorFB"), (Self::STICKY_KEYS_FB.0.into(), "STICKY_KEYS_FB", "StickyKeysFB"), (Self::TWO_KEYS.0.into(), "TWO_KEYS", "TwoKeys"), (Self::LATCH_TO_LOCK.0.into(), "LATCH_TO_LOCK", "LatchToLock"), (Self::SK_RELEASE_FB.0.into(), "SK_RELEASE_FB", "SKReleaseFB"), (Self::SK_REJECT_FB.0.into(), "SK_REJECT_FB", "SKRejectFB"), (Self::BK_REJECT_FB.0.into(), "BK_REJECT_FB", "BKRejectFB"), (Self::DUMB_BELL.0.into(), "DUMB_BELL", "DumbBell"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(AXOption, u16); pub type DeviceSpec = u16; #[derive(Clone, Copy, PartialEq, Eq)] pub struct LedClassResult(u16); impl LedClassResult { pub const KBD_FEEDBACK_CLASS: Self = Self(0); pub const LED_FEEDBACK_CLASS: Self = Self(4); } impl From for u16 { #[inline] fn from(input: LedClassResult) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: LedClassResult) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: LedClassResult) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: LedClassResult) -> Self { Some(u32::from(input.0)) } } impl From for LedClassResult { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for LedClassResult { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for LedClassResult { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KBD_FEEDBACK_CLASS.0.into(), "KBD_FEEDBACK_CLASS", "KbdFeedbackClass"), (Self::LED_FEEDBACK_CLASS.0.into(), "LED_FEEDBACK_CLASS", "LedFeedbackClass"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct LedClass(u16); impl LedClass { pub const KBD_FEEDBACK_CLASS: Self = Self(0); pub const LED_FEEDBACK_CLASS: Self = Self(4); pub const DFLT_XI_CLASS: Self = Self(768); pub const ALL_XI_CLASSES: Self = Self(1280); } impl From for u16 { #[inline] fn from(input: LedClass) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: LedClass) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: LedClass) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: LedClass) -> Self { Some(u32::from(input.0)) } } impl From for LedClass { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for LedClass { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for LedClass { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KBD_FEEDBACK_CLASS.0.into(), "KBD_FEEDBACK_CLASS", "KbdFeedbackClass"), (Self::LED_FEEDBACK_CLASS.0.into(), "LED_FEEDBACK_CLASS", "LedFeedbackClass"), (Self::DFLT_XI_CLASS.0.into(), "DFLT_XI_CLASS", "DfltXIClass"), (Self::ALL_XI_CLASSES.0.into(), "ALL_XI_CLASSES", "AllXIClasses"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } pub type LedClassSpec = u16; #[derive(Clone, Copy, PartialEq, Eq)] pub struct BellClassResult(u8); impl BellClassResult { pub const KBD_FEEDBACK_CLASS: Self = Self(0); pub const BELL_FEEDBACK_CLASS: Self = Self(5); } impl From for u8 { #[inline] fn from(input: BellClassResult) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BellClassResult) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: BellClassResult) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: BellClassResult) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: BellClassResult) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BellClassResult) -> Self { Some(u32::from(input.0)) } } impl From for BellClassResult { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for BellClassResult { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KBD_FEEDBACK_CLASS.0.into(), "KBD_FEEDBACK_CLASS", "KbdFeedbackClass"), (Self::BELL_FEEDBACK_CLASS.0.into(), "BELL_FEEDBACK_CLASS", "BellFeedbackClass"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct BellClass(u16); impl BellClass { pub const KBD_FEEDBACK_CLASS: Self = Self(0); pub const BELL_FEEDBACK_CLASS: Self = Self(5); pub const DFLT_XI_CLASS: Self = Self(768); } impl From for u16 { #[inline] fn from(input: BellClass) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BellClass) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: BellClass) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BellClass) -> Self { Some(u32::from(input.0)) } } impl From for BellClass { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for BellClass { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for BellClass { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KBD_FEEDBACK_CLASS.0.into(), "KBD_FEEDBACK_CLASS", "KbdFeedbackClass"), (Self::BELL_FEEDBACK_CLASS.0.into(), "BELL_FEEDBACK_CLASS", "BellFeedbackClass"), (Self::DFLT_XI_CLASS.0.into(), "DFLT_XI_CLASS", "DfltXIClass"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } pub type BellClassSpec = u16; #[derive(Clone, Copy, PartialEq, Eq)] pub struct ID(u16); impl ID { pub const USE_CORE_KBD: Self = Self(256); pub const USE_CORE_PTR: Self = Self(512); pub const DFLT_XI_CLASS: Self = Self(768); pub const DFLT_XI_ID: Self = Self(1024); pub const ALL_XI_CLASS: Self = Self(1280); pub const ALL_XI_ID: Self = Self(1536); pub const XI_NONE: Self = Self(65280); } impl From for u16 { #[inline] fn from(input: ID) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ID) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: ID) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ID) -> Self { Some(u32::from(input.0)) } } impl From for ID { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for ID { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for ID { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::USE_CORE_KBD.0.into(), "USE_CORE_KBD", "UseCoreKbd"), (Self::USE_CORE_PTR.0.into(), "USE_CORE_PTR", "UseCorePtr"), (Self::DFLT_XI_CLASS.0.into(), "DFLT_XI_CLASS", "DfltXIClass"), (Self::DFLT_XI_ID.0.into(), "DFLT_XI_ID", "DfltXIId"), (Self::ALL_XI_CLASS.0.into(), "ALL_XI_CLASS", "AllXIClass"), (Self::ALL_XI_ID.0.into(), "ALL_XI_ID", "AllXIId"), (Self::XI_NONE.0.into(), "XI_NONE", "XINone"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } pub type IDSpec = u16; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Group(u8); impl Group { pub const M1: Self = Self(0); pub const M2: Self = Self(1); pub const M3: Self = Self(2); pub const M4: Self = Self(3); } impl From for u8 { #[inline] fn from(input: Group) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Group) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Group) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Group) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Group) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Group) -> Self { Some(u32::from(input.0)) } } impl From for Group { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Group { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::M1.0.into(), "M1", "M1"), (Self::M2.0.into(), "M2", "M2"), (Self::M3.0.into(), "M3", "M3"), (Self::M4.0.into(), "M4", "M4"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Groups(u8); impl Groups { pub const ANY: Self = Self(254); pub const ALL: Self = Self(255); } impl From for u8 { #[inline] fn from(input: Groups) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Groups) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Groups) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Groups) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Groups) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Groups) -> Self { Some(u32::from(input.0)) } } impl From for Groups { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Groups { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ANY.0.into(), "ANY", "Any"), (Self::ALL.0.into(), "ALL", "All"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SetOfGroup(u8); impl SetOfGroup { pub const GROUP1: Self = Self(1 << 0); pub const GROUP2: Self = Self(1 << 1); pub const GROUP3: Self = Self(1 << 2); pub const GROUP4: Self = Self(1 << 3); } impl From for u8 { #[inline] fn from(input: SetOfGroup) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SetOfGroup) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SetOfGroup) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SetOfGroup) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SetOfGroup) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SetOfGroup) -> Self { Some(u32::from(input.0)) } } impl From for SetOfGroup { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SetOfGroup { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::GROUP1.0.into(), "GROUP1", "Group1"), (Self::GROUP2.0.into(), "GROUP2", "Group2"), (Self::GROUP3.0.into(), "GROUP3", "Group3"), (Self::GROUP4.0.into(), "GROUP4", "Group4"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SetOfGroup, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct SetOfGroups(u8); impl SetOfGroups { pub const ANY: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: SetOfGroups) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SetOfGroups) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SetOfGroups) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SetOfGroups) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SetOfGroups) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SetOfGroups) -> Self { Some(u32::from(input.0)) } } impl From for SetOfGroups { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SetOfGroups { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ANY.0.into(), "ANY", "Any"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SetOfGroups, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct GroupsWrap(u8); impl GroupsWrap { pub const WRAP_INTO_RANGE: Self = Self(0); pub const CLAMP_INTO_RANGE: Self = Self(1 << 6); pub const REDIRECT_INTO_RANGE: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: GroupsWrap) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GroupsWrap) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: GroupsWrap) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: GroupsWrap) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: GroupsWrap) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: GroupsWrap) -> Self { Some(u32::from(input.0)) } } impl From for GroupsWrap { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for GroupsWrap { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::WRAP_INTO_RANGE.0.into(), "WRAP_INTO_RANGE", "WrapIntoRange"), (Self::CLAMP_INTO_RANGE.0.into(), "CLAMP_INTO_RANGE", "ClampIntoRange"), (Self::REDIRECT_INTO_RANGE.0.into(), "REDIRECT_INTO_RANGE", "RedirectIntoRange"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(GroupsWrap, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct VModsHigh(u8); impl VModsHigh { pub const M15: Self = Self(1 << 7); pub const M14: Self = Self(1 << 6); pub const M13: Self = Self(1 << 5); pub const M12: Self = Self(1 << 4); pub const M11: Self = Self(1 << 3); pub const M10: Self = Self(1 << 2); pub const M9: Self = Self(1 << 1); pub const M8: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: VModsHigh) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: VModsHigh) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: VModsHigh) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: VModsHigh) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: VModsHigh) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: VModsHigh) -> Self { Some(u32::from(input.0)) } } impl From for VModsHigh { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for VModsHigh { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::M15.0.into(), "M15", "M15"), (Self::M14.0.into(), "M14", "M14"), (Self::M13.0.into(), "M13", "M13"), (Self::M12.0.into(), "M12", "M12"), (Self::M11.0.into(), "M11", "M11"), (Self::M10.0.into(), "M10", "M10"), (Self::M9.0.into(), "M9", "M9"), (Self::M8.0.into(), "M8", "M8"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(VModsHigh, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct VModsLow(u8); impl VModsLow { pub const M7: Self = Self(1 << 7); pub const M6: Self = Self(1 << 6); pub const M5: Self = Self(1 << 5); pub const M4: Self = Self(1 << 4); pub const M3: Self = Self(1 << 3); pub const M2: Self = Self(1 << 2); pub const M1: Self = Self(1 << 1); pub const M0: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: VModsLow) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: VModsLow) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: VModsLow) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: VModsLow) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: VModsLow) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: VModsLow) -> Self { Some(u32::from(input.0)) } } impl From for VModsLow { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for VModsLow { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::M7.0.into(), "M7", "M7"), (Self::M6.0.into(), "M6", "M6"), (Self::M5.0.into(), "M5", "M5"), (Self::M4.0.into(), "M4", "M4"), (Self::M3.0.into(), "M3", "M3"), (Self::M2.0.into(), "M2", "M2"), (Self::M1.0.into(), "M1", "M1"), (Self::M0.0.into(), "M0", "M0"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(VModsLow, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct VMod(u16); impl VMod { pub const M15: Self = Self(1 << 15); pub const M14: Self = Self(1 << 14); pub const M13: Self = Self(1 << 13); pub const M12: Self = Self(1 << 12); pub const M11: Self = Self(1 << 11); pub const M10: Self = Self(1 << 10); pub const M9: Self = Self(1 << 9); pub const M8: Self = Self(1 << 8); pub const M7: Self = Self(1 << 7); pub const M6: Self = Self(1 << 6); pub const M5: Self = Self(1 << 5); pub const M4: Self = Self(1 << 4); pub const M3: Self = Self(1 << 3); pub const M2: Self = Self(1 << 2); pub const M1: Self = Self(1 << 1); pub const M0: Self = Self(1 << 0); } impl From for u16 { #[inline] fn from(input: VMod) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: VMod) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: VMod) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: VMod) -> Self { Some(u32::from(input.0)) } } impl From for VMod { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for VMod { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for VMod { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::M15.0.into(), "M15", "M15"), (Self::M14.0.into(), "M14", "M14"), (Self::M13.0.into(), "M13", "M13"), (Self::M12.0.into(), "M12", "M12"), (Self::M11.0.into(), "M11", "M11"), (Self::M10.0.into(), "M10", "M10"), (Self::M9.0.into(), "M9", "M9"), (Self::M8.0.into(), "M8", "M8"), (Self::M7.0.into(), "M7", "M7"), (Self::M6.0.into(), "M6", "M6"), (Self::M5.0.into(), "M5", "M5"), (Self::M4.0.into(), "M4", "M4"), (Self::M3.0.into(), "M3", "M3"), (Self::M2.0.into(), "M2", "M2"), (Self::M1.0.into(), "M1", "M1"), (Self::M0.0.into(), "M0", "M0"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(VMod, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Explicit(u8); impl Explicit { pub const V_MOD_MAP: Self = Self(1 << 7); pub const BEHAVIOR: Self = Self(1 << 6); pub const AUTO_REPEAT: Self = Self(1 << 5); pub const INTERPRET: Self = Self(1 << 4); pub const KEY_TYPE4: Self = Self(1 << 3); pub const KEY_TYPE3: Self = Self(1 << 2); pub const KEY_TYPE2: Self = Self(1 << 1); pub const KEY_TYPE1: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: Explicit) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Explicit) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Explicit) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Explicit) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Explicit) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Explicit) -> Self { Some(u32::from(input.0)) } } impl From for Explicit { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Explicit { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::V_MOD_MAP.0.into(), "V_MOD_MAP", "VModMap"), (Self::BEHAVIOR.0.into(), "BEHAVIOR", "Behavior"), (Self::AUTO_REPEAT.0.into(), "AUTO_REPEAT", "AutoRepeat"), (Self::INTERPRET.0.into(), "INTERPRET", "Interpret"), (Self::KEY_TYPE4.0.into(), "KEY_TYPE4", "KeyType4"), (Self::KEY_TYPE3.0.into(), "KEY_TYPE3", "KeyType3"), (Self::KEY_TYPE2.0.into(), "KEY_TYPE2", "KeyType2"), (Self::KEY_TYPE1.0.into(), "KEY_TYPE1", "KeyType1"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(Explicit, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct SymInterpretMatch(u8); impl SymInterpretMatch { pub const NONE_OF: Self = Self(0); pub const ANY_OF_OR_NONE: Self = Self(1); pub const ANY_OF: Self = Self(2); pub const ALL_OF: Self = Self(3); pub const EXACTLY: Self = Self(4); } impl From for u8 { #[inline] fn from(input: SymInterpretMatch) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SymInterpretMatch) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SymInterpretMatch) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SymInterpretMatch) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SymInterpretMatch) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SymInterpretMatch) -> Self { Some(u32::from(input.0)) } } impl From for SymInterpretMatch { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SymInterpretMatch { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NONE_OF.0.into(), "NONE_OF", "NoneOf"), (Self::ANY_OF_OR_NONE.0.into(), "ANY_OF_OR_NONE", "AnyOfOrNone"), (Self::ANY_OF.0.into(), "ANY_OF", "AnyOf"), (Self::ALL_OF.0.into(), "ALL_OF", "AllOf"), (Self::EXACTLY.0.into(), "EXACTLY", "Exactly"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SymInterpMatch(u8); impl SymInterpMatch { pub const LEVEL_ONE_ONLY: Self = Self(1 << 7); pub const OP_MASK: Self = Self(127); } impl From for u8 { #[inline] fn from(input: SymInterpMatch) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SymInterpMatch) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SymInterpMatch) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SymInterpMatch) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SymInterpMatch) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SymInterpMatch) -> Self { Some(u32::from(input.0)) } } impl From for SymInterpMatch { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SymInterpMatch { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::LEVEL_ONE_ONLY.0.into(), "LEVEL_ONE_ONLY", "LevelOneOnly"), (Self::OP_MASK.0.into(), "OP_MASK", "OpMask"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct IMFlag(u8); impl IMFlag { pub const NO_EXPLICIT: Self = Self(1 << 7); pub const NO_AUTOMATIC: Self = Self(1 << 6); pub const LED_DRIVES_KB: Self = Self(1 << 5); } impl From for u8 { #[inline] fn from(input: IMFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: IMFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: IMFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: IMFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: IMFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: IMFlag) -> Self { Some(u32::from(input.0)) } } impl From for IMFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for IMFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_EXPLICIT.0.into(), "NO_EXPLICIT", "NoExplicit"), (Self::NO_AUTOMATIC.0.into(), "NO_AUTOMATIC", "NoAutomatic"), (Self::LED_DRIVES_KB.0.into(), "LED_DRIVES_KB", "LEDDrivesKB"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(IMFlag, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct IMModsWhich(u8); impl IMModsWhich { pub const USE_COMPAT: Self = Self(1 << 4); pub const USE_EFFECTIVE: Self = Self(1 << 3); pub const USE_LOCKED: Self = Self(1 << 2); pub const USE_LATCHED: Self = Self(1 << 1); pub const USE_BASE: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: IMModsWhich) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: IMModsWhich) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: IMModsWhich) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: IMModsWhich) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: IMModsWhich) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: IMModsWhich) -> Self { Some(u32::from(input.0)) } } impl From for IMModsWhich { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for IMModsWhich { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::USE_COMPAT.0.into(), "USE_COMPAT", "UseCompat"), (Self::USE_EFFECTIVE.0.into(), "USE_EFFECTIVE", "UseEffective"), (Self::USE_LOCKED.0.into(), "USE_LOCKED", "UseLocked"), (Self::USE_LATCHED.0.into(), "USE_LATCHED", "UseLatched"), (Self::USE_BASE.0.into(), "USE_BASE", "UseBase"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(IMModsWhich, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct IMGroupsWhich(u8); impl IMGroupsWhich { pub const USE_COMPAT: Self = Self(1 << 4); pub const USE_EFFECTIVE: Self = Self(1 << 3); pub const USE_LOCKED: Self = Self(1 << 2); pub const USE_LATCHED: Self = Self(1 << 1); pub const USE_BASE: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: IMGroupsWhich) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: IMGroupsWhich) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: IMGroupsWhich) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: IMGroupsWhich) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: IMGroupsWhich) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: IMGroupsWhich) -> Self { Some(u32::from(input.0)) } } impl From for IMGroupsWhich { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for IMGroupsWhich { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::USE_COMPAT.0.into(), "USE_COMPAT", "UseCompat"), (Self::USE_EFFECTIVE.0.into(), "USE_EFFECTIVE", "UseEffective"), (Self::USE_LOCKED.0.into(), "USE_LOCKED", "UseLocked"), (Self::USE_LATCHED.0.into(), "USE_LATCHED", "UseLatched"), (Self::USE_BASE.0.into(), "USE_BASE", "UseBase"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(IMGroupsWhich, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IndicatorMap { pub flags: IMFlag, pub which_groups: IMGroupsWhich, pub groups: SetOfGroup, pub which_mods: IMModsWhich, pub mods: u8, pub real_mods: u8, pub vmods: u16, pub ctrls: u32, } impl TryParse for IndicatorMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (flags, remaining) = u8::try_parse(remaining)?; let (which_groups, remaining) = u8::try_parse(remaining)?; let (groups, remaining) = u8::try_parse(remaining)?; let (which_mods, remaining) = u8::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (vmods, remaining) = u16::try_parse(remaining)?; let (ctrls, remaining) = u32::try_parse(remaining)?; let flags = flags.into(); let which_groups = which_groups.into(); let groups = groups.into(); let which_mods = which_mods.into(); let result = IndicatorMap { flags, which_groups, groups, which_mods, mods, real_mods, vmods, ctrls }; Ok((result, remaining)) } } impl Serialize for IndicatorMap { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let flags_bytes = u8::from(self.flags).serialize(); let which_groups_bytes = u8::from(self.which_groups).serialize(); let groups_bytes = u8::from(self.groups).serialize(); let which_mods_bytes = u8::from(self.which_mods).serialize(); let mods_bytes = self.mods.serialize(); let real_mods_bytes = self.real_mods.serialize(); let vmods_bytes = self.vmods.serialize(); let ctrls_bytes = self.ctrls.serialize(); [ flags_bytes[0], which_groups_bytes[0], groups_bytes[0], which_mods_bytes[0], mods_bytes[0], real_mods_bytes[0], vmods_bytes[0], vmods_bytes[1], ctrls_bytes[0], ctrls_bytes[1], ctrls_bytes[2], ctrls_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); u8::from(self.flags).serialize_into(bytes); u8::from(self.which_groups).serialize_into(bytes); u8::from(self.groups).serialize_into(bytes); u8::from(self.which_mods).serialize_into(bytes); self.mods.serialize_into(bytes); self.real_mods.serialize_into(bytes); self.vmods.serialize_into(bytes); self.ctrls.serialize_into(bytes); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct CMDetail(u8); impl CMDetail { pub const SYM_INTERP: Self = Self(1 << 0); pub const GROUP_COMPAT: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: CMDetail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: CMDetail) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: CMDetail) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: CMDetail) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: CMDetail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: CMDetail) -> Self { Some(u32::from(input.0)) } } impl From for CMDetail { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for CMDetail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SYM_INTERP.0.into(), "SYM_INTERP", "SymInterp"), (Self::GROUP_COMPAT.0.into(), "GROUP_COMPAT", "GroupCompat"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(CMDetail, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct NameDetail(u16); impl NameDetail { pub const KEYCODES: Self = Self(1 << 0); pub const GEOMETRY: Self = Self(1 << 1); pub const SYMBOLS: Self = Self(1 << 2); pub const PHYS_SYMBOLS: Self = Self(1 << 3); pub const TYPES: Self = Self(1 << 4); pub const COMPAT: Self = Self(1 << 5); pub const KEY_TYPE_NAMES: Self = Self(1 << 6); pub const KT_LEVEL_NAMES: Self = Self(1 << 7); pub const INDICATOR_NAMES: Self = Self(1 << 8); pub const KEY_NAMES: Self = Self(1 << 9); pub const KEY_ALIASES: Self = Self(1 << 10); pub const VIRTUAL_MOD_NAMES: Self = Self(1 << 11); pub const GROUP_NAMES: Self = Self(1 << 12); pub const RG_NAMES: Self = Self(1 << 13); } impl From for u16 { #[inline] fn from(input: NameDetail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: NameDetail) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: NameDetail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: NameDetail) -> Self { Some(u32::from(input.0)) } } impl From for NameDetail { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for NameDetail { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for NameDetail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEYCODES.0.into(), "KEYCODES", "Keycodes"), (Self::GEOMETRY.0.into(), "GEOMETRY", "Geometry"), (Self::SYMBOLS.0.into(), "SYMBOLS", "Symbols"), (Self::PHYS_SYMBOLS.0.into(), "PHYS_SYMBOLS", "PhysSymbols"), (Self::TYPES.0.into(), "TYPES", "Types"), (Self::COMPAT.0.into(), "COMPAT", "Compat"), (Self::KEY_TYPE_NAMES.0.into(), "KEY_TYPE_NAMES", "KeyTypeNames"), (Self::KT_LEVEL_NAMES.0.into(), "KT_LEVEL_NAMES", "KTLevelNames"), (Self::INDICATOR_NAMES.0.into(), "INDICATOR_NAMES", "IndicatorNames"), (Self::KEY_NAMES.0.into(), "KEY_NAMES", "KeyNames"), (Self::KEY_ALIASES.0.into(), "KEY_ALIASES", "KeyAliases"), (Self::VIRTUAL_MOD_NAMES.0.into(), "VIRTUAL_MOD_NAMES", "VirtualModNames"), (Self::GROUP_NAMES.0.into(), "GROUP_NAMES", "GroupNames"), (Self::RG_NAMES.0.into(), "RG_NAMES", "RGNames"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(NameDetail, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct GBNDetail(u8); impl GBNDetail { pub const TYPES: Self = Self(1 << 0); pub const COMPAT_MAP: Self = Self(1 << 1); pub const CLIENT_SYMBOLS: Self = Self(1 << 2); pub const SERVER_SYMBOLS: Self = Self(1 << 3); pub const INDICATOR_MAPS: Self = Self(1 << 4); pub const KEY_NAMES: Self = Self(1 << 5); pub const GEOMETRY: Self = Self(1 << 6); pub const OTHER_NAMES: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: GBNDetail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GBNDetail) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: GBNDetail) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: GBNDetail) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: GBNDetail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: GBNDetail) -> Self { Some(u32::from(input.0)) } } impl From for GBNDetail { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for GBNDetail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::TYPES.0.into(), "TYPES", "Types"), (Self::COMPAT_MAP.0.into(), "COMPAT_MAP", "CompatMap"), (Self::CLIENT_SYMBOLS.0.into(), "CLIENT_SYMBOLS", "ClientSymbols"), (Self::SERVER_SYMBOLS.0.into(), "SERVER_SYMBOLS", "ServerSymbols"), (Self::INDICATOR_MAPS.0.into(), "INDICATOR_MAPS", "IndicatorMaps"), (Self::KEY_NAMES.0.into(), "KEY_NAMES", "KeyNames"), (Self::GEOMETRY.0.into(), "GEOMETRY", "Geometry"), (Self::OTHER_NAMES.0.into(), "OTHER_NAMES", "OtherNames"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(GBNDetail, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct XIFeature(u8); impl XIFeature { pub const KEYBOARDS: Self = Self(1 << 0); pub const BUTTON_ACTIONS: Self = Self(1 << 1); pub const INDICATOR_NAMES: Self = Self(1 << 2); pub const INDICATOR_MAPS: Self = Self(1 << 3); pub const INDICATOR_STATE: Self = Self(1 << 4); } impl From for u8 { #[inline] fn from(input: XIFeature) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: XIFeature) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: XIFeature) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: XIFeature) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: XIFeature) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: XIFeature) -> Self { Some(u32::from(input.0)) } } impl From for XIFeature { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for XIFeature { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::KEYBOARDS.0.into(), "KEYBOARDS", "Keyboards"), (Self::BUTTON_ACTIONS.0.into(), "BUTTON_ACTIONS", "ButtonActions"), (Self::INDICATOR_NAMES.0.into(), "INDICATOR_NAMES", "IndicatorNames"), (Self::INDICATOR_MAPS.0.into(), "INDICATOR_MAPS", "IndicatorMaps"), (Self::INDICATOR_STATE.0.into(), "INDICATOR_STATE", "IndicatorState"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(XIFeature, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct PerClientFlag(u8); impl PerClientFlag { pub const DETECTABLE_AUTO_REPEAT: Self = Self(1 << 0); pub const GRABS_USE_XKB_STATE: Self = Self(1 << 1); pub const AUTO_RESET_CONTROLS: Self = Self(1 << 2); pub const LOOKUP_STATE_WHEN_GRABBED: Self = Self(1 << 3); pub const SEND_EVENT_USES_XKB_STATE: Self = Self(1 << 4); } impl From for u8 { #[inline] fn from(input: PerClientFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: PerClientFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: PerClientFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: PerClientFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: PerClientFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: PerClientFlag) -> Self { Some(u32::from(input.0)) } } impl From for PerClientFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for PerClientFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DETECTABLE_AUTO_REPEAT.0.into(), "DETECTABLE_AUTO_REPEAT", "DetectableAutoRepeat"), (Self::GRABS_USE_XKB_STATE.0.into(), "GRABS_USE_XKB_STATE", "GrabsUseXKBState"), (Self::AUTO_RESET_CONTROLS.0.into(), "AUTO_RESET_CONTROLS", "AutoResetControls"), (Self::LOOKUP_STATE_WHEN_GRABBED.0.into(), "LOOKUP_STATE_WHEN_GRABBED", "LookupStateWhenGrabbed"), (Self::SEND_EVENT_USES_XKB_STATE.0.into(), "SEND_EVENT_USES_XKB_STATE", "SendEventUsesXKBState"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(PerClientFlag, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ModDef { pub mask: u8, pub real_mods: u8, pub vmods: u16, } impl TryParse for ModDef { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (mask, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (vmods, remaining) = u16::try_parse(remaining)?; let result = ModDef { mask, real_mods, vmods }; Ok((result, remaining)) } } impl Serialize for ModDef { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let mask_bytes = self.mask.serialize(); let real_mods_bytes = self.real_mods.serialize(); let vmods_bytes = self.vmods.serialize(); [ mask_bytes[0], real_mods_bytes[0], vmods_bytes[0], vmods_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.mask.serialize_into(bytes); self.real_mods.serialize_into(bytes); self.vmods.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyName { pub name: [u8; 4], } impl TryParse for KeyName { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let name = <[u8; 4]>::try_from(name).unwrap(); let result = KeyName { name }; Ok((result, remaining)) } } impl Serialize for KeyName { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { [ self.name[0], self.name[1], self.name[2], self.name[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); bytes.extend_from_slice(&self.name); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyAlias { pub real: [u8; 4], pub alias: [u8; 4], } impl TryParse for KeyAlias { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (real, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let real = <[u8; 4]>::try_from(real).unwrap(); let (alias, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let alias = <[u8; 4]>::try_from(alias).unwrap(); let result = KeyAlias { real, alias }; Ok((result, remaining)) } } impl Serialize for KeyAlias { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { [ self.real[0], self.real[1], self.real[2], self.real[3], self.alias[0], self.alias[1], self.alias[2], self.alias[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); bytes.extend_from_slice(&self.real); bytes.extend_from_slice(&self.alias); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct CountedString16 { pub string: Vec, pub alignment_pad: Vec, } impl TryParse for CountedString16 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (length, remaining) = u16::try_parse(remaining)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, length.try_to_usize()?)?; let string = string.to_vec(); let (alignment_pad, remaining) = crate::x11_utils::parse_u8_list(remaining, (u32::from(length).checked_add(5u32).ok_or(ParseError::InvalidExpression)? & (!3u32)).checked_sub(u32::from(length).checked_add(2u32).ok_or(ParseError::InvalidExpression)?).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let alignment_pad = alignment_pad.to_vec(); let result = CountedString16 { string, alignment_pad }; Ok((result, remaining)) } } impl Serialize for CountedString16 { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let length = u16::try_from(self.string.len()).expect("`string` has too many elements"); length.serialize_into(bytes); bytes.extend_from_slice(&self.string); assert_eq!(self.alignment_pad.len(), usize::try_from((u32::from(length).checked_add(5u32).unwrap() & (!3u32)).checked_sub(u32::from(length).checked_add(2u32).unwrap()).unwrap()).unwrap(), "`alignment_pad` has an incorrect length"); bytes.extend_from_slice(&self.alignment_pad); } } impl CountedString16 { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `string` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u16 { self.string.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KTMapEntry { pub active: bool, pub mods_mask: u8, pub level: u8, pub mods_mods: u8, pub mods_vmods: u16, } impl TryParse for KTMapEntry { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (active, remaining) = bool::try_parse(remaining)?; let (mods_mask, remaining) = u8::try_parse(remaining)?; let (level, remaining) = u8::try_parse(remaining)?; let (mods_mods, remaining) = u8::try_parse(remaining)?; let (mods_vmods, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let result = KTMapEntry { active, mods_mask, level, mods_mods, mods_vmods }; Ok((result, remaining)) } } impl Serialize for KTMapEntry { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let active_bytes = self.active.serialize(); let mods_mask_bytes = self.mods_mask.serialize(); let level_bytes = self.level.serialize(); let mods_mods_bytes = self.mods_mods.serialize(); let mods_vmods_bytes = self.mods_vmods.serialize(); [ active_bytes[0], mods_mask_bytes[0], level_bytes[0], mods_mods_bytes[0], mods_vmods_bytes[0], mods_vmods_bytes[1], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.active.serialize_into(bytes); self.mods_mask.serialize_into(bytes); self.level.serialize_into(bytes); self.mods_mods.serialize_into(bytes); self.mods_vmods.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct KeyType { pub mods_mask: u8, pub mods_mods: u8, pub mods_vmods: u16, pub num_levels: u8, pub has_preserve: bool, pub map: Vec, pub preserve: Vec, } impl TryParse for KeyType { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (mods_mask, remaining) = u8::try_parse(remaining)?; let (mods_mods, remaining) = u8::try_parse(remaining)?; let (mods_vmods, remaining) = u16::try_parse(remaining)?; let (num_levels, remaining) = u8::try_parse(remaining)?; let (n_map_entries, remaining) = u8::try_parse(remaining)?; let (has_preserve, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (map, remaining) = crate::x11_utils::parse_list::(remaining, n_map_entries.try_to_usize()?)?; let (preserve, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(has_preserve).checked_mul(u32::from(n_map_entries)).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let result = KeyType { mods_mask, mods_mods, mods_vmods, num_levels, has_preserve, map, preserve }; Ok((result, remaining)) } } impl Serialize for KeyType { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.mods_mask.serialize_into(bytes); self.mods_mods.serialize_into(bytes); self.mods_vmods.serialize_into(bytes); self.num_levels.serialize_into(bytes); let n_map_entries = u8::try_from(self.map.len()).expect("`map` has too many elements"); n_map_entries.serialize_into(bytes); self.has_preserve.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.map.serialize_into(bytes); assert_eq!(self.preserve.len(), usize::try_from(u32::from(self.has_preserve).checked_mul(u32::from(n_map_entries)).unwrap()).unwrap(), "`preserve` has an incorrect length"); self.preserve.serialize_into(bytes); } } impl KeyType { /// Get the value of the `nMapEntries` field. /// /// The `nMapEntries` field is used as the length field of the `map` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_map_entries(&self) -> u8 { self.map.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct KeySymMap { pub kt_index: [u8; 4], pub group_info: u8, pub width: u8, pub syms: Vec, } impl TryParse for KeySymMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (kt_index, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let kt_index = <[u8; 4]>::try_from(kt_index).unwrap(); let (group_info, remaining) = u8::try_parse(remaining)?; let (width, remaining) = u8::try_parse(remaining)?; let (n_syms, remaining) = u16::try_parse(remaining)?; let (syms, remaining) = crate::x11_utils::parse_list::(remaining, n_syms.try_to_usize()?)?; let result = KeySymMap { kt_index, group_info, width, syms }; Ok((result, remaining)) } } impl Serialize for KeySymMap { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); bytes.extend_from_slice(&self.kt_index); self.group_info.serialize_into(bytes); self.width.serialize_into(bytes); let n_syms = u16::try_from(self.syms.len()).expect("`syms` has too many elements"); n_syms.serialize_into(bytes); self.syms.serialize_into(bytes); } } impl KeySymMap { /// Get the value of the `nSyms` field. /// /// The `nSyms` field is used as the length field of the `syms` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_syms(&self) -> u16 { self.syms.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CommonBehavior { pub type_: u8, pub data: u8, } impl TryParse for CommonBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (data, remaining) = u8::try_parse(remaining)?; let result = CommonBehavior { type_, data }; Ok((result, remaining)) } } impl Serialize for CommonBehavior { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let type_bytes = self.type_.serialize(); let data_bytes = self.data.serialize(); [ type_bytes[0], data_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.type_.serialize_into(bytes); self.data.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DefaultBehavior { pub type_: u8, } impl TryParse for DefaultBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = DefaultBehavior { type_ }; Ok((result, remaining)) } } impl Serialize for DefaultBehavior { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let type_bytes = self.type_.serialize(); [ type_bytes[0], 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.type_.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); } } pub type LockBehavior = DefaultBehavior; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct RadioGroupBehavior { pub type_: u8, pub group: u8, } impl TryParse for RadioGroupBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (group, remaining) = u8::try_parse(remaining)?; let result = RadioGroupBehavior { type_, group }; Ok((result, remaining)) } } impl Serialize for RadioGroupBehavior { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let type_bytes = self.type_.serialize(); let group_bytes = self.group.serialize(); [ type_bytes[0], group_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.type_.serialize_into(bytes); self.group.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OverlayBehavior { pub type_: u8, pub key: xproto::Keycode, } impl TryParse for OverlayBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (key, remaining) = xproto::Keycode::try_parse(remaining)?; let result = OverlayBehavior { type_, key }; Ok((result, remaining)) } } impl Serialize for OverlayBehavior { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let type_bytes = self.type_.serialize(); let key_bytes = self.key.serialize(); [ type_bytes[0], key_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.type_.serialize_into(bytes); self.key.serialize_into(bytes); } } pub type PermamentLockBehavior = LockBehavior; pub type PermamentRadioGroupBehavior = RadioGroupBehavior; pub type PermamentOverlayBehavior = OverlayBehavior; #[derive(Debug, Copy, Clone)] pub struct Behavior([u8; 2]); impl Behavior { pub fn as_common(&self) -> CommonBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (common, remaining) = CommonBehavior::try_parse(remaining)?; let _ = remaining; Ok(common) } do_the_parse(&self.0).unwrap() } pub fn as_default(&self) -> DefaultBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (default, remaining) = DefaultBehavior::try_parse(remaining)?; let _ = remaining; Ok(default) } do_the_parse(&self.0).unwrap() } pub fn as_lock(&self) -> LockBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (lock, remaining) = LockBehavior::try_parse(remaining)?; let _ = remaining; Ok(lock) } do_the_parse(&self.0).unwrap() } pub fn as_radio_group(&self) -> RadioGroupBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (radio_group, remaining) = RadioGroupBehavior::try_parse(remaining)?; let _ = remaining; Ok(radio_group) } do_the_parse(&self.0).unwrap() } pub fn as_overlay1(&self) -> OverlayBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (overlay1, remaining) = OverlayBehavior::try_parse(remaining)?; let _ = remaining; Ok(overlay1) } do_the_parse(&self.0).unwrap() } pub fn as_overlay2(&self) -> OverlayBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (overlay2, remaining) = OverlayBehavior::try_parse(remaining)?; let _ = remaining; Ok(overlay2) } do_the_parse(&self.0).unwrap() } pub fn as_permament_lock(&self) -> PermamentLockBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (permament_lock, remaining) = PermamentLockBehavior::try_parse(remaining)?; let _ = remaining; Ok(permament_lock) } do_the_parse(&self.0).unwrap() } pub fn as_permament_radio_group(&self) -> PermamentRadioGroupBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (permament_radio_group, remaining) = PermamentRadioGroupBehavior::try_parse(remaining)?; let _ = remaining; Ok(permament_radio_group) } do_the_parse(&self.0).unwrap() } pub fn as_permament_overlay1(&self) -> PermamentOverlayBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (permament_overlay1, remaining) = PermamentOverlayBehavior::try_parse(remaining)?; let _ = remaining; Ok(permament_overlay1) } do_the_parse(&self.0).unwrap() } pub fn as_permament_overlay2(&self) -> PermamentOverlayBehavior { fn do_the_parse(remaining: &[u8]) -> Result { let (permament_overlay2, remaining) = PermamentOverlayBehavior::try_parse(remaining)?; let _ = remaining; Ok(permament_overlay2) } do_the_parse(&self.0).unwrap() } pub fn as_type(&self) -> u8 { fn do_the_parse(remaining: &[u8]) -> Result { let (type_, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(type_) } do_the_parse(&self.0).unwrap() } } impl Serialize for Behavior { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { self.0 } fn serialize_into(&self, bytes: &mut Vec) { bytes.extend_from_slice(&self.0); } } impl TryParse for Behavior { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let inner: [u8; 2] = value.get(..2) .ok_or(ParseError::InsufficientData)? .try_into() .unwrap(); let result = Behavior(inner); Ok((result, &value[2..])) } } impl From for Behavior { fn from(common: CommonBehavior) -> Self { let common_bytes = common.serialize(); Self(common_bytes) } } impl From for Behavior { fn from(default: DefaultBehavior) -> Self { let default_bytes = default.serialize(); Self(default_bytes) } } impl From for Behavior { fn from(radio_group: RadioGroupBehavior) -> Self { let radio_group_bytes = radio_group.serialize(); Self(radio_group_bytes) } } impl From for Behavior { fn from(overlay1: OverlayBehavior) -> Self { let overlay1_bytes = overlay1.serialize(); Self(overlay1_bytes) } } impl From for Behavior { fn from(type_: u8) -> Self { let type_bytes = type_.serialize(); let value = [ type_bytes[0], 0, ]; Self(value) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct BehaviorType(u8); impl BehaviorType { pub const DEFAULT: Self = Self(0); pub const LOCK: Self = Self(1); pub const RADIO_GROUP: Self = Self(2); pub const OVERLAY1: Self = Self(3); pub const OVERLAY2: Self = Self(4); pub const PERMAMENT_LOCK: Self = Self(129); pub const PERMAMENT_RADIO_GROUP: Self = Self(130); pub const PERMAMENT_OVERLAY1: Self = Self(131); pub const PERMAMENT_OVERLAY2: Self = Self(132); } impl From for u8 { #[inline] fn from(input: BehaviorType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BehaviorType) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: BehaviorType) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: BehaviorType) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: BehaviorType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BehaviorType) -> Self { Some(u32::from(input.0)) } } impl From for BehaviorType { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for BehaviorType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DEFAULT.0.into(), "DEFAULT", "Default"), (Self::LOCK.0.into(), "LOCK", "Lock"), (Self::RADIO_GROUP.0.into(), "RADIO_GROUP", "RadioGroup"), (Self::OVERLAY1.0.into(), "OVERLAY1", "Overlay1"), (Self::OVERLAY2.0.into(), "OVERLAY2", "Overlay2"), (Self::PERMAMENT_LOCK.0.into(), "PERMAMENT_LOCK", "PermamentLock"), (Self::PERMAMENT_RADIO_GROUP.0.into(), "PERMAMENT_RADIO_GROUP", "PermamentRadioGroup"), (Self::PERMAMENT_OVERLAY1.0.into(), "PERMAMENT_OVERLAY1", "PermamentOverlay1"), (Self::PERMAMENT_OVERLAY2.0.into(), "PERMAMENT_OVERLAY2", "PermamentOverlay2"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy)] pub struct SetBehavior { pub keycode: xproto::Keycode, pub behavior: Behavior, } impl TryParse for SetBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (behavior, remaining) = Behavior::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = SetBehavior { keycode, behavior }; Ok((result, remaining)) } } impl Serialize for SetBehavior { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let keycode_bytes = self.keycode.serialize(); let behavior_bytes = self.behavior.serialize(); [ keycode_bytes[0], behavior_bytes[0], behavior_bytes[1], 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.keycode.serialize_into(bytes); self.behavior.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetExplicit { pub keycode: xproto::Keycode, pub explicit: u8, } impl TryParse for SetExplicit { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (explicit, remaining) = u8::try_parse(remaining)?; let result = SetExplicit { keycode, explicit }; Ok((result, remaining)) } } impl Serialize for SetExplicit { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let keycode_bytes = self.keycode.serialize(); let explicit_bytes = self.explicit.serialize(); [ keycode_bytes[0], explicit_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.keycode.serialize_into(bytes); self.explicit.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyModMap { pub keycode: xproto::Keycode, pub mods: u8, } impl TryParse for KeyModMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let result = KeyModMap { keycode, mods }; Ok((result, remaining)) } } impl Serialize for KeyModMap { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let keycode_bytes = self.keycode.serialize(); let mods_bytes = self.mods.serialize(); [ keycode_bytes[0], mods_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.keycode.serialize_into(bytes); self.mods.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyVModMap { pub keycode: xproto::Keycode, pub vmods: u16, } impl TryParse for KeyVModMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (vmods, remaining) = u16::try_parse(remaining)?; let result = KeyVModMap { keycode, vmods }; Ok((result, remaining)) } } impl Serialize for KeyVModMap { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let keycode_bytes = self.keycode.serialize(); let vmods_bytes = self.vmods.serialize(); [ keycode_bytes[0], 0, vmods_bytes[0], vmods_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.keycode.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.vmods.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KTSetMapEntry { pub level: u8, pub real_mods: u8, pub virtual_mods: u16, } impl TryParse for KTSetMapEntry { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (level, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let result = KTSetMapEntry { level, real_mods, virtual_mods }; Ok((result, remaining)) } } impl Serialize for KTSetMapEntry { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let level_bytes = self.level.serialize(); let real_mods_bytes = self.real_mods.serialize(); let virtual_mods_bytes = self.virtual_mods.serialize(); [ level_bytes[0], real_mods_bytes[0], virtual_mods_bytes[0], virtual_mods_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.level.serialize_into(bytes); self.real_mods.serialize_into(bytes); self.virtual_mods.serialize_into(bytes); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetKeyType { pub mask: u8, pub real_mods: u8, pub virtual_mods: u16, pub num_levels: u8, pub preserve: bool, pub entries: Vec, pub preserve_entries: Vec, } impl TryParse for SetKeyType { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (mask, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (num_levels, remaining) = u8::try_parse(remaining)?; let (n_map_entries, remaining) = u8::try_parse(remaining)?; let (preserve, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (entries, remaining) = crate::x11_utils::parse_list::(remaining, n_map_entries.try_to_usize()?)?; let (preserve_entries, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(preserve).checked_mul(u32::from(n_map_entries)).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let result = SetKeyType { mask, real_mods, virtual_mods, num_levels, preserve, entries, preserve_entries }; Ok((result, remaining)) } } impl Serialize for SetKeyType { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.mask.serialize_into(bytes); self.real_mods.serialize_into(bytes); self.virtual_mods.serialize_into(bytes); self.num_levels.serialize_into(bytes); let n_map_entries = u8::try_from(self.entries.len()).expect("`entries` has too many elements"); n_map_entries.serialize_into(bytes); self.preserve.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.entries.serialize_into(bytes); assert_eq!(self.preserve_entries.len(), usize::try_from(u32::from(self.preserve).checked_mul(u32::from(n_map_entries)).unwrap()).unwrap(), "`preserve_entries` has an incorrect length"); self.preserve_entries.serialize_into(bytes); } } impl SetKeyType { /// Get the value of the `nMapEntries` field. /// /// The `nMapEntries` field is used as the length field of the `entries` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_map_entries(&self) -> u8 { self.entries.len() .try_into().unwrap() } } pub type String8 = u8; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Outline { pub corner_radius: u8, pub points: Vec, } impl TryParse for Outline { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (n_points, remaining) = u8::try_parse(remaining)?; let (corner_radius, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (points, remaining) = crate::x11_utils::parse_list::(remaining, n_points.try_to_usize()?)?; let result = Outline { corner_radius, points }; Ok((result, remaining)) } } impl Serialize for Outline { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); let n_points = u8::try_from(self.points.len()).expect("`points` has too many elements"); n_points.serialize_into(bytes); self.corner_radius.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.points.serialize_into(bytes); } } impl Outline { /// Get the value of the `nPoints` field. /// /// The `nPoints` field is used as the length field of the `points` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_points(&self) -> u8 { self.points.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Shape { pub name: xproto::Atom, pub primary_ndx: u8, pub approx_ndx: u8, pub outlines: Vec, } impl TryParse for Shape { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (n_outlines, remaining) = u8::try_parse(remaining)?; let (primary_ndx, remaining) = u8::try_parse(remaining)?; let (approx_ndx, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (outlines, remaining) = crate::x11_utils::parse_list::(remaining, n_outlines.try_to_usize()?)?; let result = Shape { name, primary_ndx, approx_ndx, outlines }; Ok((result, remaining)) } } impl Serialize for Shape { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.name.serialize_into(bytes); let n_outlines = u8::try_from(self.outlines.len()).expect("`outlines` has too many elements"); n_outlines.serialize_into(bytes); self.primary_ndx.serialize_into(bytes); self.approx_ndx.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.outlines.serialize_into(bytes); } } impl Shape { /// Get the value of the `nOutlines` field. /// /// The `nOutlines` field is used as the length field of the `outlines` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_outlines(&self) -> u8 { self.outlines.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Key { pub name: [String8; 4], pub gap: i16, pub shape_ndx: u8, pub color_ndx: u8, } impl TryParse for Key { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let name = <[u8; 4]>::try_from(name).unwrap(); let (gap, remaining) = i16::try_parse(remaining)?; let (shape_ndx, remaining) = u8::try_parse(remaining)?; let (color_ndx, remaining) = u8::try_parse(remaining)?; let result = Key { name, gap, shape_ndx, color_ndx }; Ok((result, remaining)) } } impl Serialize for Key { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let gap_bytes = self.gap.serialize(); let shape_ndx_bytes = self.shape_ndx.serialize(); let color_ndx_bytes = self.color_ndx.serialize(); [ self.name[0], self.name[1], self.name[2], self.name[3], gap_bytes[0], gap_bytes[1], shape_ndx_bytes[0], color_ndx_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); bytes.extend_from_slice(&self.name); self.gap.serialize_into(bytes); self.shape_ndx.serialize_into(bytes); self.color_ndx.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct OverlayKey { pub over: [String8; 4], pub under: [String8; 4], } impl TryParse for OverlayKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (over, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let over = <[u8; 4]>::try_from(over).unwrap(); let (under, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let under = <[u8; 4]>::try_from(under).unwrap(); let result = OverlayKey { over, under }; Ok((result, remaining)) } } impl Serialize for OverlayKey { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { [ self.over[0], self.over[1], self.over[2], self.over[3], self.under[0], self.under[1], self.under[2], self.under[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); bytes.extend_from_slice(&self.over); bytes.extend_from_slice(&self.under); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct OverlayRow { pub row_under: u8, pub keys: Vec, } impl TryParse for OverlayRow { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (row_under, remaining) = u8::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (keys, remaining) = crate::x11_utils::parse_list::(remaining, n_keys.try_to_usize()?)?; let result = OverlayRow { row_under, keys }; Ok((result, remaining)) } } impl Serialize for OverlayRow { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.row_under.serialize_into(bytes); let n_keys = u8::try_from(self.keys.len()).expect("`keys` has too many elements"); n_keys.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.keys.serialize_into(bytes); } } impl OverlayRow { /// Get the value of the `nKeys` field. /// /// The `nKeys` field is used as the length field of the `keys` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_keys(&self) -> u8 { self.keys.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Overlay { pub name: xproto::Atom, pub rows: Vec, } impl TryParse for Overlay { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (n_rows, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (rows, remaining) = crate::x11_utils::parse_list::(remaining, n_rows.try_to_usize()?)?; let result = Overlay { name, rows }; Ok((result, remaining)) } } impl Serialize for Overlay { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.name.serialize_into(bytes); let n_rows = u8::try_from(self.rows.len()).expect("`rows` has too many elements"); n_rows.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.rows.serialize_into(bytes); } } impl Overlay { /// Get the value of the `nRows` field. /// /// The `nRows` field is used as the length field of the `rows` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_rows(&self) -> u8 { self.rows.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Row { pub top: i16, pub left: i16, pub vertical: bool, pub keys: Vec, } impl TryParse for Row { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (top, remaining) = i16::try_parse(remaining)?; let (left, remaining) = i16::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; let (vertical, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (keys, remaining) = crate::x11_utils::parse_list::(remaining, n_keys.try_to_usize()?)?; let result = Row { top, left, vertical, keys }; Ok((result, remaining)) } } impl Serialize for Row { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.top.serialize_into(bytes); self.left.serialize_into(bytes); let n_keys = u8::try_from(self.keys.len()).expect("`keys` has too many elements"); n_keys.serialize_into(bytes); self.vertical.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.keys.serialize_into(bytes); } } impl Row { /// Get the value of the `nKeys` field. /// /// The `nKeys` field is used as the length field of the `keys` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_keys(&self) -> u8 { self.keys.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct DoodadType(u8); impl DoodadType { pub const OUTLINE: Self = Self(1); pub const SOLID: Self = Self(2); pub const TEXT: Self = Self(3); pub const INDICATOR: Self = Self(4); pub const LOGO: Self = Self(5); } impl From for u8 { #[inline] fn from(input: DoodadType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: DoodadType) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: DoodadType) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: DoodadType) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: DoodadType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: DoodadType) -> Self { Some(u32::from(input.0)) } } impl From for DoodadType { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for DoodadType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::OUTLINE.0.into(), "OUTLINE", "Outline"), (Self::SOLID.0.into(), "SOLID", "Solid"), (Self::TEXT.0.into(), "TEXT", "Text"), (Self::INDICATOR.0.into(), "INDICATOR", "Indicator"), (Self::LOGO.0.into(), "LOGO", "Logo"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Listing { pub flags: u16, pub string: Vec, } impl TryParse for Listing { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (flags, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u16::try_parse(remaining)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, length.try_to_usize()?)?; let string = string.to_vec(); // Align offset to multiple of 2 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (2 - (offset % 2)) % 2; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = Listing { flags, string }; Ok((result, remaining)) } } impl Serialize for Listing { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.flags.serialize_into(bytes); let length = u16::try_from(self.string.len()).expect("`string` has too many elements"); length.serialize_into(bytes); bytes.extend_from_slice(&self.string); bytes.extend_from_slice(&[0; 1][..(2 - (bytes.len() % 2)) % 2]); } } impl Listing { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `string` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u16 { self.string.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct DeviceLedInfo { pub led_class: LedClass, pub led_id: IDSpec, pub names_present: u32, pub maps_present: u32, pub phys_indicators: u32, pub state: u32, pub names: Vec, pub maps: Vec, } impl TryParse for DeviceLedInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (led_class, remaining) = LedClassSpec::try_parse(remaining)?; let (led_id, remaining) = IDSpec::try_parse(remaining)?; let (names_present, remaining) = u32::try_parse(remaining)?; let (maps_present, remaining) = u32::try_parse(remaining)?; let (phys_indicators, remaining) = u32::try_parse(remaining)?; let (state, remaining) = u32::try_parse(remaining)?; let (names, remaining) = crate::x11_utils::parse_list::(remaining, names_present.count_ones().try_to_usize()?)?; let (maps, remaining) = crate::x11_utils::parse_list::(remaining, maps_present.count_ones().try_to_usize()?)?; let led_class = led_class.into(); let result = DeviceLedInfo { led_class, led_id, names_present, maps_present, phys_indicators, state, names, maps }; Ok((result, remaining)) } } impl Serialize for DeviceLedInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(20); LedClassSpec::from(self.led_class).serialize_into(bytes); self.led_id.serialize_into(bytes); self.names_present.serialize_into(bytes); self.maps_present.serialize_into(bytes); self.phys_indicators.serialize_into(bytes); self.state.serialize_into(bytes); assert_eq!(self.names.len(), usize::try_from(self.names_present.count_ones()).unwrap(), "`names` has an incorrect length"); self.names.serialize_into(bytes); assert_eq!(self.maps.len(), usize::try_from(self.maps_present.count_ones()).unwrap(), "`maps` has an incorrect length"); self.maps.serialize_into(bytes); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Error(u8); impl Error { pub const BAD_DEVICE: Self = Self(255); pub const BAD_CLASS: Self = Self(254); pub const BAD_ID: Self = Self(253); } impl From for u8 { #[inline] fn from(input: Error) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Error) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Error) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Error) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Error) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Error) -> Self { Some(u32::from(input.0)) } } impl From for Error { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Error { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::BAD_DEVICE.0.into(), "BAD_DEVICE", "BadDevice"), (Self::BAD_CLASS.0.into(), "BAD_CLASS", "BadClass"), (Self::BAD_ID.0.into(), "BAD_ID", "BadId"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the Keyboard error pub const KEYBOARD_ERROR: u8 = 0; #[derive(Clone, Copy, PartialEq, Eq)] pub struct SA(u8); impl SA { pub const CLEAR_LOCKS: Self = Self(1 << 0); pub const LATCH_TO_LOCK: Self = Self(1 << 1); pub const USE_MOD_MAP_MODS: Self = Self(1 << 2); pub const GROUP_ABSOLUTE: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: SA) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SA) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SA) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SA) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SA) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SA) -> Self { Some(u32::from(input.0)) } } impl From for SA { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SA { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CLEAR_LOCKS.0.into(), "CLEAR_LOCKS", "ClearLocks"), (Self::LATCH_TO_LOCK.0.into(), "LATCH_TO_LOCK", "LatchToLock"), (Self::USE_MOD_MAP_MODS.0.into(), "USE_MOD_MAP_MODS", "UseModMapMods"), (Self::GROUP_ABSOLUTE.0.into(), "GROUP_ABSOLUTE", "GroupAbsolute"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SA, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct SAType(u8); impl SAType { pub const NO_ACTION: Self = Self(0); pub const SET_MODS: Self = Self(1); pub const LATCH_MODS: Self = Self(2); pub const LOCK_MODS: Self = Self(3); pub const SET_GROUP: Self = Self(4); pub const LATCH_GROUP: Self = Self(5); pub const LOCK_GROUP: Self = Self(6); pub const MOVE_PTR: Self = Self(7); pub const PTR_BTN: Self = Self(8); pub const LOCK_PTR_BTN: Self = Self(9); pub const SET_PTR_DFLT: Self = Self(10); pub const ISO_LOCK: Self = Self(11); pub const TERMINATE: Self = Self(12); pub const SWITCH_SCREEN: Self = Self(13); pub const SET_CONTROLS: Self = Self(14); pub const LOCK_CONTROLS: Self = Self(15); pub const ACTION_MESSAGE: Self = Self(16); pub const REDIRECT_KEY: Self = Self(17); pub const DEVICE_BTN: Self = Self(18); pub const LOCK_DEVICE_BTN: Self = Self(19); pub const DEVICE_VALUATOR: Self = Self(20); } impl From for u8 { #[inline] fn from(input: SAType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SAType) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SAType) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SAType) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SAType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SAType) -> Self { Some(u32::from(input.0)) } } impl From for SAType { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SAType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_ACTION.0.into(), "NO_ACTION", "NoAction"), (Self::SET_MODS.0.into(), "SET_MODS", "SetMods"), (Self::LATCH_MODS.0.into(), "LATCH_MODS", "LatchMods"), (Self::LOCK_MODS.0.into(), "LOCK_MODS", "LockMods"), (Self::SET_GROUP.0.into(), "SET_GROUP", "SetGroup"), (Self::LATCH_GROUP.0.into(), "LATCH_GROUP", "LatchGroup"), (Self::LOCK_GROUP.0.into(), "LOCK_GROUP", "LockGroup"), (Self::MOVE_PTR.0.into(), "MOVE_PTR", "MovePtr"), (Self::PTR_BTN.0.into(), "PTR_BTN", "PtrBtn"), (Self::LOCK_PTR_BTN.0.into(), "LOCK_PTR_BTN", "LockPtrBtn"), (Self::SET_PTR_DFLT.0.into(), "SET_PTR_DFLT", "SetPtrDflt"), (Self::ISO_LOCK.0.into(), "ISO_LOCK", "ISOLock"), (Self::TERMINATE.0.into(), "TERMINATE", "Terminate"), (Self::SWITCH_SCREEN.0.into(), "SWITCH_SCREEN", "SwitchScreen"), (Self::SET_CONTROLS.0.into(), "SET_CONTROLS", "SetControls"), (Self::LOCK_CONTROLS.0.into(), "LOCK_CONTROLS", "LockControls"), (Self::ACTION_MESSAGE.0.into(), "ACTION_MESSAGE", "ActionMessage"), (Self::REDIRECT_KEY.0.into(), "REDIRECT_KEY", "RedirectKey"), (Self::DEVICE_BTN.0.into(), "DEVICE_BTN", "DeviceBtn"), (Self::LOCK_DEVICE_BTN.0.into(), "LOCK_DEVICE_BTN", "LockDeviceBtn"), (Self::DEVICE_VALUATOR.0.into(), "DEVICE_VALUATOR", "DeviceValuator"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SANoAction { pub type_: SAType, } impl TryParse for SANoAction { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(7..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SANoAction { type_ }; Ok((result, remaining)) } } impl Serialize for SANoAction { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); [ type_bytes[0], 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); bytes.extend_from_slice(&[0; 7]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SASetMods { pub type_: SAType, pub flags: u8, pub mask: u8, pub real_mods: u8, pub vmods_high: u8, pub vmods_low: u8, } impl TryParse for SASetMods { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (mask, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (vmods_high, remaining) = u8::try_parse(remaining)?; let (vmods_low, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SASetMods { type_, flags, mask, real_mods, vmods_high, vmods_low }; Ok((result, remaining)) } } impl Serialize for SASetMods { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let mask_bytes = self.mask.serialize(); let real_mods_bytes = self.real_mods.serialize(); let vmods_high_bytes = self.vmods_high.serialize(); let vmods_low_bytes = self.vmods_low.serialize(); [ type_bytes[0], flags_bytes[0], mask_bytes[0], real_mods_bytes[0], vmods_high_bytes[0], vmods_low_bytes[0], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.mask.serialize_into(bytes); self.real_mods.serialize_into(bytes); self.vmods_high.serialize_into(bytes); self.vmods_low.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } pub type SALatchMods = SASetMods; pub type SALockMods = SASetMods; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SASetGroup { pub type_: SAType, pub flags: u8, pub group: i8, } impl TryParse for SASetGroup { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (group, remaining) = i8::try_parse(remaining)?; let remaining = remaining.get(5..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SASetGroup { type_, flags, group }; Ok((result, remaining)) } } impl Serialize for SASetGroup { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let group_bytes = self.group.serialize(); [ type_bytes[0], flags_bytes[0], group_bytes[0], 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.group.serialize_into(bytes); bytes.extend_from_slice(&[0; 5]); } } pub type SALatchGroup = SASetGroup; pub type SALockGroup = SASetGroup; #[derive(Clone, Copy, PartialEq, Eq)] pub struct SAMovePtrFlag(u8); impl SAMovePtrFlag { pub const NO_ACCELERATION: Self = Self(1 << 0); pub const MOVE_ABSOLUTE_X: Self = Self(1 << 1); pub const MOVE_ABSOLUTE_Y: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: SAMovePtrFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SAMovePtrFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SAMovePtrFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SAMovePtrFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SAMovePtrFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SAMovePtrFlag) -> Self { Some(u32::from(input.0)) } } impl From for SAMovePtrFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SAMovePtrFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_ACCELERATION.0.into(), "NO_ACCELERATION", "NoAcceleration"), (Self::MOVE_ABSOLUTE_X.0.into(), "MOVE_ABSOLUTE_X", "MoveAbsoluteX"), (Self::MOVE_ABSOLUTE_Y.0.into(), "MOVE_ABSOLUTE_Y", "MoveAbsoluteY"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SAMovePtrFlag, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SAMovePtr { pub type_: SAType, pub flags: u8, pub x_high: i8, pub x_low: u8, pub y_high: i8, pub y_low: u8, } impl TryParse for SAMovePtr { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (x_high, remaining) = i8::try_parse(remaining)?; let (x_low, remaining) = u8::try_parse(remaining)?; let (y_high, remaining) = i8::try_parse(remaining)?; let (y_low, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SAMovePtr { type_, flags, x_high, x_low, y_high, y_low }; Ok((result, remaining)) } } impl Serialize for SAMovePtr { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let x_high_bytes = self.x_high.serialize(); let x_low_bytes = self.x_low.serialize(); let y_high_bytes = self.y_high.serialize(); let y_low_bytes = self.y_low.serialize(); [ type_bytes[0], flags_bytes[0], x_high_bytes[0], x_low_bytes[0], y_high_bytes[0], y_low_bytes[0], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.x_high.serialize_into(bytes); self.x_low.serialize_into(bytes); self.y_high.serialize_into(bytes); self.y_low.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SAPtrBtn { pub type_: SAType, pub flags: u8, pub count: u8, pub button: u8, } impl TryParse for SAPtrBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (count, remaining) = u8::try_parse(remaining)?; let (button, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SAPtrBtn { type_, flags, count, button }; Ok((result, remaining)) } } impl Serialize for SAPtrBtn { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let count_bytes = self.count.serialize(); let button_bytes = self.button.serialize(); [ type_bytes[0], flags_bytes[0], count_bytes[0], button_bytes[0], 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.count.serialize_into(bytes); self.button.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SALockPtrBtn { pub type_: SAType, pub flags: u8, pub button: u8, } impl TryParse for SALockPtrBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (button, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SALockPtrBtn { type_, flags, button }; Ok((result, remaining)) } } impl Serialize for SALockPtrBtn { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let button_bytes = self.button.serialize(); [ type_bytes[0], flags_bytes[0], 0, button_bytes[0], 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.button.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SASetPtrDfltFlag(u8); impl SASetPtrDfltFlag { pub const DFLT_BTN_ABSOLUTE: Self = Self(1 << 2); pub const AFFECT_DFLT_BUTTON: Self = Self(1 << 0); } impl From for u8 { #[inline] fn from(input: SASetPtrDfltFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SASetPtrDfltFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SASetPtrDfltFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SASetPtrDfltFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SASetPtrDfltFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SASetPtrDfltFlag) -> Self { Some(u32::from(input.0)) } } impl From for SASetPtrDfltFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SASetPtrDfltFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::DFLT_BTN_ABSOLUTE.0.into(), "DFLT_BTN_ABSOLUTE", "DfltBtnAbsolute"), (Self::AFFECT_DFLT_BUTTON.0.into(), "AFFECT_DFLT_BUTTON", "AffectDfltButton"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SASetPtrDfltFlag, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SASetPtrDflt { pub type_: SAType, pub flags: u8, pub affect: u8, pub value: i8, } impl TryParse for SASetPtrDflt { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (affect, remaining) = u8::try_parse(remaining)?; let (value, remaining) = i8::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SASetPtrDflt { type_, flags, affect, value }; Ok((result, remaining)) } } impl Serialize for SASetPtrDflt { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let affect_bytes = self.affect.serialize(); let value_bytes = self.value.serialize(); [ type_bytes[0], flags_bytes[0], affect_bytes[0], value_bytes[0], 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.affect.serialize_into(bytes); self.value.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SAIsoLockFlag(u8); impl SAIsoLockFlag { pub const NO_LOCK: Self = Self(1 << 0); pub const NO_UNLOCK: Self = Self(1 << 1); pub const USE_MOD_MAP_MODS: Self = Self(1 << 2); pub const GROUP_ABSOLUTE: Self = Self(1 << 2); pub const ISO_DFLT_IS_GROUP: Self = Self(1 << 3); } impl From for u8 { #[inline] fn from(input: SAIsoLockFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SAIsoLockFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SAIsoLockFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SAIsoLockFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SAIsoLockFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SAIsoLockFlag) -> Self { Some(u32::from(input.0)) } } impl From for SAIsoLockFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SAIsoLockFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_LOCK.0.into(), "NO_LOCK", "NoLock"), (Self::NO_UNLOCK.0.into(), "NO_UNLOCK", "NoUnlock"), (Self::USE_MOD_MAP_MODS.0.into(), "USE_MOD_MAP_MODS", "UseModMapMods"), (Self::GROUP_ABSOLUTE.0.into(), "GROUP_ABSOLUTE", "GroupAbsolute"), (Self::ISO_DFLT_IS_GROUP.0.into(), "ISO_DFLT_IS_GROUP", "ISODfltIsGroup"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SAIsoLockFlag, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct SAIsoLockNoAffect(u8); impl SAIsoLockNoAffect { pub const CTRLS: Self = Self(1 << 3); pub const PTR: Self = Self(1 << 4); pub const GROUP: Self = Self(1 << 5); pub const MODS: Self = Self(1 << 6); } impl From for u8 { #[inline] fn from(input: SAIsoLockNoAffect) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SAIsoLockNoAffect) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SAIsoLockNoAffect) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SAIsoLockNoAffect) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SAIsoLockNoAffect) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SAIsoLockNoAffect) -> Self { Some(u32::from(input.0)) } } impl From for SAIsoLockNoAffect { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SAIsoLockNoAffect { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::CTRLS.0.into(), "CTRLS", "Ctrls"), (Self::PTR.0.into(), "PTR", "Ptr"), (Self::GROUP.0.into(), "GROUP", "Group"), (Self::MODS.0.into(), "MODS", "Mods"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SAIsoLockNoAffect, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SAIsoLock { pub type_: SAType, pub flags: u8, pub mask: u8, pub real_mods: u8, pub group: i8, pub affect: u8, pub vmods_high: u8, pub vmods_low: u8, } impl TryParse for SAIsoLock { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (mask, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (group, remaining) = i8::try_parse(remaining)?; let (affect, remaining) = u8::try_parse(remaining)?; let (vmods_high, remaining) = u8::try_parse(remaining)?; let (vmods_low, remaining) = u8::try_parse(remaining)?; let type_ = type_.into(); let result = SAIsoLock { type_, flags, mask, real_mods, group, affect, vmods_high, vmods_low }; Ok((result, remaining)) } } impl Serialize for SAIsoLock { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let mask_bytes = self.mask.serialize(); let real_mods_bytes = self.real_mods.serialize(); let group_bytes = self.group.serialize(); let affect_bytes = self.affect.serialize(); let vmods_high_bytes = self.vmods_high.serialize(); let vmods_low_bytes = self.vmods_low.serialize(); [ type_bytes[0], flags_bytes[0], mask_bytes[0], real_mods_bytes[0], group_bytes[0], affect_bytes[0], vmods_high_bytes[0], vmods_low_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.mask.serialize_into(bytes); self.real_mods.serialize_into(bytes); self.group.serialize_into(bytes); self.affect.serialize_into(bytes); self.vmods_high.serialize_into(bytes); self.vmods_low.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SATerminate { pub type_: SAType, } impl TryParse for SATerminate { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(7..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SATerminate { type_ }; Ok((result, remaining)) } } impl Serialize for SATerminate { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); [ type_bytes[0], 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); bytes.extend_from_slice(&[0; 7]); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SwitchScreenFlag(u8); impl SwitchScreenFlag { pub const APPLICATION: Self = Self(1 << 0); pub const ABSOLUTE: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: SwitchScreenFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SwitchScreenFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SwitchScreenFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SwitchScreenFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SwitchScreenFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SwitchScreenFlag) -> Self { Some(u32::from(input.0)) } } impl From for SwitchScreenFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SwitchScreenFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::APPLICATION.0.into(), "APPLICATION", "Application"), (Self::ABSOLUTE.0.into(), "ABSOLUTE", "Absolute"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(SwitchScreenFlag, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SASwitchScreen { pub type_: SAType, pub flags: u8, pub new_screen: i8, } impl TryParse for SASwitchScreen { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (new_screen, remaining) = i8::try_parse(remaining)?; let remaining = remaining.get(5..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SASwitchScreen { type_, flags, new_screen }; Ok((result, remaining)) } } impl Serialize for SASwitchScreen { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let new_screen_bytes = self.new_screen.serialize(); [ type_bytes[0], flags_bytes[0], new_screen_bytes[0], 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.new_screen.serialize_into(bytes); bytes.extend_from_slice(&[0; 5]); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct BoolCtrlsHigh(u8); impl BoolCtrlsHigh { pub const ACCESS_X_FEEDBACK: Self = Self(1 << 0); pub const AUDIBLE_BELL: Self = Self(1 << 1); pub const OVERLAY1: Self = Self(1 << 2); pub const OVERLAY2: Self = Self(1 << 3); pub const IGNORE_GROUP_LOCK: Self = Self(1 << 4); } impl From for u8 { #[inline] fn from(input: BoolCtrlsHigh) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BoolCtrlsHigh) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: BoolCtrlsHigh) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: BoolCtrlsHigh) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: BoolCtrlsHigh) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BoolCtrlsHigh) -> Self { Some(u32::from(input.0)) } } impl From for BoolCtrlsHigh { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for BoolCtrlsHigh { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ACCESS_X_FEEDBACK.0.into(), "ACCESS_X_FEEDBACK", "AccessXFeedback"), (Self::AUDIBLE_BELL.0.into(), "AUDIBLE_BELL", "AudibleBell"), (Self::OVERLAY1.0.into(), "OVERLAY1", "Overlay1"), (Self::OVERLAY2.0.into(), "OVERLAY2", "Overlay2"), (Self::IGNORE_GROUP_LOCK.0.into(), "IGNORE_GROUP_LOCK", "IgnoreGroupLock"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(BoolCtrlsHigh, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct BoolCtrlsLow(u8); impl BoolCtrlsLow { pub const REPEAT_KEYS: Self = Self(1 << 0); pub const SLOW_KEYS: Self = Self(1 << 1); pub const BOUNCE_KEYS: Self = Self(1 << 2); pub const STICKY_KEYS: Self = Self(1 << 3); pub const MOUSE_KEYS: Self = Self(1 << 4); pub const MOUSE_KEYS_ACCEL: Self = Self(1 << 5); pub const ACCESS_X_KEYS: Self = Self(1 << 6); pub const ACCESS_X_TIMEOUT: Self = Self(1 << 7); } impl From for u8 { #[inline] fn from(input: BoolCtrlsLow) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BoolCtrlsLow) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: BoolCtrlsLow) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: BoolCtrlsLow) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: BoolCtrlsLow) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: BoolCtrlsLow) -> Self { Some(u32::from(input.0)) } } impl From for BoolCtrlsLow { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for BoolCtrlsLow { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::REPEAT_KEYS.0.into(), "REPEAT_KEYS", "RepeatKeys"), (Self::SLOW_KEYS.0.into(), "SLOW_KEYS", "SlowKeys"), (Self::BOUNCE_KEYS.0.into(), "BOUNCE_KEYS", "BounceKeys"), (Self::STICKY_KEYS.0.into(), "STICKY_KEYS", "StickyKeys"), (Self::MOUSE_KEYS.0.into(), "MOUSE_KEYS", "MouseKeys"), (Self::MOUSE_KEYS_ACCEL.0.into(), "MOUSE_KEYS_ACCEL", "MouseKeysAccel"), (Self::ACCESS_X_KEYS.0.into(), "ACCESS_X_KEYS", "AccessXKeys"), (Self::ACCESS_X_TIMEOUT.0.into(), "ACCESS_X_TIMEOUT", "AccessXTimeout"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(BoolCtrlsLow, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SASetControls { pub type_: SAType, pub bool_ctrls_high: u8, pub bool_ctrls_low: u8, } impl TryParse for SASetControls { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (bool_ctrls_high, remaining) = u8::try_parse(remaining)?; let (bool_ctrls_low, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SASetControls { type_, bool_ctrls_high, bool_ctrls_low }; Ok((result, remaining)) } } impl Serialize for SASetControls { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let bool_ctrls_high_bytes = self.bool_ctrls_high.serialize(); let bool_ctrls_low_bytes = self.bool_ctrls_low.serialize(); [ type_bytes[0], 0, 0, 0, bool_ctrls_high_bytes[0], bool_ctrls_low_bytes[0], 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.bool_ctrls_high.serialize_into(bytes); self.bool_ctrls_low.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); } } pub type SALockControls = SASetControls; #[derive(Clone, Copy, PartialEq, Eq)] pub struct ActionMessageFlag(u8); impl ActionMessageFlag { pub const ON_PRESS: Self = Self(1 << 0); pub const ON_RELEASE: Self = Self(1 << 1); pub const GEN_KEY_EVENT: Self = Self(1 << 2); } impl From for u8 { #[inline] fn from(input: ActionMessageFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ActionMessageFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ActionMessageFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ActionMessageFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ActionMessageFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ActionMessageFlag) -> Self { Some(u32::from(input.0)) } } impl From for ActionMessageFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ActionMessageFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ON_PRESS.0.into(), "ON_PRESS", "OnPress"), (Self::ON_RELEASE.0.into(), "ON_RELEASE", "OnRelease"), (Self::GEN_KEY_EVENT.0.into(), "GEN_KEY_EVENT", "GenKeyEvent"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ActionMessageFlag, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SAActionMessage { pub type_: SAType, pub flags: u8, pub message: [u8; 6], } impl TryParse for SAActionMessage { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (message, remaining) = crate::x11_utils::parse_u8_list(remaining, 6)?; let message = <[u8; 6]>::try_from(message).unwrap(); let type_ = type_.into(); let result = SAActionMessage { type_, flags, message }; Ok((result, remaining)) } } impl Serialize for SAActionMessage { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); [ type_bytes[0], flags_bytes[0], self.message[0], self.message[1], self.message[2], self.message[3], self.message[4], self.message[5], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); bytes.extend_from_slice(&self.message); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SARedirectKey { pub type_: SAType, pub newkey: xproto::Keycode, pub mask: u8, pub real_modifiers: u8, pub vmods_mask_high: u8, pub vmods_mask_low: u8, pub vmods_high: u8, pub vmods_low: u8, } impl TryParse for SARedirectKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (newkey, remaining) = xproto::Keycode::try_parse(remaining)?; let (mask, remaining) = u8::try_parse(remaining)?; let (real_modifiers, remaining) = u8::try_parse(remaining)?; let (vmods_mask_high, remaining) = u8::try_parse(remaining)?; let (vmods_mask_low, remaining) = u8::try_parse(remaining)?; let (vmods_high, remaining) = u8::try_parse(remaining)?; let (vmods_low, remaining) = u8::try_parse(remaining)?; let type_ = type_.into(); let result = SARedirectKey { type_, newkey, mask, real_modifiers, vmods_mask_high, vmods_mask_low, vmods_high, vmods_low }; Ok((result, remaining)) } } impl Serialize for SARedirectKey { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let newkey_bytes = self.newkey.serialize(); let mask_bytes = self.mask.serialize(); let real_modifiers_bytes = self.real_modifiers.serialize(); let vmods_mask_high_bytes = self.vmods_mask_high.serialize(); let vmods_mask_low_bytes = self.vmods_mask_low.serialize(); let vmods_high_bytes = self.vmods_high.serialize(); let vmods_low_bytes = self.vmods_low.serialize(); [ type_bytes[0], newkey_bytes[0], mask_bytes[0], real_modifiers_bytes[0], vmods_mask_high_bytes[0], vmods_mask_low_bytes[0], vmods_high_bytes[0], vmods_low_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.newkey.serialize_into(bytes); self.mask.serialize_into(bytes); self.real_modifiers.serialize_into(bytes); self.vmods_mask_high.serialize_into(bytes); self.vmods_mask_low.serialize_into(bytes); self.vmods_high.serialize_into(bytes); self.vmods_low.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SADeviceBtn { pub type_: SAType, pub flags: u8, pub count: u8, pub button: u8, pub device: u8, } impl TryParse for SADeviceBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (count, remaining) = u8::try_parse(remaining)?; let (button, remaining) = u8::try_parse(remaining)?; let (device, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SADeviceBtn { type_, flags, count, button, device }; Ok((result, remaining)) } } impl Serialize for SADeviceBtn { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let count_bytes = self.count.serialize(); let button_bytes = self.button.serialize(); let device_bytes = self.device.serialize(); [ type_bytes[0], flags_bytes[0], count_bytes[0], button_bytes[0], device_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); self.count.serialize_into(bytes); self.button.serialize_into(bytes); self.device.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct LockDeviceFlags(u8); impl LockDeviceFlags { pub const NO_LOCK: Self = Self(1 << 0); pub const NO_UNLOCK: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: LockDeviceFlags) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: LockDeviceFlags) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: LockDeviceFlags) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: LockDeviceFlags) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: LockDeviceFlags) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: LockDeviceFlags) -> Self { Some(u32::from(input.0)) } } impl From for LockDeviceFlags { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for LockDeviceFlags { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_LOCK.0.into(), "NO_LOCK", "NoLock"), (Self::NO_UNLOCK.0.into(), "NO_UNLOCK", "NoUnlock"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(LockDeviceFlags, u8); #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SALockDeviceBtn { pub type_: SAType, pub flags: u8, pub button: u8, pub device: u8, } impl TryParse for SALockDeviceBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (button, remaining) = u8::try_parse(remaining)?; let (device, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let result = SALockDeviceBtn { type_, flags, button, device }; Ok((result, remaining)) } } impl Serialize for SALockDeviceBtn { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let flags_bytes = self.flags.serialize(); let button_bytes = self.button.serialize(); let device_bytes = self.device.serialize(); [ type_bytes[0], flags_bytes[0], 0, button_bytes[0], device_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.flags.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.button.serialize_into(bytes); self.device.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct SAValWhat(u8); impl SAValWhat { pub const IGNORE_VAL: Self = Self(0); pub const SET_VAL_MIN: Self = Self(1); pub const SET_VAL_CENTER: Self = Self(2); pub const SET_VAL_MAX: Self = Self(3); pub const SET_VAL_RELATIVE: Self = Self(4); pub const SET_VAL_ABSOLUTE: Self = Self(5); } impl From for u8 { #[inline] fn from(input: SAValWhat) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: SAValWhat) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: SAValWhat) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: SAValWhat) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: SAValWhat) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: SAValWhat) -> Self { Some(u32::from(input.0)) } } impl From for SAValWhat { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for SAValWhat { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::IGNORE_VAL.0.into(), "IGNORE_VAL", "IgnoreVal"), (Self::SET_VAL_MIN.0.into(), "SET_VAL_MIN", "SetValMin"), (Self::SET_VAL_CENTER.0.into(), "SET_VAL_CENTER", "SetValCenter"), (Self::SET_VAL_MAX.0.into(), "SET_VAL_MAX", "SetValMax"), (Self::SET_VAL_RELATIVE.0.into(), "SET_VAL_RELATIVE", "SetValRelative"), (Self::SET_VAL_ABSOLUTE.0.into(), "SET_VAL_ABSOLUTE", "SetValAbsolute"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SADeviceValuator { pub type_: SAType, pub device: u8, pub val1what: SAValWhat, pub val1index: u8, pub val1value: u8, pub val2what: SAValWhat, pub val2index: u8, pub val2value: u8, } impl TryParse for SADeviceValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (device, remaining) = u8::try_parse(remaining)?; let (val1what, remaining) = u8::try_parse(remaining)?; let (val1index, remaining) = u8::try_parse(remaining)?; let (val1value, remaining) = u8::try_parse(remaining)?; let (val2what, remaining) = u8::try_parse(remaining)?; let (val2index, remaining) = u8::try_parse(remaining)?; let (val2value, remaining) = u8::try_parse(remaining)?; let type_ = type_.into(); let val1what = val1what.into(); let val2what = val2what.into(); let result = SADeviceValuator { type_, device, val1what, val1index, val1value, val2what, val2index, val2value }; Ok((result, remaining)) } } impl Serialize for SADeviceValuator { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); let device_bytes = self.device.serialize(); let val1what_bytes = u8::from(self.val1what).serialize(); let val1index_bytes = self.val1index.serialize(); let val1value_bytes = self.val1value.serialize(); let val2what_bytes = u8::from(self.val2what).serialize(); let val2index_bytes = self.val2index.serialize(); let val2value_bytes = self.val2value.serialize(); [ type_bytes[0], device_bytes[0], val1what_bytes[0], val1index_bytes[0], val1value_bytes[0], val2what_bytes[0], val2index_bytes[0], val2value_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); self.device.serialize_into(bytes); u8::from(self.val1what).serialize_into(bytes); self.val1index.serialize_into(bytes); self.val1value.serialize_into(bytes); u8::from(self.val2what).serialize_into(bytes); self.val2index.serialize_into(bytes); self.val2value.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SIAction { pub type_: SAType, pub data: [u8; 7], } impl TryParse for SIAction { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (type_, remaining) = u8::try_parse(remaining)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, 7)?; let data = <[u8; 7]>::try_from(data).unwrap(); let type_ = type_.into(); let result = SIAction { type_, data }; Ok((result, remaining)) } } impl Serialize for SIAction { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let type_bytes = u8::from(self.type_).serialize(); [ type_bytes[0], self.data[0], self.data[1], self.data[2], self.data[3], self.data[4], self.data[5], self.data[6], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); u8::from(self.type_).serialize_into(bytes); bytes.extend_from_slice(&self.data); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SymInterpret { pub sym: xproto::Keysym, pub mods: u8, pub match_: u8, pub virtual_mod: u8, pub flags: u8, pub action: SIAction, } impl TryParse for SymInterpret { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (sym, remaining) = xproto::Keysym::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let (match_, remaining) = u8::try_parse(remaining)?; let (virtual_mod, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (action, remaining) = SIAction::try_parse(remaining)?; let result = SymInterpret { sym, mods, match_, virtual_mod, flags, action }; Ok((result, remaining)) } } impl Serialize for SymInterpret { type Bytes = [u8; 16]; fn serialize(&self) -> [u8; 16] { let sym_bytes = self.sym.serialize(); let mods_bytes = self.mods.serialize(); let match_bytes = self.match_.serialize(); let virtual_mod_bytes = self.virtual_mod.serialize(); let flags_bytes = self.flags.serialize(); let action_bytes = self.action.serialize(); [ sym_bytes[0], sym_bytes[1], sym_bytes[2], sym_bytes[3], mods_bytes[0], match_bytes[0], virtual_mod_bytes[0], flags_bytes[0], action_bytes[0], action_bytes[1], action_bytes[2], action_bytes[3], action_bytes[4], action_bytes[5], action_bytes[6], action_bytes[7], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); self.sym.serialize_into(bytes); self.mods.serialize_into(bytes); self.match_.serialize_into(bytes); self.virtual_mod.serialize_into(bytes); self.flags.serialize_into(bytes); self.action.serialize_into(bytes); } } #[derive(Debug, Copy, Clone)] pub struct Action([u8; 8]); impl Action { pub fn as_noaction(&self) -> SANoAction { fn do_the_parse(remaining: &[u8]) -> Result { let (noaction, remaining) = SANoAction::try_parse(remaining)?; let _ = remaining; Ok(noaction) } do_the_parse(&self.0).unwrap() } pub fn as_setmods(&self) -> SASetMods { fn do_the_parse(remaining: &[u8]) -> Result { let (setmods, remaining) = SASetMods::try_parse(remaining)?; let _ = remaining; Ok(setmods) } do_the_parse(&self.0).unwrap() } pub fn as_latchmods(&self) -> SALatchMods { fn do_the_parse(remaining: &[u8]) -> Result { let (latchmods, remaining) = SALatchMods::try_parse(remaining)?; let _ = remaining; Ok(latchmods) } do_the_parse(&self.0).unwrap() } pub fn as_lockmods(&self) -> SALockMods { fn do_the_parse(remaining: &[u8]) -> Result { let (lockmods, remaining) = SALockMods::try_parse(remaining)?; let _ = remaining; Ok(lockmods) } do_the_parse(&self.0).unwrap() } pub fn as_setgroup(&self) -> SASetGroup { fn do_the_parse(remaining: &[u8]) -> Result { let (setgroup, remaining) = SASetGroup::try_parse(remaining)?; let _ = remaining; Ok(setgroup) } do_the_parse(&self.0).unwrap() } pub fn as_latchgroup(&self) -> SALatchGroup { fn do_the_parse(remaining: &[u8]) -> Result { let (latchgroup, remaining) = SALatchGroup::try_parse(remaining)?; let _ = remaining; Ok(latchgroup) } do_the_parse(&self.0).unwrap() } pub fn as_lockgroup(&self) -> SALockGroup { fn do_the_parse(remaining: &[u8]) -> Result { let (lockgroup, remaining) = SALockGroup::try_parse(remaining)?; let _ = remaining; Ok(lockgroup) } do_the_parse(&self.0).unwrap() } pub fn as_moveptr(&self) -> SAMovePtr { fn do_the_parse(remaining: &[u8]) -> Result { let (moveptr, remaining) = SAMovePtr::try_parse(remaining)?; let _ = remaining; Ok(moveptr) } do_the_parse(&self.0).unwrap() } pub fn as_ptrbtn(&self) -> SAPtrBtn { fn do_the_parse(remaining: &[u8]) -> Result { let (ptrbtn, remaining) = SAPtrBtn::try_parse(remaining)?; let _ = remaining; Ok(ptrbtn) } do_the_parse(&self.0).unwrap() } pub fn as_lockptrbtn(&self) -> SALockPtrBtn { fn do_the_parse(remaining: &[u8]) -> Result { let (lockptrbtn, remaining) = SALockPtrBtn::try_parse(remaining)?; let _ = remaining; Ok(lockptrbtn) } do_the_parse(&self.0).unwrap() } pub fn as_setptrdflt(&self) -> SASetPtrDflt { fn do_the_parse(remaining: &[u8]) -> Result { let (setptrdflt, remaining) = SASetPtrDflt::try_parse(remaining)?; let _ = remaining; Ok(setptrdflt) } do_the_parse(&self.0).unwrap() } pub fn as_isolock(&self) -> SAIsoLock { fn do_the_parse(remaining: &[u8]) -> Result { let (isolock, remaining) = SAIsoLock::try_parse(remaining)?; let _ = remaining; Ok(isolock) } do_the_parse(&self.0).unwrap() } pub fn as_terminate(&self) -> SATerminate { fn do_the_parse(remaining: &[u8]) -> Result { let (terminate, remaining) = SATerminate::try_parse(remaining)?; let _ = remaining; Ok(terminate) } do_the_parse(&self.0).unwrap() } pub fn as_switchscreen(&self) -> SASwitchScreen { fn do_the_parse(remaining: &[u8]) -> Result { let (switchscreen, remaining) = SASwitchScreen::try_parse(remaining)?; let _ = remaining; Ok(switchscreen) } do_the_parse(&self.0).unwrap() } pub fn as_setcontrols(&self) -> SASetControls { fn do_the_parse(remaining: &[u8]) -> Result { let (setcontrols, remaining) = SASetControls::try_parse(remaining)?; let _ = remaining; Ok(setcontrols) } do_the_parse(&self.0).unwrap() } pub fn as_lockcontrols(&self) -> SALockControls { fn do_the_parse(remaining: &[u8]) -> Result { let (lockcontrols, remaining) = SALockControls::try_parse(remaining)?; let _ = remaining; Ok(lockcontrols) } do_the_parse(&self.0).unwrap() } pub fn as_message(&self) -> SAActionMessage { fn do_the_parse(remaining: &[u8]) -> Result { let (message, remaining) = SAActionMessage::try_parse(remaining)?; let _ = remaining; Ok(message) } do_the_parse(&self.0).unwrap() } pub fn as_redirect(&self) -> SARedirectKey { fn do_the_parse(remaining: &[u8]) -> Result { let (redirect, remaining) = SARedirectKey::try_parse(remaining)?; let _ = remaining; Ok(redirect) } do_the_parse(&self.0).unwrap() } pub fn as_devbtn(&self) -> SADeviceBtn { fn do_the_parse(remaining: &[u8]) -> Result { let (devbtn, remaining) = SADeviceBtn::try_parse(remaining)?; let _ = remaining; Ok(devbtn) } do_the_parse(&self.0).unwrap() } pub fn as_lockdevbtn(&self) -> SALockDeviceBtn { fn do_the_parse(remaining: &[u8]) -> Result { let (lockdevbtn, remaining) = SALockDeviceBtn::try_parse(remaining)?; let _ = remaining; Ok(lockdevbtn) } do_the_parse(&self.0).unwrap() } pub fn as_devval(&self) -> SADeviceValuator { fn do_the_parse(remaining: &[u8]) -> Result { let (devval, remaining) = SADeviceValuator::try_parse(remaining)?; let _ = remaining; Ok(devval) } do_the_parse(&self.0).unwrap() } pub fn as_type(&self) -> SAType { fn do_the_parse(remaining: &[u8]) -> Result { let (type_, remaining) = u8::try_parse(remaining)?; let type_ = type_.into(); let _ = remaining; Ok(type_) } do_the_parse(&self.0).unwrap() } } impl Serialize for Action { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { self.0 } fn serialize_into(&self, bytes: &mut Vec) { bytes.extend_from_slice(&self.0); } } impl TryParse for Action { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let inner: [u8; 8] = value.get(..8) .ok_or(ParseError::InsufficientData)? .try_into() .unwrap(); let result = Action(inner); Ok((result, &value[8..])) } } impl From for Action { fn from(noaction: SANoAction) -> Self { let noaction_bytes = noaction.serialize(); Self(noaction_bytes) } } impl From for Action { fn from(setmods: SASetMods) -> Self { let setmods_bytes = setmods.serialize(); Self(setmods_bytes) } } impl From for Action { fn from(setgroup: SASetGroup) -> Self { let setgroup_bytes = setgroup.serialize(); Self(setgroup_bytes) } } impl From for Action { fn from(moveptr: SAMovePtr) -> Self { let moveptr_bytes = moveptr.serialize(); Self(moveptr_bytes) } } impl From for Action { fn from(ptrbtn: SAPtrBtn) -> Self { let ptrbtn_bytes = ptrbtn.serialize(); Self(ptrbtn_bytes) } } impl From for Action { fn from(lockptrbtn: SALockPtrBtn) -> Self { let lockptrbtn_bytes = lockptrbtn.serialize(); Self(lockptrbtn_bytes) } } impl From for Action { fn from(setptrdflt: SASetPtrDflt) -> Self { let setptrdflt_bytes = setptrdflt.serialize(); Self(setptrdflt_bytes) } } impl From for Action { fn from(isolock: SAIsoLock) -> Self { let isolock_bytes = isolock.serialize(); Self(isolock_bytes) } } impl From for Action { fn from(terminate: SATerminate) -> Self { let terminate_bytes = terminate.serialize(); Self(terminate_bytes) } } impl From for Action { fn from(switchscreen: SASwitchScreen) -> Self { let switchscreen_bytes = switchscreen.serialize(); Self(switchscreen_bytes) } } impl From for Action { fn from(setcontrols: SASetControls) -> Self { let setcontrols_bytes = setcontrols.serialize(); Self(setcontrols_bytes) } } impl From for Action { fn from(message: SAActionMessage) -> Self { let message_bytes = message.serialize(); Self(message_bytes) } } impl From for Action { fn from(redirect: SARedirectKey) -> Self { let redirect_bytes = redirect.serialize(); Self(redirect_bytes) } } impl From for Action { fn from(devbtn: SADeviceBtn) -> Self { let devbtn_bytes = devbtn.serialize(); Self(devbtn_bytes) } } impl From for Action { fn from(lockdevbtn: SALockDeviceBtn) -> Self { let lockdevbtn_bytes = lockdevbtn.serialize(); Self(lockdevbtn_bytes) } } impl From for Action { fn from(devval: SADeviceValuator) -> Self { let devval_bytes = devval.serialize(); Self(devval_bytes) } } impl From for Action { fn from(type_: SAType) -> Self { let type_bytes = u8::from(type_).serialize(); let value = [ type_bytes[0], 0, 0, 0, 0, 0, 0, 0, ]; Self(value) } } /// Opcode for the UseExtension request pub const USE_EXTENSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UseExtensionRequest { pub wanted_major: u16, pub wanted_minor: u16, } impl UseExtensionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let wanted_major_bytes = self.wanted_major.serialize(); let wanted_minor_bytes = self.wanted_minor.serialize(); let mut request0 = vec![ extension_information.major_opcode, USE_EXTENSION_REQUEST, 0, 0, wanted_major_bytes[0], wanted_major_bytes[1], wanted_minor_bytes[0], wanted_minor_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != USE_EXTENSION_REQUEST { return Err(ParseError::InvalidValue); } let (wanted_major, remaining) = u16::try_parse(value)?; let (wanted_minor, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(UseExtensionRequest { wanted_major, wanted_minor, }) } } impl Request for UseExtensionRequest { type Reply = UseExtensionReply; } pub fn use_extension(conn: &Conn, wanted_major: u16, wanted_minor: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = UseExtensionRequest { wanted_major, wanted_minor, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UseExtensionReply { pub supported: bool, pub sequence: u16, pub length: u32, pub server_major: u16, pub server_minor: u16, } impl TryParse for UseExtensionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (supported, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major, remaining) = u16::try_parse(remaining)?; let (server_minor, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = UseExtensionReply { supported, sequence, length, server_major, server_minor }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase1 { pub affect_new_keyboard: u16, pub new_keyboard_details: u16, } impl TryParse for SelectEventsAuxBitcase1 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_new_keyboard, remaining) = u16::try_parse(remaining)?; let (new_keyboard_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase1 { affect_new_keyboard, new_keyboard_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase1 { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let affect_new_keyboard_bytes = self.affect_new_keyboard.serialize(); let new_keyboard_details_bytes = self.new_keyboard_details.serialize(); [ affect_new_keyboard_bytes[0], affect_new_keyboard_bytes[1], new_keyboard_details_bytes[0], new_keyboard_details_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.affect_new_keyboard.serialize_into(bytes); self.new_keyboard_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase2 { pub affect_state: u16, pub state_details: u16, } impl TryParse for SelectEventsAuxBitcase2 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_state, remaining) = u16::try_parse(remaining)?; let (state_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase2 { affect_state, state_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase2 { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let affect_state_bytes = self.affect_state.serialize(); let state_details_bytes = self.state_details.serialize(); [ affect_state_bytes[0], affect_state_bytes[1], state_details_bytes[0], state_details_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.affect_state.serialize_into(bytes); self.state_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase3 { pub affect_ctrls: u32, pub ctrl_details: u32, } impl TryParse for SelectEventsAuxBitcase3 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_ctrls, remaining) = u32::try_parse(remaining)?; let (ctrl_details, remaining) = u32::try_parse(remaining)?; let result = SelectEventsAuxBitcase3 { affect_ctrls, ctrl_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase3 { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let affect_ctrls_bytes = self.affect_ctrls.serialize(); let ctrl_details_bytes = self.ctrl_details.serialize(); [ affect_ctrls_bytes[0], affect_ctrls_bytes[1], affect_ctrls_bytes[2], affect_ctrls_bytes[3], ctrl_details_bytes[0], ctrl_details_bytes[1], ctrl_details_bytes[2], ctrl_details_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.affect_ctrls.serialize_into(bytes); self.ctrl_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase4 { pub affect_indicator_state: u32, pub indicator_state_details: u32, } impl TryParse for SelectEventsAuxBitcase4 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_indicator_state, remaining) = u32::try_parse(remaining)?; let (indicator_state_details, remaining) = u32::try_parse(remaining)?; let result = SelectEventsAuxBitcase4 { affect_indicator_state, indicator_state_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase4 { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let affect_indicator_state_bytes = self.affect_indicator_state.serialize(); let indicator_state_details_bytes = self.indicator_state_details.serialize(); [ affect_indicator_state_bytes[0], affect_indicator_state_bytes[1], affect_indicator_state_bytes[2], affect_indicator_state_bytes[3], indicator_state_details_bytes[0], indicator_state_details_bytes[1], indicator_state_details_bytes[2], indicator_state_details_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.affect_indicator_state.serialize_into(bytes); self.indicator_state_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase5 { pub affect_indicator_map: u32, pub indicator_map_details: u32, } impl TryParse for SelectEventsAuxBitcase5 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_indicator_map, remaining) = u32::try_parse(remaining)?; let (indicator_map_details, remaining) = u32::try_parse(remaining)?; let result = SelectEventsAuxBitcase5 { affect_indicator_map, indicator_map_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase5 { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let affect_indicator_map_bytes = self.affect_indicator_map.serialize(); let indicator_map_details_bytes = self.indicator_map_details.serialize(); [ affect_indicator_map_bytes[0], affect_indicator_map_bytes[1], affect_indicator_map_bytes[2], affect_indicator_map_bytes[3], indicator_map_details_bytes[0], indicator_map_details_bytes[1], indicator_map_details_bytes[2], indicator_map_details_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.affect_indicator_map.serialize_into(bytes); self.indicator_map_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase6 { pub affect_names: u16, pub names_details: u16, } impl TryParse for SelectEventsAuxBitcase6 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_names, remaining) = u16::try_parse(remaining)?; let (names_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase6 { affect_names, names_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase6 { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let affect_names_bytes = self.affect_names.serialize(); let names_details_bytes = self.names_details.serialize(); [ affect_names_bytes[0], affect_names_bytes[1], names_details_bytes[0], names_details_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.affect_names.serialize_into(bytes); self.names_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase7 { pub affect_compat: u8, pub compat_details: u8, } impl TryParse for SelectEventsAuxBitcase7 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_compat, remaining) = u8::try_parse(remaining)?; let (compat_details, remaining) = u8::try_parse(remaining)?; let result = SelectEventsAuxBitcase7 { affect_compat, compat_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase7 { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let affect_compat_bytes = self.affect_compat.serialize(); let compat_details_bytes = self.compat_details.serialize(); [ affect_compat_bytes[0], compat_details_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.affect_compat.serialize_into(bytes); self.compat_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase8 { pub affect_bell: u8, pub bell_details: u8, } impl TryParse for SelectEventsAuxBitcase8 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_bell, remaining) = u8::try_parse(remaining)?; let (bell_details, remaining) = u8::try_parse(remaining)?; let result = SelectEventsAuxBitcase8 { affect_bell, bell_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase8 { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let affect_bell_bytes = self.affect_bell.serialize(); let bell_details_bytes = self.bell_details.serialize(); [ affect_bell_bytes[0], bell_details_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.affect_bell.serialize_into(bytes); self.bell_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase9 { pub affect_msg_details: u8, pub msg_details: u8, } impl TryParse for SelectEventsAuxBitcase9 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_msg_details, remaining) = u8::try_parse(remaining)?; let (msg_details, remaining) = u8::try_parse(remaining)?; let result = SelectEventsAuxBitcase9 { affect_msg_details, msg_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase9 { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let affect_msg_details_bytes = self.affect_msg_details.serialize(); let msg_details_bytes = self.msg_details.serialize(); [ affect_msg_details_bytes[0], msg_details_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.affect_msg_details.serialize_into(bytes); self.msg_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase10 { pub affect_access_x: u16, pub access_x_details: u16, } impl TryParse for SelectEventsAuxBitcase10 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_access_x, remaining) = u16::try_parse(remaining)?; let (access_x_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase10 { affect_access_x, access_x_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase10 { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let affect_access_x_bytes = self.affect_access_x.serialize(); let access_x_details_bytes = self.access_x_details.serialize(); [ affect_access_x_bytes[0], affect_access_x_bytes[1], access_x_details_bytes[0], access_x_details_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.affect_access_x.serialize_into(bytes); self.access_x_details.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectEventsAuxBitcase11 { pub affect_ext_dev: u16, pub extdev_details: u16, } impl TryParse for SelectEventsAuxBitcase11 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (affect_ext_dev, remaining) = u16::try_parse(remaining)?; let (extdev_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase11 { affect_ext_dev, extdev_details }; Ok((result, remaining)) } } impl Serialize for SelectEventsAuxBitcase11 { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let affect_ext_dev_bytes = self.affect_ext_dev.serialize(); let extdev_details_bytes = self.extdev_details.serialize(); [ affect_ext_dev_bytes[0], affect_ext_dev_bytes[1], extdev_details_bytes[0], extdev_details_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.affect_ext_dev.serialize_into(bytes); self.extdev_details.serialize_into(bytes); } } /// Auxiliary and optional information for the `select_events` function #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct SelectEventsAux { pub bitcase1: Option, pub bitcase2: Option, pub bitcase3: Option, pub bitcase4: Option, pub bitcase5: Option, pub bitcase6: Option, pub bitcase7: Option, pub bitcase8: Option, pub bitcase9: Option, pub bitcase10: Option, pub bitcase11: Option, } impl SelectEventsAux { fn try_parse(value: &[u8], affect_which: u16, clear: u16, select_all: u16) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(affect_which) & ((!u32::from(clear)) & (!u32::from(select_all))); let mut outer_remaining = value; let bitcase1 = if switch_expr & u32::from(EventType::NEW_KEYBOARD_NOTIFY) != 0 { let (bitcase1, new_remaining) = SelectEventsAuxBitcase1::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase1) } else { None }; let bitcase2 = if switch_expr & u32::from(EventType::STATE_NOTIFY) != 0 { let (bitcase2, new_remaining) = SelectEventsAuxBitcase2::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase2) } else { None }; let bitcase3 = if switch_expr & u32::from(EventType::CONTROLS_NOTIFY) != 0 { let (bitcase3, new_remaining) = SelectEventsAuxBitcase3::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase3) } else { None }; let bitcase4 = if switch_expr & u32::from(EventType::INDICATOR_STATE_NOTIFY) != 0 { let (bitcase4, new_remaining) = SelectEventsAuxBitcase4::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase4) } else { None }; let bitcase5 = if switch_expr & u32::from(EventType::INDICATOR_MAP_NOTIFY) != 0 { let (bitcase5, new_remaining) = SelectEventsAuxBitcase5::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase5) } else { None }; let bitcase6 = if switch_expr & u32::from(EventType::NAMES_NOTIFY) != 0 { let (bitcase6, new_remaining) = SelectEventsAuxBitcase6::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase6) } else { None }; let bitcase7 = if switch_expr & u32::from(EventType::COMPAT_MAP_NOTIFY) != 0 { let (bitcase7, new_remaining) = SelectEventsAuxBitcase7::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase7) } else { None }; let bitcase8 = if switch_expr & u32::from(EventType::BELL_NOTIFY) != 0 { let (bitcase8, new_remaining) = SelectEventsAuxBitcase8::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase8) } else { None }; let bitcase9 = if switch_expr & u32::from(EventType::ACTION_MESSAGE) != 0 { let (bitcase9, new_remaining) = SelectEventsAuxBitcase9::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase9) } else { None }; let bitcase10 = if switch_expr & u32::from(EventType::ACCESS_X_NOTIFY) != 0 { let (bitcase10, new_remaining) = SelectEventsAuxBitcase10::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase10) } else { None }; let bitcase11 = if switch_expr & u32::from(EventType::EXTENSION_DEVICE_NOTIFY) != 0 { let (bitcase11, new_remaining) = SelectEventsAuxBitcase11::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(bitcase11) } else { None }; let result = SelectEventsAux { bitcase1, bitcase2, bitcase3, bitcase4, bitcase5, bitcase6, bitcase7, bitcase8, bitcase9, bitcase10, bitcase11 }; Ok((result, outer_remaining)) } } impl SelectEventsAux { #[allow(dead_code)] fn serialize(&self, affect_which: u16, clear: u16, select_all: u16) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, affect_which, clear, select_all); result } fn serialize_into(&self, bytes: &mut Vec, affect_which: u16, clear: u16, select_all: u16) { assert_eq!(self.switch_expr(), u32::from(affect_which) & ((!u32::from(clear)) & (!u32::from(select_all))), "switch `details` has an inconsistent discriminant"); if let Some(ref bitcase1) = self.bitcase1 { bitcase1.serialize_into(bytes); } if let Some(ref bitcase2) = self.bitcase2 { bitcase2.serialize_into(bytes); } if let Some(ref bitcase3) = self.bitcase3 { bitcase3.serialize_into(bytes); } if let Some(ref bitcase4) = self.bitcase4 { bitcase4.serialize_into(bytes); } if let Some(ref bitcase5) = self.bitcase5 { bitcase5.serialize_into(bytes); } if let Some(ref bitcase6) = self.bitcase6 { bitcase6.serialize_into(bytes); } if let Some(ref bitcase7) = self.bitcase7 { bitcase7.serialize_into(bytes); } if let Some(ref bitcase8) = self.bitcase8 { bitcase8.serialize_into(bytes); } if let Some(ref bitcase9) = self.bitcase9 { bitcase9.serialize_into(bytes); } if let Some(ref bitcase10) = self.bitcase10 { bitcase10.serialize_into(bytes); } if let Some(ref bitcase11) = self.bitcase11 { bitcase11.serialize_into(bytes); } } } impl SelectEventsAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.bitcase1.is_some() { expr_value |= u32::from(EventType::NEW_KEYBOARD_NOTIFY); } if self.bitcase2.is_some() { expr_value |= u32::from(EventType::STATE_NOTIFY); } if self.bitcase3.is_some() { expr_value |= u32::from(EventType::CONTROLS_NOTIFY); } if self.bitcase4.is_some() { expr_value |= u32::from(EventType::INDICATOR_STATE_NOTIFY); } if self.bitcase5.is_some() { expr_value |= u32::from(EventType::INDICATOR_MAP_NOTIFY); } if self.bitcase6.is_some() { expr_value |= u32::from(EventType::NAMES_NOTIFY); } if self.bitcase7.is_some() { expr_value |= u32::from(EventType::COMPAT_MAP_NOTIFY); } if self.bitcase8.is_some() { expr_value |= u32::from(EventType::BELL_NOTIFY); } if self.bitcase9.is_some() { expr_value |= u32::from(EventType::ACTION_MESSAGE); } if self.bitcase10.is_some() { expr_value |= u32::from(EventType::ACCESS_X_NOTIFY); } if self.bitcase11.is_some() { expr_value |= u32::from(EventType::EXTENSION_DEVICE_NOTIFY); } expr_value } } impl SelectEventsAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `bitcase1` field of this structure. pub fn bitcase1(mut self, value: I) -> Self where I: Into> { self.bitcase1 = value.into(); self } /// Set the `bitcase2` field of this structure. pub fn bitcase2(mut self, value: I) -> Self where I: Into> { self.bitcase2 = value.into(); self } /// Set the `bitcase3` field of this structure. pub fn bitcase3(mut self, value: I) -> Self where I: Into> { self.bitcase3 = value.into(); self } /// Set the `bitcase4` field of this structure. pub fn bitcase4(mut self, value: I) -> Self where I: Into> { self.bitcase4 = value.into(); self } /// Set the `bitcase5` field of this structure. pub fn bitcase5(mut self, value: I) -> Self where I: Into> { self.bitcase5 = value.into(); self } /// Set the `bitcase6` field of this structure. pub fn bitcase6(mut self, value: I) -> Self where I: Into> { self.bitcase6 = value.into(); self } /// Set the `bitcase7` field of this structure. pub fn bitcase7(mut self, value: I) -> Self where I: Into> { self.bitcase7 = value.into(); self } /// Set the `bitcase8` field of this structure. pub fn bitcase8(mut self, value: I) -> Self where I: Into> { self.bitcase8 = value.into(); self } /// Set the `bitcase9` field of this structure. pub fn bitcase9(mut self, value: I) -> Self where I: Into> { self.bitcase9 = value.into(); self } /// Set the `bitcase10` field of this structure. pub fn bitcase10(mut self, value: I) -> Self where I: Into> { self.bitcase10 = value.into(); self } /// Set the `bitcase11` field of this structure. pub fn bitcase11(mut self, value: I) -> Self where I: Into> { self.bitcase11 = value.into(); self } } /// Opcode for the SelectEvents request pub const SELECT_EVENTS_REQUEST: u8 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SelectEventsRequest<'input> { pub device_spec: DeviceSpec, pub clear: u16, pub select_all: u16, pub affect_map: u16, pub map: u16, pub details: Cow<'input, SelectEventsAux>, } impl<'input> SelectEventsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let affect_which = u16::try_from(self.details.switch_expr() | (u32::from(self.clear) | u32::from(self.select_all))).unwrap(); let affect_which_bytes = affect_which.serialize(); let clear_bytes = self.clear.serialize(); let select_all_bytes = self.select_all.serialize(); let affect_map_bytes = self.affect_map.serialize(); let map_bytes = self.map.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_EVENTS_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], affect_which_bytes[0], affect_which_bytes[1], clear_bytes[0], clear_bytes[1], select_all_bytes[0], select_all_bytes[1], affect_map_bytes[0], affect_map_bytes[1], map_bytes[0], map_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let details_bytes = self.details.serialize(affect_which, self.clear, self.select_all); let length_so_far = length_so_far + details_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), details_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SELECT_EVENTS_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (affect_which, remaining) = u16::try_parse(remaining)?; let (clear, remaining) = u16::try_parse(remaining)?; let (select_all, remaining) = u16::try_parse(remaining)?; let (affect_map, remaining) = u16::try_parse(remaining)?; let (map, remaining) = u16::try_parse(remaining)?; let (details, remaining) = SelectEventsAux::try_parse(remaining, affect_which, clear, select_all)?; let _ = remaining; Ok(SelectEventsRequest { device_spec, clear, select_all, affect_map, map, details: Cow::Owned(details), }) } /// Clone all borrowed data in this SelectEventsRequest. pub fn into_owned(self) -> SelectEventsRequest<'static> { SelectEventsRequest { device_spec: self.device_spec, clear: self.clear, select_all: self.select_all, affect_map: self.affect_map, map: self.map, details: Cow::Owned(self.details.into_owned()), } } } impl<'input> Request for SelectEventsRequest<'input> { type Reply = (); } pub fn select_events<'c, 'input, Conn, A, B, C, D>(conn: &'c Conn, device_spec: DeviceSpec, clear: A, select_all: B, affect_map: C, map: D, details: &'input SelectEventsAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, D: Into, { let clear: u16 = clear.into(); let select_all: u16 = select_all.into(); let affect_map: u16 = affect_map.into(); let map: u16 = map.into(); let request0 = SelectEventsRequest { device_spec, clear, select_all, affect_map, map, details: Cow::Borrowed(details), }; request0.send(conn) } /// Opcode for the Bell request pub const BELL_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BellRequest { pub device_spec: DeviceSpec, pub bell_class: BellClassSpec, pub bell_id: IDSpec, pub percent: i8, pub force_sound: bool, pub event_only: bool, pub pitch: i16, pub duration: i16, pub name: xproto::Atom, pub window: xproto::Window, } impl BellRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let bell_class_bytes = self.bell_class.serialize(); let bell_id_bytes = self.bell_id.serialize(); let percent_bytes = self.percent.serialize(); let force_sound_bytes = self.force_sound.serialize(); let event_only_bytes = self.event_only.serialize(); let pitch_bytes = self.pitch.serialize(); let duration_bytes = self.duration.serialize(); let name_bytes = self.name.serialize(); let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, BELL_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], bell_class_bytes[0], bell_class_bytes[1], bell_id_bytes[0], bell_id_bytes[1], percent_bytes[0], force_sound_bytes[0], event_only_bytes[0], 0, pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], 0, 0, name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != BELL_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (bell_class, remaining) = BellClassSpec::try_parse(remaining)?; let (bell_id, remaining) = IDSpec::try_parse(remaining)?; let (percent, remaining) = i8::try_parse(remaining)?; let (force_sound, remaining) = bool::try_parse(remaining)?; let (event_only, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (pitch, remaining) = i16::try_parse(remaining)?; let (duration, remaining) = i16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let _ = remaining; Ok(BellRequest { device_spec, bell_class, bell_id, percent, force_sound, event_only, pitch, duration, name, window, }) } } impl Request for BellRequest { type Reply = (); } pub fn bell(conn: &Conn, device_spec: DeviceSpec, bell_class: BellClassSpec, bell_id: IDSpec, percent: i8, force_sound: bool, event_only: bool, pitch: i16, duration: i16, name: xproto::Atom, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = BellRequest { device_spec, bell_class, bell_id, percent, force_sound, event_only, pitch, duration, name, window, }; request0.send(conn) } /// Opcode for the GetState request pub const GET_STATE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetStateRequest { pub device_spec: DeviceSpec, } impl GetStateRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_STATE_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_STATE_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetStateRequest { device_spec, }) } } impl Request for GetStateRequest { type Reply = GetStateReply; } pub fn get_state(conn: &Conn, device_spec: DeviceSpec) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetStateRequest { device_spec, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetStateReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub mods: u8, pub base_mods: u8, pub latched_mods: u8, pub locked_mods: u8, pub group: Group, pub locked_group: Group, pub base_group: i16, pub latched_group: i16, pub compat_state: u8, pub grab_mods: u8, pub compat_grab_mods: u8, pub lookup_mods: u8, pub compat_lookup_mods: u8, pub ptr_btn_state: u16, } impl TryParse for GetStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let (base_mods, remaining) = u8::try_parse(remaining)?; let (latched_mods, remaining) = u8::try_parse(remaining)?; let (locked_mods, remaining) = u8::try_parse(remaining)?; let (group, remaining) = u8::try_parse(remaining)?; let (locked_group, remaining) = u8::try_parse(remaining)?; let (base_group, remaining) = i16::try_parse(remaining)?; let (latched_group, remaining) = i16::try_parse(remaining)?; let (compat_state, remaining) = u8::try_parse(remaining)?; let (grab_mods, remaining) = u8::try_parse(remaining)?; let (compat_grab_mods, remaining) = u8::try_parse(remaining)?; let (lookup_mods, remaining) = u8::try_parse(remaining)?; let (compat_lookup_mods, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (ptr_btn_state, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(6..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let group = group.into(); let locked_group = locked_group.into(); let result = GetStateReply { device_id, sequence, length, mods, base_mods, latched_mods, locked_mods, group, locked_group, base_group, latched_group, compat_state, grab_mods, compat_grab_mods, lookup_mods, compat_lookup_mods, ptr_btn_state }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the LatchLockState request pub const LATCH_LOCK_STATE_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct LatchLockStateRequest { pub device_spec: DeviceSpec, pub affect_mod_locks: u8, pub mod_locks: u8, pub lock_group: bool, pub group_lock: Group, pub affect_mod_latches: u8, pub latch_group: bool, pub group_latch: u16, } impl LatchLockStateRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let affect_mod_locks_bytes = self.affect_mod_locks.serialize(); let mod_locks_bytes = self.mod_locks.serialize(); let lock_group_bytes = self.lock_group.serialize(); let group_lock_bytes = u8::from(self.group_lock).serialize(); let affect_mod_latches_bytes = self.affect_mod_latches.serialize(); let latch_group_bytes = self.latch_group.serialize(); let group_latch_bytes = self.group_latch.serialize(); let mut request0 = vec![ extension_information.major_opcode, LATCH_LOCK_STATE_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], affect_mod_locks_bytes[0], mod_locks_bytes[0], lock_group_bytes[0], group_lock_bytes[0], affect_mod_latches_bytes[0], 0, 0, latch_group_bytes[0], group_latch_bytes[0], group_latch_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LATCH_LOCK_STATE_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (affect_mod_locks, remaining) = u8::try_parse(remaining)?; let (mod_locks, remaining) = u8::try_parse(remaining)?; let (lock_group, remaining) = bool::try_parse(remaining)?; let (group_lock, remaining) = u8::try_parse(remaining)?; let group_lock = group_lock.into(); let (affect_mod_latches, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (latch_group, remaining) = bool::try_parse(remaining)?; let (group_latch, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(LatchLockStateRequest { device_spec, affect_mod_locks, mod_locks, lock_group, group_lock, affect_mod_latches, latch_group, group_latch, }) } } impl Request for LatchLockStateRequest { type Reply = (); } pub fn latch_lock_state(conn: &Conn, device_spec: DeviceSpec, affect_mod_locks: A, mod_locks: B, lock_group: bool, group_lock: Group, affect_mod_latches: C, latch_group: bool, group_latch: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, { let affect_mod_locks: u8 = affect_mod_locks.into(); let mod_locks: u8 = mod_locks.into(); let affect_mod_latches: u8 = affect_mod_latches.into(); let request0 = LatchLockStateRequest { device_spec, affect_mod_locks, mod_locks, lock_group, group_lock, affect_mod_latches, latch_group, group_latch, }; request0.send(conn) } /// Opcode for the GetControls request pub const GET_CONTROLS_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetControlsRequest { pub device_spec: DeviceSpec, } impl GetControlsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CONTROLS_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CONTROLS_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetControlsRequest { device_spec, }) } } impl Request for GetControlsRequest { type Reply = GetControlsReply; } pub fn get_controls(conn: &Conn, device_spec: DeviceSpec) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetControlsRequest { device_spec, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetControlsReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub mouse_keys_dflt_btn: u8, pub num_groups: u8, pub groups_wrap: u8, pub internal_mods_mask: u8, pub ignore_lock_mods_mask: u8, pub internal_mods_real_mods: u8, pub ignore_lock_mods_real_mods: u8, pub internal_mods_vmods: u16, pub ignore_lock_mods_vmods: u16, pub repeat_delay: u16, pub repeat_interval: u16, pub slow_keys_delay: u16, pub debounce_delay: u16, pub mouse_keys_delay: u16, pub mouse_keys_interval: u16, pub mouse_keys_time_to_max: u16, pub mouse_keys_max_speed: u16, pub mouse_keys_curve: i16, pub access_x_option: u16, pub access_x_timeout: u16, pub access_x_timeout_options_mask: u16, pub access_x_timeout_options_values: u16, pub access_x_timeout_mask: u32, pub access_x_timeout_values: u32, pub enabled_controls: u32, pub per_key_repeat: [u8; 32], } impl TryParse for GetControlsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (mouse_keys_dflt_btn, remaining) = u8::try_parse(remaining)?; let (num_groups, remaining) = u8::try_parse(remaining)?; let (groups_wrap, remaining) = u8::try_parse(remaining)?; let (internal_mods_mask, remaining) = u8::try_parse(remaining)?; let (ignore_lock_mods_mask, remaining) = u8::try_parse(remaining)?; let (internal_mods_real_mods, remaining) = u8::try_parse(remaining)?; let (ignore_lock_mods_real_mods, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (internal_mods_vmods, remaining) = u16::try_parse(remaining)?; let (ignore_lock_mods_vmods, remaining) = u16::try_parse(remaining)?; let (repeat_delay, remaining) = u16::try_parse(remaining)?; let (repeat_interval, remaining) = u16::try_parse(remaining)?; let (slow_keys_delay, remaining) = u16::try_parse(remaining)?; let (debounce_delay, remaining) = u16::try_parse(remaining)?; let (mouse_keys_delay, remaining) = u16::try_parse(remaining)?; let (mouse_keys_interval, remaining) = u16::try_parse(remaining)?; let (mouse_keys_time_to_max, remaining) = u16::try_parse(remaining)?; let (mouse_keys_max_speed, remaining) = u16::try_parse(remaining)?; let (mouse_keys_curve, remaining) = i16::try_parse(remaining)?; let (access_x_option, remaining) = u16::try_parse(remaining)?; let (access_x_timeout, remaining) = u16::try_parse(remaining)?; let (access_x_timeout_options_mask, remaining) = u16::try_parse(remaining)?; let (access_x_timeout_options_values, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (access_x_timeout_mask, remaining) = u32::try_parse(remaining)?; let (access_x_timeout_values, remaining) = u32::try_parse(remaining)?; let (enabled_controls, remaining) = u32::try_parse(remaining)?; let (per_key_repeat, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let per_key_repeat = <[u8; 32]>::try_from(per_key_repeat).unwrap(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetControlsReply { device_id, sequence, length, mouse_keys_dflt_btn, num_groups, groups_wrap, internal_mods_mask, ignore_lock_mods_mask, internal_mods_real_mods, ignore_lock_mods_real_mods, internal_mods_vmods, ignore_lock_mods_vmods, repeat_delay, repeat_interval, slow_keys_delay, debounce_delay, mouse_keys_delay, mouse_keys_interval, mouse_keys_time_to_max, mouse_keys_max_speed, mouse_keys_curve, access_x_option, access_x_timeout, access_x_timeout_options_mask, access_x_timeout_options_values, access_x_timeout_mask, access_x_timeout_values, enabled_controls, per_key_repeat }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetControls request pub const SET_CONTROLS_REQUEST: u8 = 7; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetControlsRequest<'input> { pub device_spec: DeviceSpec, pub affect_internal_real_mods: u8, pub internal_real_mods: u8, pub affect_ignore_lock_real_mods: u8, pub ignore_lock_real_mods: u8, pub affect_internal_virtual_mods: u16, pub internal_virtual_mods: u16, pub affect_ignore_lock_virtual_mods: u16, pub ignore_lock_virtual_mods: u16, pub mouse_keys_dflt_btn: u8, pub groups_wrap: u8, pub access_x_options: u16, pub affect_enabled_controls: u32, pub enabled_controls: u32, pub change_controls: u32, pub repeat_delay: u16, pub repeat_interval: u16, pub slow_keys_delay: u16, pub debounce_delay: u16, pub mouse_keys_delay: u16, pub mouse_keys_interval: u16, pub mouse_keys_time_to_max: u16, pub mouse_keys_max_speed: u16, pub mouse_keys_curve: i16, pub access_x_timeout: u16, pub access_x_timeout_mask: u32, pub access_x_timeout_values: u32, pub access_x_timeout_options_mask: u16, pub access_x_timeout_options_values: u16, pub per_key_repeat: Cow<'input, [u8; 32]>, } impl<'input> SetControlsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let affect_internal_real_mods_bytes = self.affect_internal_real_mods.serialize(); let internal_real_mods_bytes = self.internal_real_mods.serialize(); let affect_ignore_lock_real_mods_bytes = self.affect_ignore_lock_real_mods.serialize(); let ignore_lock_real_mods_bytes = self.ignore_lock_real_mods.serialize(); let affect_internal_virtual_mods_bytes = self.affect_internal_virtual_mods.serialize(); let internal_virtual_mods_bytes = self.internal_virtual_mods.serialize(); let affect_ignore_lock_virtual_mods_bytes = self.affect_ignore_lock_virtual_mods.serialize(); let ignore_lock_virtual_mods_bytes = self.ignore_lock_virtual_mods.serialize(); let mouse_keys_dflt_btn_bytes = self.mouse_keys_dflt_btn.serialize(); let groups_wrap_bytes = self.groups_wrap.serialize(); let access_x_options_bytes = self.access_x_options.serialize(); let affect_enabled_controls_bytes = self.affect_enabled_controls.serialize(); let enabled_controls_bytes = self.enabled_controls.serialize(); let change_controls_bytes = self.change_controls.serialize(); let repeat_delay_bytes = self.repeat_delay.serialize(); let repeat_interval_bytes = self.repeat_interval.serialize(); let slow_keys_delay_bytes = self.slow_keys_delay.serialize(); let debounce_delay_bytes = self.debounce_delay.serialize(); let mouse_keys_delay_bytes = self.mouse_keys_delay.serialize(); let mouse_keys_interval_bytes = self.mouse_keys_interval.serialize(); let mouse_keys_time_to_max_bytes = self.mouse_keys_time_to_max.serialize(); let mouse_keys_max_speed_bytes = self.mouse_keys_max_speed.serialize(); let mouse_keys_curve_bytes = self.mouse_keys_curve.serialize(); let access_x_timeout_bytes = self.access_x_timeout.serialize(); let access_x_timeout_mask_bytes = self.access_x_timeout_mask.serialize(); let access_x_timeout_values_bytes = self.access_x_timeout_values.serialize(); let access_x_timeout_options_mask_bytes = self.access_x_timeout_options_mask.serialize(); let access_x_timeout_options_values_bytes = self.access_x_timeout_options_values.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_CONTROLS_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], affect_internal_real_mods_bytes[0], internal_real_mods_bytes[0], affect_ignore_lock_real_mods_bytes[0], ignore_lock_real_mods_bytes[0], affect_internal_virtual_mods_bytes[0], affect_internal_virtual_mods_bytes[1], internal_virtual_mods_bytes[0], internal_virtual_mods_bytes[1], affect_ignore_lock_virtual_mods_bytes[0], affect_ignore_lock_virtual_mods_bytes[1], ignore_lock_virtual_mods_bytes[0], ignore_lock_virtual_mods_bytes[1], mouse_keys_dflt_btn_bytes[0], groups_wrap_bytes[0], access_x_options_bytes[0], access_x_options_bytes[1], 0, 0, affect_enabled_controls_bytes[0], affect_enabled_controls_bytes[1], affect_enabled_controls_bytes[2], affect_enabled_controls_bytes[3], enabled_controls_bytes[0], enabled_controls_bytes[1], enabled_controls_bytes[2], enabled_controls_bytes[3], change_controls_bytes[0], change_controls_bytes[1], change_controls_bytes[2], change_controls_bytes[3], repeat_delay_bytes[0], repeat_delay_bytes[1], repeat_interval_bytes[0], repeat_interval_bytes[1], slow_keys_delay_bytes[0], slow_keys_delay_bytes[1], debounce_delay_bytes[0], debounce_delay_bytes[1], mouse_keys_delay_bytes[0], mouse_keys_delay_bytes[1], mouse_keys_interval_bytes[0], mouse_keys_interval_bytes[1], mouse_keys_time_to_max_bytes[0], mouse_keys_time_to_max_bytes[1], mouse_keys_max_speed_bytes[0], mouse_keys_max_speed_bytes[1], mouse_keys_curve_bytes[0], mouse_keys_curve_bytes[1], access_x_timeout_bytes[0], access_x_timeout_bytes[1], access_x_timeout_mask_bytes[0], access_x_timeout_mask_bytes[1], access_x_timeout_mask_bytes[2], access_x_timeout_mask_bytes[3], access_x_timeout_values_bytes[0], access_x_timeout_values_bytes[1], access_x_timeout_values_bytes[2], access_x_timeout_values_bytes[3], access_x_timeout_options_mask_bytes[0], access_x_timeout_options_mask_bytes[1], access_x_timeout_options_values_bytes[0], access_x_timeout_options_values_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.per_key_repeat.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), Cow::Owned(self.per_key_repeat.to_vec())], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_CONTROLS_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (affect_internal_real_mods, remaining) = u8::try_parse(remaining)?; let (internal_real_mods, remaining) = u8::try_parse(remaining)?; let (affect_ignore_lock_real_mods, remaining) = u8::try_parse(remaining)?; let (ignore_lock_real_mods, remaining) = u8::try_parse(remaining)?; let (affect_internal_virtual_mods, remaining) = u16::try_parse(remaining)?; let (internal_virtual_mods, remaining) = u16::try_parse(remaining)?; let (affect_ignore_lock_virtual_mods, remaining) = u16::try_parse(remaining)?; let (ignore_lock_virtual_mods, remaining) = u16::try_parse(remaining)?; let (mouse_keys_dflt_btn, remaining) = u8::try_parse(remaining)?; let (groups_wrap, remaining) = u8::try_parse(remaining)?; let (access_x_options, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (affect_enabled_controls, remaining) = u32::try_parse(remaining)?; let (enabled_controls, remaining) = u32::try_parse(remaining)?; let (change_controls, remaining) = u32::try_parse(remaining)?; let (repeat_delay, remaining) = u16::try_parse(remaining)?; let (repeat_interval, remaining) = u16::try_parse(remaining)?; let (slow_keys_delay, remaining) = u16::try_parse(remaining)?; let (debounce_delay, remaining) = u16::try_parse(remaining)?; let (mouse_keys_delay, remaining) = u16::try_parse(remaining)?; let (mouse_keys_interval, remaining) = u16::try_parse(remaining)?; let (mouse_keys_time_to_max, remaining) = u16::try_parse(remaining)?; let (mouse_keys_max_speed, remaining) = u16::try_parse(remaining)?; let (mouse_keys_curve, remaining) = i16::try_parse(remaining)?; let (access_x_timeout, remaining) = u16::try_parse(remaining)?; let (access_x_timeout_mask, remaining) = u32::try_parse(remaining)?; let (access_x_timeout_values, remaining) = u32::try_parse(remaining)?; let (access_x_timeout_options_mask, remaining) = u16::try_parse(remaining)?; let (access_x_timeout_options_values, remaining) = u16::try_parse(remaining)?; let (per_key_repeat, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let per_key_repeat = <&[u8; 32]>::try_from(per_key_repeat).unwrap(); let _ = remaining; Ok(SetControlsRequest { device_spec, affect_internal_real_mods, internal_real_mods, affect_ignore_lock_real_mods, ignore_lock_real_mods, affect_internal_virtual_mods, internal_virtual_mods, affect_ignore_lock_virtual_mods, ignore_lock_virtual_mods, mouse_keys_dflt_btn, groups_wrap, access_x_options, affect_enabled_controls, enabled_controls, change_controls, repeat_delay, repeat_interval, slow_keys_delay, debounce_delay, mouse_keys_delay, mouse_keys_interval, mouse_keys_time_to_max, mouse_keys_max_speed, mouse_keys_curve, access_x_timeout, access_x_timeout_mask, access_x_timeout_values, access_x_timeout_options_mask, access_x_timeout_options_values, per_key_repeat: Cow::Borrowed(per_key_repeat), }) } /// Clone all borrowed data in this SetControlsRequest. pub fn into_owned(self) -> SetControlsRequest<'static> { SetControlsRequest { device_spec: self.device_spec, affect_internal_real_mods: self.affect_internal_real_mods, internal_real_mods: self.internal_real_mods, affect_ignore_lock_real_mods: self.affect_ignore_lock_real_mods, ignore_lock_real_mods: self.ignore_lock_real_mods, affect_internal_virtual_mods: self.affect_internal_virtual_mods, internal_virtual_mods: self.internal_virtual_mods, affect_ignore_lock_virtual_mods: self.affect_ignore_lock_virtual_mods, ignore_lock_virtual_mods: self.ignore_lock_virtual_mods, mouse_keys_dflt_btn: self.mouse_keys_dflt_btn, groups_wrap: self.groups_wrap, access_x_options: self.access_x_options, affect_enabled_controls: self.affect_enabled_controls, enabled_controls: self.enabled_controls, change_controls: self.change_controls, repeat_delay: self.repeat_delay, repeat_interval: self.repeat_interval, slow_keys_delay: self.slow_keys_delay, debounce_delay: self.debounce_delay, mouse_keys_delay: self.mouse_keys_delay, mouse_keys_interval: self.mouse_keys_interval, mouse_keys_time_to_max: self.mouse_keys_time_to_max, mouse_keys_max_speed: self.mouse_keys_max_speed, mouse_keys_curve: self.mouse_keys_curve, access_x_timeout: self.access_x_timeout, access_x_timeout_mask: self.access_x_timeout_mask, access_x_timeout_values: self.access_x_timeout_values, access_x_timeout_options_mask: self.access_x_timeout_options_mask, access_x_timeout_options_values: self.access_x_timeout_options_values, per_key_repeat: Cow::Owned(self.per_key_repeat.into_owned()), } } } impl<'input> Request for SetControlsRequest<'input> { type Reply = (); } pub fn set_controls<'c, 'input, Conn, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(conn: &'c Conn, device_spec: DeviceSpec, affect_internal_real_mods: A, internal_real_mods: B, affect_ignore_lock_real_mods: C, ignore_lock_real_mods: D, affect_internal_virtual_mods: E, internal_virtual_mods: F, affect_ignore_lock_virtual_mods: G, ignore_lock_virtual_mods: H, mouse_keys_dflt_btn: u8, groups_wrap: u8, access_x_options: I, affect_enabled_controls: J, enabled_controls: K, change_controls: L, repeat_delay: u16, repeat_interval: u16, slow_keys_delay: u16, debounce_delay: u16, mouse_keys_delay: u16, mouse_keys_interval: u16, mouse_keys_time_to_max: u16, mouse_keys_max_speed: u16, mouse_keys_curve: i16, access_x_timeout: u16, access_x_timeout_mask: M, access_x_timeout_values: N, access_x_timeout_options_mask: O, access_x_timeout_options_values: P, per_key_repeat: &'input [u8; 32]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, D: Into, E: Into, F: Into, G: Into, H: Into, I: Into, J: Into, K: Into, L: Into, M: Into, N: Into, O: Into, P: Into, { let affect_internal_real_mods: u8 = affect_internal_real_mods.into(); let internal_real_mods: u8 = internal_real_mods.into(); let affect_ignore_lock_real_mods: u8 = affect_ignore_lock_real_mods.into(); let ignore_lock_real_mods: u8 = ignore_lock_real_mods.into(); let affect_internal_virtual_mods: u16 = affect_internal_virtual_mods.into(); let internal_virtual_mods: u16 = internal_virtual_mods.into(); let affect_ignore_lock_virtual_mods: u16 = affect_ignore_lock_virtual_mods.into(); let ignore_lock_virtual_mods: u16 = ignore_lock_virtual_mods.into(); let access_x_options: u16 = access_x_options.into(); let affect_enabled_controls: u32 = affect_enabled_controls.into(); let enabled_controls: u32 = enabled_controls.into(); let change_controls: u32 = change_controls.into(); let access_x_timeout_mask: u32 = access_x_timeout_mask.into(); let access_x_timeout_values: u32 = access_x_timeout_values.into(); let access_x_timeout_options_mask: u16 = access_x_timeout_options_mask.into(); let access_x_timeout_options_values: u16 = access_x_timeout_options_values.into(); let request0 = SetControlsRequest { device_spec, affect_internal_real_mods, internal_real_mods, affect_ignore_lock_real_mods, ignore_lock_real_mods, affect_internal_virtual_mods, internal_virtual_mods, affect_ignore_lock_virtual_mods, ignore_lock_virtual_mods, mouse_keys_dflt_btn, groups_wrap, access_x_options, affect_enabled_controls, enabled_controls, change_controls, repeat_delay, repeat_interval, slow_keys_delay, debounce_delay, mouse_keys_delay, mouse_keys_interval, mouse_keys_time_to_max, mouse_keys_max_speed, mouse_keys_curve, access_x_timeout, access_x_timeout_mask, access_x_timeout_values, access_x_timeout_options_mask, access_x_timeout_options_values, per_key_repeat: Cow::Borrowed(per_key_repeat), }; request0.send(conn) } /// Opcode for the GetMap request pub const GET_MAP_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetMapRequest { pub device_spec: DeviceSpec, pub full: u16, pub partial: u16, pub first_type: u8, pub n_types: u8, pub first_key_sym: xproto::Keycode, pub n_key_syms: u8, pub first_key_action: xproto::Keycode, pub n_key_actions: u8, pub first_key_behavior: xproto::Keycode, pub n_key_behaviors: u8, pub virtual_mods: u16, pub first_key_explicit: xproto::Keycode, pub n_key_explicit: u8, pub first_mod_map_key: xproto::Keycode, pub n_mod_map_keys: u8, pub first_v_mod_map_key: xproto::Keycode, pub n_v_mod_map_keys: u8, } impl GetMapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let full_bytes = self.full.serialize(); let partial_bytes = self.partial.serialize(); let first_type_bytes = self.first_type.serialize(); let n_types_bytes = self.n_types.serialize(); let first_key_sym_bytes = self.first_key_sym.serialize(); let n_key_syms_bytes = self.n_key_syms.serialize(); let first_key_action_bytes = self.first_key_action.serialize(); let n_key_actions_bytes = self.n_key_actions.serialize(); let first_key_behavior_bytes = self.first_key_behavior.serialize(); let n_key_behaviors_bytes = self.n_key_behaviors.serialize(); let virtual_mods_bytes = self.virtual_mods.serialize(); let first_key_explicit_bytes = self.first_key_explicit.serialize(); let n_key_explicit_bytes = self.n_key_explicit.serialize(); let first_mod_map_key_bytes = self.first_mod_map_key.serialize(); let n_mod_map_keys_bytes = self.n_mod_map_keys.serialize(); let first_v_mod_map_key_bytes = self.first_v_mod_map_key.serialize(); let n_v_mod_map_keys_bytes = self.n_v_mod_map_keys.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_MAP_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], full_bytes[0], full_bytes[1], partial_bytes[0], partial_bytes[1], first_type_bytes[0], n_types_bytes[0], first_key_sym_bytes[0], n_key_syms_bytes[0], first_key_action_bytes[0], n_key_actions_bytes[0], first_key_behavior_bytes[0], n_key_behaviors_bytes[0], virtual_mods_bytes[0], virtual_mods_bytes[1], first_key_explicit_bytes[0], n_key_explicit_bytes[0], first_mod_map_key_bytes[0], n_mod_map_keys_bytes[0], first_v_mod_map_key_bytes[0], n_v_mod_map_keys_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_MAP_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (full, remaining) = u16::try_parse(remaining)?; let (partial, remaining) = u16::try_parse(remaining)?; let (first_type, remaining) = u8::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (first_key_sym, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_syms, remaining) = u8::try_parse(remaining)?; let (first_key_action, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_actions, remaining) = u8::try_parse(remaining)?; let (first_key_behavior, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_behaviors, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (first_key_explicit, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_explicit, remaining) = u8::try_parse(remaining)?; let (first_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (first_v_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetMapRequest { device_spec, full, partial, first_type, n_types, first_key_sym, n_key_syms, first_key_action, n_key_actions, first_key_behavior, n_key_behaviors, virtual_mods, first_key_explicit, n_key_explicit, first_mod_map_key, n_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, }) } } impl Request for GetMapRequest { type Reply = GetMapReply; } pub fn get_map(conn: &Conn, device_spec: DeviceSpec, full: A, partial: B, first_type: u8, n_types: u8, first_key_sym: xproto::Keycode, n_key_syms: u8, first_key_action: xproto::Keycode, n_key_actions: u8, first_key_behavior: xproto::Keycode, n_key_behaviors: u8, virtual_mods: C, first_key_explicit: xproto::Keycode, n_key_explicit: u8, first_mod_map_key: xproto::Keycode, n_mod_map_keys: u8, first_v_mod_map_key: xproto::Keycode, n_v_mod_map_keys: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, { let full: u16 = full.into(); let partial: u16 = partial.into(); let virtual_mods: u16 = virtual_mods.into(); let request0 = GetMapRequest { device_spec, full, partial, first_type, n_types, first_key_sym, n_key_syms, first_key_action, n_key_actions, first_key_behavior, n_key_behaviors, virtual_mods, first_key_explicit, n_key_explicit, first_mod_map_key, n_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, }; request0.send(conn) } #[derive(Debug, Clone)] pub struct GetMapMapBitcase3 { pub acts_rtrn_count: Vec, pub acts_rtrn_acts: Vec, } impl GetMapMapBitcase3 { pub fn try_parse(remaining: &[u8], n_key_actions: u8, total_actions: u16) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (acts_rtrn_count, remaining) = crate::x11_utils::parse_u8_list(remaining, n_key_actions.try_to_usize()?)?; let acts_rtrn_count = acts_rtrn_count.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (acts_rtrn_acts, remaining) = crate::x11_utils::parse_list::(remaining, total_actions.try_to_usize()?)?; let result = GetMapMapBitcase3 { acts_rtrn_count, acts_rtrn_acts }; Ok((result, remaining)) } } #[derive(Debug, Clone, Default)] pub struct GetMapMap { pub types_rtrn: Option>, pub syms_rtrn: Option>, pub bitcase3: Option, pub behaviors_rtrn: Option>, pub vmods_rtrn: Option>, pub explicit_rtrn: Option>, pub modmap_rtrn: Option>, pub vmodmap_rtrn: Option>, } impl GetMapMap { fn try_parse(value: &[u8], present: u16, n_types: u8, n_key_syms: u8, n_key_actions: u8, total_actions: u16, total_key_behaviors: u8, virtual_mods: u16, total_key_explicit: u8, total_mod_map_keys: u8, total_v_mod_map_keys: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(present); let mut outer_remaining = value; let types_rtrn = if switch_expr & u32::from(MapPart::KEY_TYPES) != 0 { let remaining = outer_remaining; let (types_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, n_types.try_to_usize()?)?; outer_remaining = remaining; Some(types_rtrn) } else { None }; let syms_rtrn = if switch_expr & u32::from(MapPart::KEY_SYMS) != 0 { let remaining = outer_remaining; let (syms_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, n_key_syms.try_to_usize()?)?; outer_remaining = remaining; Some(syms_rtrn) } else { None }; let bitcase3 = if switch_expr & u32::from(MapPart::KEY_ACTIONS) != 0 { let (bitcase3, new_remaining) = GetMapMapBitcase3::try_parse(outer_remaining, n_key_actions, total_actions)?; outer_remaining = new_remaining; Some(bitcase3) } else { None }; let behaviors_rtrn = if switch_expr & u32::from(MapPart::KEY_BEHAVIORS) != 0 { let remaining = outer_remaining; let (behaviors_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_key_behaviors.try_to_usize()?)?; outer_remaining = remaining; Some(behaviors_rtrn) } else { None }; let vmods_rtrn = if switch_expr & u32::from(MapPart::VIRTUAL_MODS) != 0 { let remaining = outer_remaining; let value = remaining; let (vmods_rtrn, remaining) = crate::x11_utils::parse_u8_list(remaining, virtual_mods.count_ones().try_to_usize()?)?; let vmods_rtrn = vmods_rtrn.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; Some(vmods_rtrn) } else { None }; let explicit_rtrn = if switch_expr & u32::from(MapPart::EXPLICIT_COMPONENTS) != 0 { let remaining = outer_remaining; let value = remaining; let (explicit_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_key_explicit.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; Some(explicit_rtrn) } else { None }; let modmap_rtrn = if switch_expr & u32::from(MapPart::MODIFIER_MAP) != 0 { let remaining = outer_remaining; let value = remaining; let (modmap_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_mod_map_keys.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; Some(modmap_rtrn) } else { None }; let vmodmap_rtrn = if switch_expr & u32::from(MapPart::VIRTUAL_MOD_MAP) != 0 { let remaining = outer_remaining; let (vmodmap_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_v_mod_map_keys.try_to_usize()?)?; outer_remaining = remaining; Some(vmodmap_rtrn) } else { None }; let result = GetMapMap { types_rtrn, syms_rtrn, bitcase3, behaviors_rtrn, vmods_rtrn, explicit_rtrn, modmap_rtrn, vmodmap_rtrn }; Ok((result, outer_remaining)) } } #[derive(Debug, Clone)] pub struct GetMapReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub min_key_code: xproto::Keycode, pub max_key_code: xproto::Keycode, pub first_type: u8, pub n_types: u8, pub total_types: u8, pub first_key_sym: xproto::Keycode, pub total_syms: u16, pub n_key_syms: u8, pub first_key_action: xproto::Keycode, pub total_actions: u16, pub n_key_actions: u8, pub first_key_behavior: xproto::Keycode, pub n_key_behaviors: u8, pub total_key_behaviors: u8, pub first_key_explicit: xproto::Keycode, pub n_key_explicit: u8, pub total_key_explicit: u8, pub first_mod_map_key: xproto::Keycode, pub n_mod_map_keys: u8, pub total_mod_map_keys: u8, pub first_v_mod_map_key: xproto::Keycode, pub n_v_mod_map_keys: u8, pub total_v_mod_map_keys: u8, pub virtual_mods: u16, pub map: GetMapMap, } impl TryParse for GetMapReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (present, remaining) = u16::try_parse(remaining)?; let (first_type, remaining) = u8::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (total_types, remaining) = u8::try_parse(remaining)?; let (first_key_sym, remaining) = xproto::Keycode::try_parse(remaining)?; let (total_syms, remaining) = u16::try_parse(remaining)?; let (n_key_syms, remaining) = u8::try_parse(remaining)?; let (first_key_action, remaining) = xproto::Keycode::try_parse(remaining)?; let (total_actions, remaining) = u16::try_parse(remaining)?; let (n_key_actions, remaining) = u8::try_parse(remaining)?; let (first_key_behavior, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_behaviors, remaining) = u8::try_parse(remaining)?; let (total_key_behaviors, remaining) = u8::try_parse(remaining)?; let (first_key_explicit, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_explicit, remaining) = u8::try_parse(remaining)?; let (total_key_explicit, remaining) = u8::try_parse(remaining)?; let (first_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (total_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (first_v_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (total_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (map, remaining) = GetMapMap::try_parse(remaining, present, n_types, n_key_syms, n_key_actions, total_actions, total_key_behaviors, virtual_mods, total_key_explicit, total_mod_map_keys, total_v_mod_map_keys)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetMapReply { device_id, sequence, length, min_key_code, max_key_code, first_type, n_types, total_types, first_key_sym, total_syms, n_key_syms, first_key_action, total_actions, n_key_actions, first_key_behavior, n_key_behaviors, total_key_behaviors, first_key_explicit, n_key_explicit, total_key_explicit, first_mod_map_key, n_mod_map_keys, total_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, total_v_mod_map_keys, virtual_mods, map }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Debug, Clone)] pub struct SetMapAuxBitcase3 { pub actions_count: Vec, pub actions: Vec, } impl SetMapAuxBitcase3 { pub fn try_parse(remaining: &[u8], n_key_actions: u8, total_actions: u16) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (actions_count, remaining) = crate::x11_utils::parse_u8_list(remaining, n_key_actions.try_to_usize()?)?; let actions_count = actions_count.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (actions, remaining) = crate::x11_utils::parse_list::(remaining, total_actions.try_to_usize()?)?; let result = SetMapAuxBitcase3 { actions_count, actions }; Ok((result, remaining)) } } impl SetMapAuxBitcase3 { #[allow(dead_code)] fn serialize(&self, n_key_actions: u8, total_actions: u16) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, n_key_actions, total_actions); result } fn serialize_into(&self, bytes: &mut Vec, n_key_actions: u8, total_actions: u16) { assert_eq!(self.actions_count.len(), usize::try_from(n_key_actions).unwrap(), "`actions_count` has an incorrect length"); bytes.extend_from_slice(&self.actions_count); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); assert_eq!(self.actions.len(), usize::try_from(total_actions).unwrap(), "`actions` has an incorrect length"); self.actions.serialize_into(bytes); } } /// Auxiliary and optional information for the `set_map` function #[derive(Debug, Clone, Default)] pub struct SetMapAux { pub types: Option>, pub syms: Option>, pub bitcase3: Option, pub behaviors: Option>, pub vmods: Option>, pub explicit: Option>, pub modmap: Option>, pub vmodmap: Option>, } impl SetMapAux { fn try_parse(value: &[u8], present: u16, n_types: u8, n_key_syms: u8, n_key_actions: u8, total_actions: u16, total_key_behaviors: u8, virtual_mods: u16, total_key_explicit: u8, total_mod_map_keys: u8, total_v_mod_map_keys: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(present); let mut outer_remaining = value; let types = if switch_expr & u32::from(MapPart::KEY_TYPES) != 0 { let remaining = outer_remaining; let (types, remaining) = crate::x11_utils::parse_list::(remaining, n_types.try_to_usize()?)?; outer_remaining = remaining; Some(types) } else { None }; let syms = if switch_expr & u32::from(MapPart::KEY_SYMS) != 0 { let remaining = outer_remaining; let (syms, remaining) = crate::x11_utils::parse_list::(remaining, n_key_syms.try_to_usize()?)?; outer_remaining = remaining; Some(syms) } else { None }; let bitcase3 = if switch_expr & u32::from(MapPart::KEY_ACTIONS) != 0 { let (bitcase3, new_remaining) = SetMapAuxBitcase3::try_parse(outer_remaining, n_key_actions, total_actions)?; outer_remaining = new_remaining; Some(bitcase3) } else { None }; let behaviors = if switch_expr & u32::from(MapPart::KEY_BEHAVIORS) != 0 { let remaining = outer_remaining; let (behaviors, remaining) = crate::x11_utils::parse_list::(remaining, total_key_behaviors.try_to_usize()?)?; outer_remaining = remaining; Some(behaviors) } else { None }; let vmods = if switch_expr & u32::from(MapPart::VIRTUAL_MODS) != 0 { let remaining = outer_remaining; let value = remaining; let (vmods, remaining) = crate::x11_utils::parse_u8_list(remaining, virtual_mods.count_ones().try_to_usize()?)?; let vmods = vmods.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; Some(vmods) } else { None }; let explicit = if switch_expr & u32::from(MapPart::EXPLICIT_COMPONENTS) != 0 { let remaining = outer_remaining; let (explicit, remaining) = crate::x11_utils::parse_list::(remaining, total_key_explicit.try_to_usize()?)?; outer_remaining = remaining; Some(explicit) } else { None }; let modmap = if switch_expr & u32::from(MapPart::MODIFIER_MAP) != 0 { let remaining = outer_remaining; let (modmap, remaining) = crate::x11_utils::parse_list::(remaining, total_mod_map_keys.try_to_usize()?)?; outer_remaining = remaining; Some(modmap) } else { None }; let vmodmap = if switch_expr & u32::from(MapPart::VIRTUAL_MOD_MAP) != 0 { let remaining = outer_remaining; let (vmodmap, remaining) = crate::x11_utils::parse_list::(remaining, total_v_mod_map_keys.try_to_usize()?)?; outer_remaining = remaining; Some(vmodmap) } else { None }; let result = SetMapAux { types, syms, bitcase3, behaviors, vmods, explicit, modmap, vmodmap }; Ok((result, outer_remaining)) } } impl SetMapAux { #[allow(dead_code)] fn serialize(&self, present: u16, n_types: u8, n_key_syms: u8, n_key_actions: u8, total_actions: u16, total_key_behaviors: u8, virtual_mods: u16, total_key_explicit: u8, total_mod_map_keys: u8, total_v_mod_map_keys: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, present, n_types, n_key_syms, n_key_actions, total_actions, total_key_behaviors, virtual_mods, total_key_explicit, total_mod_map_keys, total_v_mod_map_keys); result } fn serialize_into(&self, bytes: &mut Vec, present: u16, n_types: u8, n_key_syms: u8, n_key_actions: u8, total_actions: u16, total_key_behaviors: u8, virtual_mods: u16, total_key_explicit: u8, total_mod_map_keys: u8, total_v_mod_map_keys: u8) { assert_eq!(self.switch_expr(), u32::from(present), "switch `values` has an inconsistent discriminant"); if let Some(ref types) = self.types { assert_eq!(types.len(), usize::try_from(n_types).unwrap(), "`types` has an incorrect length"); types.serialize_into(bytes); } if let Some(ref syms) = self.syms { assert_eq!(syms.len(), usize::try_from(n_key_syms).unwrap(), "`syms` has an incorrect length"); syms.serialize_into(bytes); } if let Some(ref bitcase3) = self.bitcase3 { bitcase3.serialize_into(bytes, n_key_actions, total_actions); } if let Some(ref behaviors) = self.behaviors { assert_eq!(behaviors.len(), usize::try_from(total_key_behaviors).unwrap(), "`behaviors` has an incorrect length"); behaviors.serialize_into(bytes); } if let Some(ref vmods) = self.vmods { assert_eq!(vmods.len(), usize::try_from(virtual_mods.count_ones()).unwrap(), "`vmods` has an incorrect length"); bytes.extend_from_slice(&vmods); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } if let Some(ref explicit) = self.explicit { assert_eq!(explicit.len(), usize::try_from(total_key_explicit).unwrap(), "`explicit` has an incorrect length"); explicit.serialize_into(bytes); } if let Some(ref modmap) = self.modmap { assert_eq!(modmap.len(), usize::try_from(total_mod_map_keys).unwrap(), "`modmap` has an incorrect length"); modmap.serialize_into(bytes); } if let Some(ref vmodmap) = self.vmodmap { assert_eq!(vmodmap.len(), usize::try_from(total_v_mod_map_keys).unwrap(), "`vmodmap` has an incorrect length"); vmodmap.serialize_into(bytes); } } } impl SetMapAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.types.is_some() { expr_value |= u32::from(MapPart::KEY_TYPES); } if self.syms.is_some() { expr_value |= u32::from(MapPart::KEY_SYMS); } if self.bitcase3.is_some() { expr_value |= u32::from(MapPart::KEY_ACTIONS); } if self.behaviors.is_some() { expr_value |= u32::from(MapPart::KEY_BEHAVIORS); } if self.vmods.is_some() { expr_value |= u32::from(MapPart::VIRTUAL_MODS); } if self.explicit.is_some() { expr_value |= u32::from(MapPart::EXPLICIT_COMPONENTS); } if self.modmap.is_some() { expr_value |= u32::from(MapPart::MODIFIER_MAP); } if self.vmodmap.is_some() { expr_value |= u32::from(MapPart::VIRTUAL_MOD_MAP); } expr_value } } impl SetMapAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `types` field of this structure. pub fn types(mut self, value: I) -> Self where I: Into>> { self.types = value.into(); self } /// Set the `syms` field of this structure. pub fn syms(mut self, value: I) -> Self where I: Into>> { self.syms = value.into(); self } /// Set the `bitcase3` field of this structure. pub fn bitcase3(mut self, value: I) -> Self where I: Into> { self.bitcase3 = value.into(); self } /// Set the `behaviors` field of this structure. pub fn behaviors(mut self, value: I) -> Self where I: Into>> { self.behaviors = value.into(); self } /// Set the `vmods` field of this structure. pub fn vmods(mut self, value: I) -> Self where I: Into>> { self.vmods = value.into(); self } /// Set the `explicit` field of this structure. pub fn explicit(mut self, value: I) -> Self where I: Into>> { self.explicit = value.into(); self } /// Set the `modmap` field of this structure. pub fn modmap(mut self, value: I) -> Self where I: Into>> { self.modmap = value.into(); self } /// Set the `vmodmap` field of this structure. pub fn vmodmap(mut self, value: I) -> Self where I: Into>> { self.vmodmap = value.into(); self } } /// Opcode for the SetMap request pub const SET_MAP_REQUEST: u8 = 9; #[derive(Debug, Clone)] pub struct SetMapRequest<'input> { pub device_spec: DeviceSpec, pub flags: u16, pub min_key_code: xproto::Keycode, pub max_key_code: xproto::Keycode, pub first_type: u8, pub n_types: u8, pub first_key_sym: xproto::Keycode, pub n_key_syms: u8, pub total_syms: u16, pub first_key_action: xproto::Keycode, pub n_key_actions: u8, pub total_actions: u16, pub first_key_behavior: xproto::Keycode, pub n_key_behaviors: u8, pub total_key_behaviors: u8, pub first_key_explicit: xproto::Keycode, pub n_key_explicit: u8, pub total_key_explicit: u8, pub first_mod_map_key: xproto::Keycode, pub n_mod_map_keys: u8, pub total_mod_map_keys: u8, pub first_v_mod_map_key: xproto::Keycode, pub n_v_mod_map_keys: u8, pub total_v_mod_map_keys: u8, pub virtual_mods: u16, pub values: Cow<'input, SetMapAux>, } impl<'input> SetMapRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let present = u16::try_from(self.values.switch_expr()).unwrap(); let present_bytes = present.serialize(); let flags_bytes = self.flags.serialize(); let min_key_code_bytes = self.min_key_code.serialize(); let max_key_code_bytes = self.max_key_code.serialize(); let first_type_bytes = self.first_type.serialize(); let n_types_bytes = self.n_types.serialize(); let first_key_sym_bytes = self.first_key_sym.serialize(); let n_key_syms_bytes = self.n_key_syms.serialize(); let total_syms_bytes = self.total_syms.serialize(); let first_key_action_bytes = self.first_key_action.serialize(); let n_key_actions_bytes = self.n_key_actions.serialize(); let total_actions_bytes = self.total_actions.serialize(); let first_key_behavior_bytes = self.first_key_behavior.serialize(); let n_key_behaviors_bytes = self.n_key_behaviors.serialize(); let total_key_behaviors_bytes = self.total_key_behaviors.serialize(); let first_key_explicit_bytes = self.first_key_explicit.serialize(); let n_key_explicit_bytes = self.n_key_explicit.serialize(); let total_key_explicit_bytes = self.total_key_explicit.serialize(); let first_mod_map_key_bytes = self.first_mod_map_key.serialize(); let n_mod_map_keys_bytes = self.n_mod_map_keys.serialize(); let total_mod_map_keys_bytes = self.total_mod_map_keys.serialize(); let first_v_mod_map_key_bytes = self.first_v_mod_map_key.serialize(); let n_v_mod_map_keys_bytes = self.n_v_mod_map_keys.serialize(); let total_v_mod_map_keys_bytes = self.total_v_mod_map_keys.serialize(); let virtual_mods_bytes = self.virtual_mods.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_MAP_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], present_bytes[0], present_bytes[1], flags_bytes[0], flags_bytes[1], min_key_code_bytes[0], max_key_code_bytes[0], first_type_bytes[0], n_types_bytes[0], first_key_sym_bytes[0], n_key_syms_bytes[0], total_syms_bytes[0], total_syms_bytes[1], first_key_action_bytes[0], n_key_actions_bytes[0], total_actions_bytes[0], total_actions_bytes[1], first_key_behavior_bytes[0], n_key_behaviors_bytes[0], total_key_behaviors_bytes[0], first_key_explicit_bytes[0], n_key_explicit_bytes[0], total_key_explicit_bytes[0], first_mod_map_key_bytes[0], n_mod_map_keys_bytes[0], total_mod_map_keys_bytes[0], first_v_mod_map_key_bytes[0], n_v_mod_map_keys_bytes[0], total_v_mod_map_keys_bytes[0], virtual_mods_bytes[0], virtual_mods_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let values_bytes = self.values.serialize(present, self.n_types, self.n_key_syms, self.n_key_actions, self.total_actions, self.total_key_behaviors, self.virtual_mods, self.total_key_explicit, self.total_mod_map_keys, self.total_v_mod_map_keys); let length_so_far = length_so_far + values_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), values_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_MAP_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (present, remaining) = u16::try_parse(remaining)?; let (flags, remaining) = u16::try_parse(remaining)?; let (min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (first_type, remaining) = u8::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (first_key_sym, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_syms, remaining) = u8::try_parse(remaining)?; let (total_syms, remaining) = u16::try_parse(remaining)?; let (first_key_action, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_actions, remaining) = u8::try_parse(remaining)?; let (total_actions, remaining) = u16::try_parse(remaining)?; let (first_key_behavior, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_behaviors, remaining) = u8::try_parse(remaining)?; let (total_key_behaviors, remaining) = u8::try_parse(remaining)?; let (first_key_explicit, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_explicit, remaining) = u8::try_parse(remaining)?; let (total_key_explicit, remaining) = u8::try_parse(remaining)?; let (first_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (total_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (first_v_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (total_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (values, remaining) = SetMapAux::try_parse(remaining, present, n_types, n_key_syms, n_key_actions, total_actions, total_key_behaviors, virtual_mods, total_key_explicit, total_mod_map_keys, total_v_mod_map_keys)?; let _ = remaining; Ok(SetMapRequest { device_spec, flags, min_key_code, max_key_code, first_type, n_types, first_key_sym, n_key_syms, total_syms, first_key_action, n_key_actions, total_actions, first_key_behavior, n_key_behaviors, total_key_behaviors, first_key_explicit, n_key_explicit, total_key_explicit, first_mod_map_key, n_mod_map_keys, total_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, total_v_mod_map_keys, virtual_mods, values: Cow::Owned(values), }) } /// Clone all borrowed data in this SetMapRequest. pub fn into_owned(self) -> SetMapRequest<'static> { SetMapRequest { device_spec: self.device_spec, flags: self.flags, min_key_code: self.min_key_code, max_key_code: self.max_key_code, first_type: self.first_type, n_types: self.n_types, first_key_sym: self.first_key_sym, n_key_syms: self.n_key_syms, total_syms: self.total_syms, first_key_action: self.first_key_action, n_key_actions: self.n_key_actions, total_actions: self.total_actions, first_key_behavior: self.first_key_behavior, n_key_behaviors: self.n_key_behaviors, total_key_behaviors: self.total_key_behaviors, first_key_explicit: self.first_key_explicit, n_key_explicit: self.n_key_explicit, total_key_explicit: self.total_key_explicit, first_mod_map_key: self.first_mod_map_key, n_mod_map_keys: self.n_mod_map_keys, total_mod_map_keys: self.total_mod_map_keys, first_v_mod_map_key: self.first_v_mod_map_key, n_v_mod_map_keys: self.n_v_mod_map_keys, total_v_mod_map_keys: self.total_v_mod_map_keys, virtual_mods: self.virtual_mods, values: Cow::Owned(self.values.into_owned()), } } } impl<'input> Request for SetMapRequest<'input> { type Reply = (); } pub fn set_map<'c, 'input, Conn, A, B>(conn: &'c Conn, device_spec: DeviceSpec, flags: A, min_key_code: xproto::Keycode, max_key_code: xproto::Keycode, first_type: u8, n_types: u8, first_key_sym: xproto::Keycode, n_key_syms: u8, total_syms: u16, first_key_action: xproto::Keycode, n_key_actions: u8, total_actions: u16, first_key_behavior: xproto::Keycode, n_key_behaviors: u8, total_key_behaviors: u8, first_key_explicit: xproto::Keycode, n_key_explicit: u8, total_key_explicit: u8, first_mod_map_key: xproto::Keycode, n_mod_map_keys: u8, total_mod_map_keys: u8, first_v_mod_map_key: xproto::Keycode, n_v_mod_map_keys: u8, total_v_mod_map_keys: u8, virtual_mods: B, values: &'input SetMapAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let flags: u16 = flags.into(); let virtual_mods: u16 = virtual_mods.into(); let request0 = SetMapRequest { device_spec, flags, min_key_code, max_key_code, first_type, n_types, first_key_sym, n_key_syms, total_syms, first_key_action, n_key_actions, total_actions, first_key_behavior, n_key_behaviors, total_key_behaviors, first_key_explicit, n_key_explicit, total_key_explicit, first_mod_map_key, n_mod_map_keys, total_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, total_v_mod_map_keys, virtual_mods, values: Cow::Borrowed(values), }; request0.send(conn) } /// Opcode for the GetCompatMap request pub const GET_COMPAT_MAP_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetCompatMapRequest { pub device_spec: DeviceSpec, pub groups: u8, pub get_all_si: bool, pub first_si: u16, pub n_si: u16, } impl GetCompatMapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let groups_bytes = self.groups.serialize(); let get_all_si_bytes = self.get_all_si.serialize(); let first_si_bytes = self.first_si.serialize(); let n_si_bytes = self.n_si.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_COMPAT_MAP_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], groups_bytes[0], get_all_si_bytes[0], first_si_bytes[0], first_si_bytes[1], n_si_bytes[0], n_si_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_COMPAT_MAP_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (groups, remaining) = u8::try_parse(remaining)?; let (get_all_si, remaining) = bool::try_parse(remaining)?; let (first_si, remaining) = u16::try_parse(remaining)?; let (n_si, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(GetCompatMapRequest { device_spec, groups, get_all_si, first_si, n_si, }) } } impl Request for GetCompatMapRequest { type Reply = GetCompatMapReply; } pub fn get_compat_map(conn: &Conn, device_spec: DeviceSpec, groups: A, get_all_si: bool, first_si: u16, n_si: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let groups: u8 = groups.into(); let request0 = GetCompatMapRequest { device_spec, groups, get_all_si, first_si, n_si, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetCompatMapReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub groups_rtrn: u8, pub first_si_rtrn: u16, pub n_total_si: u16, pub si_rtrn: Vec, pub group_rtrn: Vec, } impl TryParse for GetCompatMapReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (groups_rtrn, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (first_si_rtrn, remaining) = u16::try_parse(remaining)?; let (n_si_rtrn, remaining) = u16::try_parse(remaining)?; let (n_total_si, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (si_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, n_si_rtrn.try_to_usize()?)?; let (group_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, groups_rtrn.count_ones().try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetCompatMapReply { device_id, sequence, length, groups_rtrn, first_si_rtrn, n_total_si, si_rtrn, group_rtrn }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetCompatMapReply { /// Get the value of the `nSIRtrn` field. /// /// The `nSIRtrn` field is used as the length field of the `si_rtrn` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_si_rtrn(&self) -> u16 { self.si_rtrn.len() .try_into().unwrap() } } /// Opcode for the SetCompatMap request pub const SET_COMPAT_MAP_REQUEST: u8 = 11; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetCompatMapRequest<'input> { pub device_spec: DeviceSpec, pub recompute_actions: bool, pub truncate_si: bool, pub groups: u8, pub first_si: u16, pub si: Cow<'input, [SymInterpret]>, pub group_maps: Cow<'input, [ModDef]>, } impl<'input> SetCompatMapRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let recompute_actions_bytes = self.recompute_actions.serialize(); let truncate_si_bytes = self.truncate_si.serialize(); let groups_bytes = self.groups.serialize(); let first_si_bytes = self.first_si.serialize(); let n_si = u16::try_from(self.si.len()).expect("`si` has too many elements"); let n_si_bytes = n_si.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_COMPAT_MAP_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, recompute_actions_bytes[0], truncate_si_bytes[0], groups_bytes[0], first_si_bytes[0], first_si_bytes[1], n_si_bytes[0], n_si_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let si_bytes = self.si.serialize(); let length_so_far = length_so_far + si_bytes.len(); assert_eq!(self.group_maps.len(), usize::try_from(self.groups.count_ones()).unwrap(), "`group_maps` has an incorrect length"); let group_maps_bytes = self.group_maps.serialize(); let length_so_far = length_so_far + group_maps_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), si_bytes.into(), group_maps_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_COMPAT_MAP_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (recompute_actions, remaining) = bool::try_parse(remaining)?; let (truncate_si, remaining) = bool::try_parse(remaining)?; let (groups, remaining) = u8::try_parse(remaining)?; let (first_si, remaining) = u16::try_parse(remaining)?; let (n_si, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (si, remaining) = crate::x11_utils::parse_list::(remaining, n_si.try_to_usize()?)?; let (group_maps, remaining) = crate::x11_utils::parse_list::(remaining, groups.count_ones().try_to_usize()?)?; let _ = remaining; Ok(SetCompatMapRequest { device_spec, recompute_actions, truncate_si, groups, first_si, si: Cow::Owned(si), group_maps: Cow::Owned(group_maps), }) } /// Clone all borrowed data in this SetCompatMapRequest. pub fn into_owned(self) -> SetCompatMapRequest<'static> { SetCompatMapRequest { device_spec: self.device_spec, recompute_actions: self.recompute_actions, truncate_si: self.truncate_si, groups: self.groups, first_si: self.first_si, si: Cow::Owned(self.si.into_owned()), group_maps: Cow::Owned(self.group_maps.into_owned()), } } } impl<'input> Request for SetCompatMapRequest<'input> { type Reply = (); } pub fn set_compat_map<'c, 'input, Conn, A>(conn: &'c Conn, device_spec: DeviceSpec, recompute_actions: bool, truncate_si: bool, groups: A, first_si: u16, si: &'input [SymInterpret], group_maps: &'input [ModDef]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let groups: u8 = groups.into(); let request0 = SetCompatMapRequest { device_spec, recompute_actions, truncate_si, groups, first_si, si: Cow::Borrowed(si), group_maps: Cow::Borrowed(group_maps), }; request0.send(conn) } /// Opcode for the GetIndicatorState request pub const GET_INDICATOR_STATE_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetIndicatorStateRequest { pub device_spec: DeviceSpec, } impl GetIndicatorStateRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_INDICATOR_STATE_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_INDICATOR_STATE_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetIndicatorStateRequest { device_spec, }) } } impl Request for GetIndicatorStateRequest { type Reply = GetIndicatorStateReply; } pub fn get_indicator_state(conn: &Conn, device_spec: DeviceSpec) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetIndicatorStateRequest { device_spec, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetIndicatorStateReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub state: u32, } impl TryParse for GetIndicatorStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (state, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetIndicatorStateReply { device_id, sequence, length, state }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetIndicatorMap request pub const GET_INDICATOR_MAP_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetIndicatorMapRequest { pub device_spec: DeviceSpec, pub which: u32, } impl GetIndicatorMapRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let which_bytes = self.which.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_INDICATOR_MAP_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, 0, which_bytes[0], which_bytes[1], which_bytes[2], which_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_INDICATOR_MAP_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (which, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetIndicatorMapRequest { device_spec, which, }) } } impl Request for GetIndicatorMapRequest { type Reply = GetIndicatorMapReply; } pub fn get_indicator_map(conn: &Conn, device_spec: DeviceSpec, which: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetIndicatorMapRequest { device_spec, which, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetIndicatorMapReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub which: u32, pub real_indicators: u32, pub n_indicators: u8, pub maps: Vec, } impl TryParse for GetIndicatorMapReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (which, remaining) = u32::try_parse(remaining)?; let (real_indicators, remaining) = u32::try_parse(remaining)?; let (n_indicators, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(15..).ok_or(ParseError::InsufficientData)?; let (maps, remaining) = crate::x11_utils::parse_list::(remaining, which.count_ones().try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetIndicatorMapReply { device_id, sequence, length, which, real_indicators, n_indicators, maps }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetIndicatorMap request pub const SET_INDICATOR_MAP_REQUEST: u8 = 14; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetIndicatorMapRequest<'input> { pub device_spec: DeviceSpec, pub which: u32, pub maps: Cow<'input, [IndicatorMap]>, } impl<'input> SetIndicatorMapRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let which_bytes = self.which.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_INDICATOR_MAP_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, 0, which_bytes[0], which_bytes[1], which_bytes[2], which_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(self.maps.len(), usize::try_from(self.which.count_ones()).unwrap(), "`maps` has an incorrect length"); let maps_bytes = self.maps.serialize(); let length_so_far = length_so_far + maps_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), maps_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_INDICATOR_MAP_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (which, remaining) = u32::try_parse(remaining)?; let (maps, remaining) = crate::x11_utils::parse_list::(remaining, which.count_ones().try_to_usize()?)?; let _ = remaining; Ok(SetIndicatorMapRequest { device_spec, which, maps: Cow::Owned(maps), }) } /// Clone all borrowed data in this SetIndicatorMapRequest. pub fn into_owned(self) -> SetIndicatorMapRequest<'static> { SetIndicatorMapRequest { device_spec: self.device_spec, which: self.which, maps: Cow::Owned(self.maps.into_owned()), } } } impl<'input> Request for SetIndicatorMapRequest<'input> { type Reply = (); } pub fn set_indicator_map<'c, 'input, Conn>(conn: &'c Conn, device_spec: DeviceSpec, which: u32, maps: &'input [IndicatorMap]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetIndicatorMapRequest { device_spec, which, maps: Cow::Borrowed(maps), }; request0.send(conn) } /// Opcode for the GetNamedIndicator request pub const GET_NAMED_INDICATOR_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetNamedIndicatorRequest { pub device_spec: DeviceSpec, pub led_class: LedClass, pub led_id: IDSpec, pub indicator: xproto::Atom, } impl GetNamedIndicatorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let led_class_bytes = LedClassSpec::from(self.led_class).serialize(); let led_id_bytes = self.led_id.serialize(); let indicator_bytes = self.indicator.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_NAMED_INDICATOR_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], led_class_bytes[0], led_class_bytes[1], led_id_bytes[0], led_id_bytes[1], 0, 0, indicator_bytes[0], indicator_bytes[1], indicator_bytes[2], indicator_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_NAMED_INDICATOR_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (led_class, remaining) = LedClassSpec::try_parse(remaining)?; let led_class = led_class.into(); let (led_id, remaining) = IDSpec::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (indicator, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(GetNamedIndicatorRequest { device_spec, led_class, led_id, indicator, }) } } impl Request for GetNamedIndicatorRequest { type Reply = GetNamedIndicatorReply; } pub fn get_named_indicator(conn: &Conn, device_spec: DeviceSpec, led_class: LedClass, led_id: A, indicator: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let led_id: IDSpec = led_id.into(); let request0 = GetNamedIndicatorRequest { device_spec, led_class, led_id, indicator, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetNamedIndicatorReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub indicator: xproto::Atom, pub found: bool, pub on: bool, pub real_indicator: bool, pub ndx: u8, pub map_flags: u8, pub map_which_groups: u8, pub map_groups: u8, pub map_which_mods: u8, pub map_mods: u8, pub map_real_mods: u8, pub map_vmod: u16, pub map_ctrls: u32, pub supported: bool, } impl TryParse for GetNamedIndicatorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (indicator, remaining) = xproto::Atom::try_parse(remaining)?; let (found, remaining) = bool::try_parse(remaining)?; let (on, remaining) = bool::try_parse(remaining)?; let (real_indicator, remaining) = bool::try_parse(remaining)?; let (ndx, remaining) = u8::try_parse(remaining)?; let (map_flags, remaining) = u8::try_parse(remaining)?; let (map_which_groups, remaining) = u8::try_parse(remaining)?; let (map_groups, remaining) = u8::try_parse(remaining)?; let (map_which_mods, remaining) = u8::try_parse(remaining)?; let (map_mods, remaining) = u8::try_parse(remaining)?; let (map_real_mods, remaining) = u8::try_parse(remaining)?; let (map_vmod, remaining) = u16::try_parse(remaining)?; let (map_ctrls, remaining) = u32::try_parse(remaining)?; let (supported, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetNamedIndicatorReply { device_id, sequence, length, indicator, found, on, real_indicator, ndx, map_flags, map_which_groups, map_groups, map_which_mods, map_mods, map_real_mods, map_vmod, map_ctrls, supported }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetNamedIndicator request pub const SET_NAMED_INDICATOR_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetNamedIndicatorRequest { pub device_spec: DeviceSpec, pub led_class: LedClass, pub led_id: IDSpec, pub indicator: xproto::Atom, pub set_state: bool, pub on: bool, pub set_map: bool, pub create_map: bool, pub map_flags: u8, pub map_which_groups: u8, pub map_groups: u8, pub map_which_mods: u8, pub map_real_mods: u8, pub map_vmods: u16, pub map_ctrls: u32, } impl SetNamedIndicatorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let led_class_bytes = LedClassSpec::from(self.led_class).serialize(); let led_id_bytes = self.led_id.serialize(); let indicator_bytes = self.indicator.serialize(); let set_state_bytes = self.set_state.serialize(); let on_bytes = self.on.serialize(); let set_map_bytes = self.set_map.serialize(); let create_map_bytes = self.create_map.serialize(); let map_flags_bytes = self.map_flags.serialize(); let map_which_groups_bytes = self.map_which_groups.serialize(); let map_groups_bytes = self.map_groups.serialize(); let map_which_mods_bytes = self.map_which_mods.serialize(); let map_real_mods_bytes = self.map_real_mods.serialize(); let map_vmods_bytes = self.map_vmods.serialize(); let map_ctrls_bytes = self.map_ctrls.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_NAMED_INDICATOR_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], led_class_bytes[0], led_class_bytes[1], led_id_bytes[0], led_id_bytes[1], 0, 0, indicator_bytes[0], indicator_bytes[1], indicator_bytes[2], indicator_bytes[3], set_state_bytes[0], on_bytes[0], set_map_bytes[0], create_map_bytes[0], 0, map_flags_bytes[0], map_which_groups_bytes[0], map_groups_bytes[0], map_which_mods_bytes[0], map_real_mods_bytes[0], map_vmods_bytes[0], map_vmods_bytes[1], map_ctrls_bytes[0], map_ctrls_bytes[1], map_ctrls_bytes[2], map_ctrls_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_NAMED_INDICATOR_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (led_class, remaining) = LedClassSpec::try_parse(remaining)?; let led_class = led_class.into(); let (led_id, remaining) = IDSpec::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (indicator, remaining) = xproto::Atom::try_parse(remaining)?; let (set_state, remaining) = bool::try_parse(remaining)?; let (on, remaining) = bool::try_parse(remaining)?; let (set_map, remaining) = bool::try_parse(remaining)?; let (create_map, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (map_flags, remaining) = u8::try_parse(remaining)?; let (map_which_groups, remaining) = u8::try_parse(remaining)?; let (map_groups, remaining) = u8::try_parse(remaining)?; let (map_which_mods, remaining) = u8::try_parse(remaining)?; let (map_real_mods, remaining) = u8::try_parse(remaining)?; let (map_vmods, remaining) = u16::try_parse(remaining)?; let (map_ctrls, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(SetNamedIndicatorRequest { device_spec, led_class, led_id, indicator, set_state, on, set_map, create_map, map_flags, map_which_groups, map_groups, map_which_mods, map_real_mods, map_vmods, map_ctrls, }) } } impl Request for SetNamedIndicatorRequest { type Reply = (); } pub fn set_named_indicator(conn: &Conn, device_spec: DeviceSpec, led_class: LedClass, led_id: A, indicator: xproto::Atom, set_state: bool, on: bool, set_map: bool, create_map: bool, map_flags: B, map_which_groups: C, map_groups: D, map_which_mods: E, map_real_mods: F, map_vmods: G, map_ctrls: H) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, D: Into, E: Into, F: Into, G: Into, H: Into, { let led_id: IDSpec = led_id.into(); let map_flags: u8 = map_flags.into(); let map_which_groups: u8 = map_which_groups.into(); let map_groups: u8 = map_groups.into(); let map_which_mods: u8 = map_which_mods.into(); let map_real_mods: u8 = map_real_mods.into(); let map_vmods: u16 = map_vmods.into(); let map_ctrls: u32 = map_ctrls.into(); let request0 = SetNamedIndicatorRequest { device_spec, led_class, led_id, indicator, set_state, on, set_map, create_map, map_flags, map_which_groups, map_groups, map_which_mods, map_real_mods, map_vmods, map_ctrls, }; request0.send(conn) } /// Opcode for the GetNames request pub const GET_NAMES_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetNamesRequest { pub device_spec: DeviceSpec, pub which: u32, } impl GetNamesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let which_bytes = self.which.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_NAMES_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, 0, which_bytes[0], which_bytes[1], which_bytes[2], which_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_NAMES_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (which, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(GetNamesRequest { device_spec, which, }) } } impl Request for GetNamesRequest { type Reply = GetNamesReply; } pub fn get_names(conn: &Conn, device_spec: DeviceSpec, which: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let which: u32 = which.into(); let request0 = GetNamesRequest { device_spec, which, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetNamesValueListBitcase8 { pub n_levels_per_type: Vec, pub kt_level_names: Vec, } impl GetNamesValueListBitcase8 { pub fn try_parse(remaining: &[u8], n_types: u8) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (n_levels_per_type, remaining) = crate::x11_utils::parse_u8_list(remaining, n_types.try_to_usize()?)?; let n_levels_per_type = n_levels_per_type.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (kt_level_names, remaining) = crate::x11_utils::parse_list::(remaining, n_levels_per_type.iter().try_fold(0u32, |acc, x| acc.checked_add(u32::from(*x)).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = GetNamesValueListBitcase8 { n_levels_per_type, kt_level_names }; Ok((result, remaining)) } } #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct GetNamesValueList { pub keycodes_name: Option, pub geometry_name: Option, pub symbols_name: Option, pub phys_symbols_name: Option, pub types_name: Option, pub compat_name: Option, pub type_names: Option>, pub bitcase8: Option, pub indicator_names: Option>, pub virtual_mod_names: Option>, pub groups: Option>, pub key_names: Option>, pub key_aliases: Option>, pub radio_group_names: Option>, } impl GetNamesValueList { fn try_parse(value: &[u8], which: u32, n_types: u8, indicators: u32, virtual_mods: u16, group_names: u8, n_keys: u8, n_key_aliases: u8, n_radio_groups: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = which; let mut outer_remaining = value; let keycodes_name = if switch_expr & u32::from(NameDetail::KEYCODES) != 0 { let remaining = outer_remaining; let (keycodes_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(keycodes_name) } else { None }; let geometry_name = if switch_expr & u32::from(NameDetail::GEOMETRY) != 0 { let remaining = outer_remaining; let (geometry_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(geometry_name) } else { None }; let symbols_name = if switch_expr & u32::from(NameDetail::SYMBOLS) != 0 { let remaining = outer_remaining; let (symbols_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(symbols_name) } else { None }; let phys_symbols_name = if switch_expr & u32::from(NameDetail::PHYS_SYMBOLS) != 0 { let remaining = outer_remaining; let (phys_symbols_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(phys_symbols_name) } else { None }; let types_name = if switch_expr & u32::from(NameDetail::TYPES) != 0 { let remaining = outer_remaining; let (types_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(types_name) } else { None }; let compat_name = if switch_expr & u32::from(NameDetail::COMPAT) != 0 { let remaining = outer_remaining; let (compat_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(compat_name) } else { None }; let type_names = if switch_expr & u32::from(NameDetail::KEY_TYPE_NAMES) != 0 { let remaining = outer_remaining; let (type_names, remaining) = crate::x11_utils::parse_list::(remaining, n_types.try_to_usize()?)?; outer_remaining = remaining; Some(type_names) } else { None }; let bitcase8 = if switch_expr & u32::from(NameDetail::KT_LEVEL_NAMES) != 0 { let (bitcase8, new_remaining) = GetNamesValueListBitcase8::try_parse(outer_remaining, n_types)?; outer_remaining = new_remaining; Some(bitcase8) } else { None }; let indicator_names = if switch_expr & u32::from(NameDetail::INDICATOR_NAMES) != 0 { let remaining = outer_remaining; let (indicator_names, remaining) = crate::x11_utils::parse_list::(remaining, indicators.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(indicator_names) } else { None }; let virtual_mod_names = if switch_expr & u32::from(NameDetail::VIRTUAL_MOD_NAMES) != 0 { let remaining = outer_remaining; let (virtual_mod_names, remaining) = crate::x11_utils::parse_list::(remaining, virtual_mods.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(virtual_mod_names) } else { None }; let groups = if switch_expr & u32::from(NameDetail::GROUP_NAMES) != 0 { let remaining = outer_remaining; let (groups, remaining) = crate::x11_utils::parse_list::(remaining, group_names.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(groups) } else { None }; let key_names = if switch_expr & u32::from(NameDetail::KEY_NAMES) != 0 { let remaining = outer_remaining; let (key_names, remaining) = crate::x11_utils::parse_list::(remaining, n_keys.try_to_usize()?)?; outer_remaining = remaining; Some(key_names) } else { None }; let key_aliases = if switch_expr & u32::from(NameDetail::KEY_ALIASES) != 0 { let remaining = outer_remaining; let (key_aliases, remaining) = crate::x11_utils::parse_list::(remaining, n_key_aliases.try_to_usize()?)?; outer_remaining = remaining; Some(key_aliases) } else { None }; let radio_group_names = if switch_expr & u32::from(NameDetail::RG_NAMES) != 0 { let remaining = outer_remaining; let (radio_group_names, remaining) = crate::x11_utils::parse_list::(remaining, n_radio_groups.try_to_usize()?)?; outer_remaining = remaining; Some(radio_group_names) } else { None }; let result = GetNamesValueList { keycodes_name, geometry_name, symbols_name, phys_symbols_name, types_name, compat_name, type_names, bitcase8, indicator_names, virtual_mod_names, groups, key_names, key_aliases, radio_group_names }; Ok((result, outer_remaining)) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetNamesReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub min_key_code: xproto::Keycode, pub max_key_code: xproto::Keycode, pub n_types: u8, pub group_names: u8, pub virtual_mods: u16, pub first_key: xproto::Keycode, pub n_keys: u8, pub indicators: u32, pub n_radio_groups: u8, pub n_key_aliases: u8, pub n_kt_levels: u16, pub value_list: GetNamesValueList, } impl TryParse for GetNamesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (which, remaining) = u32::try_parse(remaining)?; let (min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (group_names, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (first_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; let (indicators, remaining) = u32::try_parse(remaining)?; let (n_radio_groups, remaining) = u8::try_parse(remaining)?; let (n_key_aliases, remaining) = u8::try_parse(remaining)?; let (n_kt_levels, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (value_list, remaining) = GetNamesValueList::try_parse(remaining, which, n_types, indicators, virtual_mods, group_names, n_keys, n_key_aliases, n_radio_groups)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetNamesReply { device_id, sequence, length, min_key_code, max_key_code, n_types, group_names, virtual_mods, first_key, n_keys, indicators, n_radio_groups, n_key_aliases, n_kt_levels, value_list }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetNamesAuxBitcase8 { pub n_levels_per_type: Vec, pub kt_level_names: Vec, } impl SetNamesAuxBitcase8 { pub fn try_parse(remaining: &[u8], n_types: u8) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (n_levels_per_type, remaining) = crate::x11_utils::parse_u8_list(remaining, n_types.try_to_usize()?)?; let n_levels_per_type = n_levels_per_type.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (kt_level_names, remaining) = crate::x11_utils::parse_list::(remaining, n_levels_per_type.iter().try_fold(0u32, |acc, x| acc.checked_add(u32::from(*x)).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = SetNamesAuxBitcase8 { n_levels_per_type, kt_level_names }; Ok((result, remaining)) } } impl SetNamesAuxBitcase8 { #[allow(dead_code)] fn serialize(&self, n_types: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, n_types); result } fn serialize_into(&self, bytes: &mut Vec, n_types: u8) { assert_eq!(self.n_levels_per_type.len(), usize::try_from(n_types).unwrap(), "`n_levels_per_type` has an incorrect length"); bytes.extend_from_slice(&self.n_levels_per_type); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); assert_eq!(self.kt_level_names.len(), usize::try_from(self.n_levels_per_type.iter().fold(0u32, |acc, x| acc.checked_add(u32::from(*x)).unwrap())).unwrap(), "`kt_level_names` has an incorrect length"); self.kt_level_names.serialize_into(bytes); } } /// Auxiliary and optional information for the `set_names` function #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct SetNamesAux { pub keycodes_name: Option, pub geometry_name: Option, pub symbols_name: Option, pub phys_symbols_name: Option, pub types_name: Option, pub compat_name: Option, pub type_names: Option>, pub bitcase8: Option, pub indicator_names: Option>, pub virtual_mod_names: Option>, pub groups: Option>, pub key_names: Option>, pub key_aliases: Option>, pub radio_group_names: Option>, } impl SetNamesAux { fn try_parse(value: &[u8], which: u32, n_types: u8, indicators: u32, virtual_mods: u16, group_names: u8, n_keys: u8, n_key_aliases: u8, n_radio_groups: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = which; let mut outer_remaining = value; let keycodes_name = if switch_expr & u32::from(NameDetail::KEYCODES) != 0 { let remaining = outer_remaining; let (keycodes_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(keycodes_name) } else { None }; let geometry_name = if switch_expr & u32::from(NameDetail::GEOMETRY) != 0 { let remaining = outer_remaining; let (geometry_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(geometry_name) } else { None }; let symbols_name = if switch_expr & u32::from(NameDetail::SYMBOLS) != 0 { let remaining = outer_remaining; let (symbols_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(symbols_name) } else { None }; let phys_symbols_name = if switch_expr & u32::from(NameDetail::PHYS_SYMBOLS) != 0 { let remaining = outer_remaining; let (phys_symbols_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(phys_symbols_name) } else { None }; let types_name = if switch_expr & u32::from(NameDetail::TYPES) != 0 { let remaining = outer_remaining; let (types_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(types_name) } else { None }; let compat_name = if switch_expr & u32::from(NameDetail::COMPAT) != 0 { let remaining = outer_remaining; let (compat_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(compat_name) } else { None }; let type_names = if switch_expr & u32::from(NameDetail::KEY_TYPE_NAMES) != 0 { let remaining = outer_remaining; let (type_names, remaining) = crate::x11_utils::parse_list::(remaining, n_types.try_to_usize()?)?; outer_remaining = remaining; Some(type_names) } else { None }; let bitcase8 = if switch_expr & u32::from(NameDetail::KT_LEVEL_NAMES) != 0 { let (bitcase8, new_remaining) = SetNamesAuxBitcase8::try_parse(outer_remaining, n_types)?; outer_remaining = new_remaining; Some(bitcase8) } else { None }; let indicator_names = if switch_expr & u32::from(NameDetail::INDICATOR_NAMES) != 0 { let remaining = outer_remaining; let (indicator_names, remaining) = crate::x11_utils::parse_list::(remaining, indicators.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(indicator_names) } else { None }; let virtual_mod_names = if switch_expr & u32::from(NameDetail::VIRTUAL_MOD_NAMES) != 0 { let remaining = outer_remaining; let (virtual_mod_names, remaining) = crate::x11_utils::parse_list::(remaining, virtual_mods.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(virtual_mod_names) } else { None }; let groups = if switch_expr & u32::from(NameDetail::GROUP_NAMES) != 0 { let remaining = outer_remaining; let (groups, remaining) = crate::x11_utils::parse_list::(remaining, group_names.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(groups) } else { None }; let key_names = if switch_expr & u32::from(NameDetail::KEY_NAMES) != 0 { let remaining = outer_remaining; let (key_names, remaining) = crate::x11_utils::parse_list::(remaining, n_keys.try_to_usize()?)?; outer_remaining = remaining; Some(key_names) } else { None }; let key_aliases = if switch_expr & u32::from(NameDetail::KEY_ALIASES) != 0 { let remaining = outer_remaining; let (key_aliases, remaining) = crate::x11_utils::parse_list::(remaining, n_key_aliases.try_to_usize()?)?; outer_remaining = remaining; Some(key_aliases) } else { None }; let radio_group_names = if switch_expr & u32::from(NameDetail::RG_NAMES) != 0 { let remaining = outer_remaining; let (radio_group_names, remaining) = crate::x11_utils::parse_list::(remaining, n_radio_groups.try_to_usize()?)?; outer_remaining = remaining; Some(radio_group_names) } else { None }; let result = SetNamesAux { keycodes_name, geometry_name, symbols_name, phys_symbols_name, types_name, compat_name, type_names, bitcase8, indicator_names, virtual_mod_names, groups, key_names, key_aliases, radio_group_names }; Ok((result, outer_remaining)) } } impl SetNamesAux { #[allow(dead_code)] fn serialize(&self, which: u32, n_types: u8, indicators: u32, virtual_mods: u16, group_names: u8, n_keys: u8, n_key_aliases: u8, n_radio_groups: u8) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result, which, n_types, indicators, virtual_mods, group_names, n_keys, n_key_aliases, n_radio_groups); result } fn serialize_into(&self, bytes: &mut Vec, which: u32, n_types: u8, indicators: u32, virtual_mods: u16, group_names: u8, n_keys: u8, n_key_aliases: u8, n_radio_groups: u8) { assert_eq!(self.switch_expr(), which, "switch `values` has an inconsistent discriminant"); if let Some(keycodes_name) = self.keycodes_name { keycodes_name.serialize_into(bytes); } if let Some(geometry_name) = self.geometry_name { geometry_name.serialize_into(bytes); } if let Some(symbols_name) = self.symbols_name { symbols_name.serialize_into(bytes); } if let Some(phys_symbols_name) = self.phys_symbols_name { phys_symbols_name.serialize_into(bytes); } if let Some(types_name) = self.types_name { types_name.serialize_into(bytes); } if let Some(compat_name) = self.compat_name { compat_name.serialize_into(bytes); } if let Some(ref type_names) = self.type_names { assert_eq!(type_names.len(), usize::try_from(n_types).unwrap(), "`type_names` has an incorrect length"); type_names.serialize_into(bytes); } if let Some(ref bitcase8) = self.bitcase8 { bitcase8.serialize_into(bytes, n_types); } if let Some(ref indicator_names) = self.indicator_names { assert_eq!(indicator_names.len(), usize::try_from(indicators.count_ones()).unwrap(), "`indicator_names` has an incorrect length"); indicator_names.serialize_into(bytes); } if let Some(ref virtual_mod_names) = self.virtual_mod_names { assert_eq!(virtual_mod_names.len(), usize::try_from(virtual_mods.count_ones()).unwrap(), "`virtual_mod_names` has an incorrect length"); virtual_mod_names.serialize_into(bytes); } if let Some(ref groups) = self.groups { assert_eq!(groups.len(), usize::try_from(group_names.count_ones()).unwrap(), "`groups` has an incorrect length"); groups.serialize_into(bytes); } if let Some(ref key_names) = self.key_names { assert_eq!(key_names.len(), usize::try_from(n_keys).unwrap(), "`key_names` has an incorrect length"); key_names.serialize_into(bytes); } if let Some(ref key_aliases) = self.key_aliases { assert_eq!(key_aliases.len(), usize::try_from(n_key_aliases).unwrap(), "`key_aliases` has an incorrect length"); key_aliases.serialize_into(bytes); } if let Some(ref radio_group_names) = self.radio_group_names { assert_eq!(radio_group_names.len(), usize::try_from(n_radio_groups).unwrap(), "`radio_group_names` has an incorrect length"); radio_group_names.serialize_into(bytes); } } } impl SetNamesAux { fn switch_expr(&self) -> u32 { let mut expr_value = 0; if self.keycodes_name.is_some() { expr_value |= u32::from(NameDetail::KEYCODES); } if self.geometry_name.is_some() { expr_value |= u32::from(NameDetail::GEOMETRY); } if self.symbols_name.is_some() { expr_value |= u32::from(NameDetail::SYMBOLS); } if self.phys_symbols_name.is_some() { expr_value |= u32::from(NameDetail::PHYS_SYMBOLS); } if self.types_name.is_some() { expr_value |= u32::from(NameDetail::TYPES); } if self.compat_name.is_some() { expr_value |= u32::from(NameDetail::COMPAT); } if self.type_names.is_some() { expr_value |= u32::from(NameDetail::KEY_TYPE_NAMES); } if self.bitcase8.is_some() { expr_value |= u32::from(NameDetail::KT_LEVEL_NAMES); } if self.indicator_names.is_some() { expr_value |= u32::from(NameDetail::INDICATOR_NAMES); } if self.virtual_mod_names.is_some() { expr_value |= u32::from(NameDetail::VIRTUAL_MOD_NAMES); } if self.groups.is_some() { expr_value |= u32::from(NameDetail::GROUP_NAMES); } if self.key_names.is_some() { expr_value |= u32::from(NameDetail::KEY_NAMES); } if self.key_aliases.is_some() { expr_value |= u32::from(NameDetail::KEY_ALIASES); } if self.radio_group_names.is_some() { expr_value |= u32::from(NameDetail::RG_NAMES); } expr_value } } impl SetNamesAux { /// Create a new instance with all fields unset / not present. pub fn new() -> Self { Default::default() } /// Set the `keycodes_name` field of this structure. pub fn keycodes_name(mut self, value: I) -> Self where I: Into> { self.keycodes_name = value.into(); self } /// Set the `geometry_name` field of this structure. pub fn geometry_name(mut self, value: I) -> Self where I: Into> { self.geometry_name = value.into(); self } /// Set the `symbols_name` field of this structure. pub fn symbols_name(mut self, value: I) -> Self where I: Into> { self.symbols_name = value.into(); self } /// Set the `phys_symbols_name` field of this structure. pub fn phys_symbols_name(mut self, value: I) -> Self where I: Into> { self.phys_symbols_name = value.into(); self } /// Set the `types_name` field of this structure. pub fn types_name(mut self, value: I) -> Self where I: Into> { self.types_name = value.into(); self } /// Set the `compat_name` field of this structure. pub fn compat_name(mut self, value: I) -> Self where I: Into> { self.compat_name = value.into(); self } /// Set the `type_names` field of this structure. pub fn type_names(mut self, value: I) -> Self where I: Into>> { self.type_names = value.into(); self } /// Set the `bitcase8` field of this structure. pub fn bitcase8(mut self, value: I) -> Self where I: Into> { self.bitcase8 = value.into(); self } /// Set the `indicator_names` field of this structure. pub fn indicator_names(mut self, value: I) -> Self where I: Into>> { self.indicator_names = value.into(); self } /// Set the `virtual_mod_names` field of this structure. pub fn virtual_mod_names(mut self, value: I) -> Self where I: Into>> { self.virtual_mod_names = value.into(); self } /// Set the `groups` field of this structure. pub fn groups(mut self, value: I) -> Self where I: Into>> { self.groups = value.into(); self } /// Set the `key_names` field of this structure. pub fn key_names(mut self, value: I) -> Self where I: Into>> { self.key_names = value.into(); self } /// Set the `key_aliases` field of this structure. pub fn key_aliases(mut self, value: I) -> Self where I: Into>> { self.key_aliases = value.into(); self } /// Set the `radio_group_names` field of this structure. pub fn radio_group_names(mut self, value: I) -> Self where I: Into>> { self.radio_group_names = value.into(); self } } /// Opcode for the SetNames request pub const SET_NAMES_REQUEST: u8 = 18; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetNamesRequest<'input> { pub device_spec: DeviceSpec, pub virtual_mods: u16, pub first_type: u8, pub n_types: u8, pub first_kt_levelt: u8, pub n_kt_levels: u8, pub indicators: u32, pub group_names: u8, pub n_radio_groups: u8, pub first_key: xproto::Keycode, pub n_keys: u8, pub n_key_aliases: u8, pub total_kt_level_names: u16, pub values: Cow<'input, SetNamesAux>, } impl<'input> SetNamesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let virtual_mods_bytes = self.virtual_mods.serialize(); let which = self.values.switch_expr(); let which_bytes = which.serialize(); let first_type_bytes = self.first_type.serialize(); let n_types_bytes = self.n_types.serialize(); let first_kt_levelt_bytes = self.first_kt_levelt.serialize(); let n_kt_levels_bytes = self.n_kt_levels.serialize(); let indicators_bytes = self.indicators.serialize(); let group_names_bytes = self.group_names.serialize(); let n_radio_groups_bytes = self.n_radio_groups.serialize(); let first_key_bytes = self.first_key.serialize(); let n_keys_bytes = self.n_keys.serialize(); let n_key_aliases_bytes = self.n_key_aliases.serialize(); let total_kt_level_names_bytes = self.total_kt_level_names.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_NAMES_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], virtual_mods_bytes[0], virtual_mods_bytes[1], which_bytes[0], which_bytes[1], which_bytes[2], which_bytes[3], first_type_bytes[0], n_types_bytes[0], first_kt_levelt_bytes[0], n_kt_levels_bytes[0], indicators_bytes[0], indicators_bytes[1], indicators_bytes[2], indicators_bytes[3], group_names_bytes[0], n_radio_groups_bytes[0], first_key_bytes[0], n_keys_bytes[0], n_key_aliases_bytes[0], 0, total_kt_level_names_bytes[0], total_kt_level_names_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let values_bytes = self.values.serialize(which, self.n_types, self.indicators, self.virtual_mods, self.group_names, self.n_keys, self.n_key_aliases, self.n_radio_groups); let length_so_far = length_so_far + values_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), values_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_NAMES_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (which, remaining) = u32::try_parse(remaining)?; let (first_type, remaining) = u8::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (first_kt_levelt, remaining) = u8::try_parse(remaining)?; let (n_kt_levels, remaining) = u8::try_parse(remaining)?; let (indicators, remaining) = u32::try_parse(remaining)?; let (group_names, remaining) = u8::try_parse(remaining)?; let (n_radio_groups, remaining) = u8::try_parse(remaining)?; let (first_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; let (n_key_aliases, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (total_kt_level_names, remaining) = u16::try_parse(remaining)?; let (values, remaining) = SetNamesAux::try_parse(remaining, which, n_types, indicators, virtual_mods, group_names, n_keys, n_key_aliases, n_radio_groups)?; let _ = remaining; Ok(SetNamesRequest { device_spec, virtual_mods, first_type, n_types, first_kt_levelt, n_kt_levels, indicators, group_names, n_radio_groups, first_key, n_keys, n_key_aliases, total_kt_level_names, values: Cow::Owned(values), }) } /// Clone all borrowed data in this SetNamesRequest. pub fn into_owned(self) -> SetNamesRequest<'static> { SetNamesRequest { device_spec: self.device_spec, virtual_mods: self.virtual_mods, first_type: self.first_type, n_types: self.n_types, first_kt_levelt: self.first_kt_levelt, n_kt_levels: self.n_kt_levels, indicators: self.indicators, group_names: self.group_names, n_radio_groups: self.n_radio_groups, first_key: self.first_key, n_keys: self.n_keys, n_key_aliases: self.n_key_aliases, total_kt_level_names: self.total_kt_level_names, values: Cow::Owned(self.values.into_owned()), } } } impl<'input> Request for SetNamesRequest<'input> { type Reply = (); } pub fn set_names<'c, 'input, Conn, A, B>(conn: &'c Conn, device_spec: DeviceSpec, virtual_mods: A, first_type: u8, n_types: u8, first_kt_levelt: u8, n_kt_levels: u8, indicators: u32, group_names: B, n_radio_groups: u8, first_key: xproto::Keycode, n_keys: u8, n_key_aliases: u8, total_kt_level_names: u16, values: &'input SetNamesAux) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let virtual_mods: u16 = virtual_mods.into(); let group_names: u8 = group_names.into(); let request0 = SetNamesRequest { device_spec, virtual_mods, first_type, n_types, first_kt_levelt, n_kt_levels, indicators, group_names, n_radio_groups, first_key, n_keys, n_key_aliases, total_kt_level_names, values: Cow::Borrowed(values), }; request0.send(conn) } /// Opcode for the PerClientFlags request pub const PER_CLIENT_FLAGS_REQUEST: u8 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PerClientFlagsRequest { pub device_spec: DeviceSpec, pub change: u32, pub value: u32, pub ctrls_to_change: u32, pub auto_ctrls: u32, pub auto_ctrls_values: u32, } impl PerClientFlagsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let change_bytes = self.change.serialize(); let value_bytes = self.value.serialize(); let ctrls_to_change_bytes = self.ctrls_to_change.serialize(); let auto_ctrls_bytes = self.auto_ctrls.serialize(); let auto_ctrls_values_bytes = self.auto_ctrls_values.serialize(); let mut request0 = vec![ extension_information.major_opcode, PER_CLIENT_FLAGS_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], 0, 0, change_bytes[0], change_bytes[1], change_bytes[2], change_bytes[3], value_bytes[0], value_bytes[1], value_bytes[2], value_bytes[3], ctrls_to_change_bytes[0], ctrls_to_change_bytes[1], ctrls_to_change_bytes[2], ctrls_to_change_bytes[3], auto_ctrls_bytes[0], auto_ctrls_bytes[1], auto_ctrls_bytes[2], auto_ctrls_bytes[3], auto_ctrls_values_bytes[0], auto_ctrls_values_bytes[1], auto_ctrls_values_bytes[2], auto_ctrls_values_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PER_CLIENT_FLAGS_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (change, remaining) = u32::try_parse(remaining)?; let (value, remaining) = u32::try_parse(remaining)?; let (ctrls_to_change, remaining) = u32::try_parse(remaining)?; let (auto_ctrls, remaining) = u32::try_parse(remaining)?; let (auto_ctrls_values, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(PerClientFlagsRequest { device_spec, change, value, ctrls_to_change, auto_ctrls, auto_ctrls_values, }) } } impl Request for PerClientFlagsRequest { type Reply = PerClientFlagsReply; } pub fn per_client_flags(conn: &Conn, device_spec: DeviceSpec, change: A, value: B, ctrls_to_change: C, auto_ctrls: D, auto_ctrls_values: E) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, C: Into, D: Into, E: Into, { let change: u32 = change.into(); let value: u32 = value.into(); let ctrls_to_change: u32 = ctrls_to_change.into(); let auto_ctrls: u32 = auto_ctrls.into(); let auto_ctrls_values: u32 = auto_ctrls_values.into(); let request0 = PerClientFlagsRequest { device_spec, change, value, ctrls_to_change, auto_ctrls, auto_ctrls_values, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PerClientFlagsReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub supported: u32, pub value: u32, pub auto_ctrls: u32, pub auto_ctrls_values: u32, } impl TryParse for PerClientFlagsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (supported, remaining) = u32::try_parse(remaining)?; let (value, remaining) = u32::try_parse(remaining)?; let (auto_ctrls, remaining) = u32::try_parse(remaining)?; let (auto_ctrls_values, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PerClientFlagsReply { device_id, sequence, length, supported, value, auto_ctrls, auto_ctrls_values }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the ListComponents request pub const LIST_COMPONENTS_REQUEST: u8 = 22; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListComponentsRequest { pub device_spec: DeviceSpec, pub max_names: u16, } impl ListComponentsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let max_names_bytes = self.max_names.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_COMPONENTS_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], max_names_bytes[0], max_names_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_COMPONENTS_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (max_names, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(ListComponentsRequest { device_spec, max_names, }) } } impl Request for ListComponentsRequest { type Reply = ListComponentsReply; } pub fn list_components(conn: &Conn, device_spec: DeviceSpec, max_names: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListComponentsRequest { device_spec, max_names, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListComponentsReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub extra: u16, pub keymaps: Vec, pub keycodes: Vec, pub types: Vec, pub compat_maps: Vec, pub symbols: Vec, pub geometries: Vec, } impl TryParse for ListComponentsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (n_keymaps, remaining) = u16::try_parse(remaining)?; let (n_keycodes, remaining) = u16::try_parse(remaining)?; let (n_types, remaining) = u16::try_parse(remaining)?; let (n_compat_maps, remaining) = u16::try_parse(remaining)?; let (n_symbols, remaining) = u16::try_parse(remaining)?; let (n_geometries, remaining) = u16::try_parse(remaining)?; let (extra, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(10..).ok_or(ParseError::InsufficientData)?; let (keymaps, remaining) = crate::x11_utils::parse_list::(remaining, n_keymaps.try_to_usize()?)?; let (keycodes, remaining) = crate::x11_utils::parse_list::(remaining, n_keycodes.try_to_usize()?)?; let (types, remaining) = crate::x11_utils::parse_list::(remaining, n_types.try_to_usize()?)?; let (compat_maps, remaining) = crate::x11_utils::parse_list::(remaining, n_compat_maps.try_to_usize()?)?; let (symbols, remaining) = crate::x11_utils::parse_list::(remaining, n_symbols.try_to_usize()?)?; let (geometries, remaining) = crate::x11_utils::parse_list::(remaining, n_geometries.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListComponentsReply { device_id, sequence, length, extra, keymaps, keycodes, types, compat_maps, symbols, geometries }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListComponentsReply { /// Get the value of the `nKeymaps` field. /// /// The `nKeymaps` field is used as the length field of the `keymaps` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_keymaps(&self) -> u16 { self.keymaps.len() .try_into().unwrap() } /// Get the value of the `nKeycodes` field. /// /// The `nKeycodes` field is used as the length field of the `keycodes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_keycodes(&self) -> u16 { self.keycodes.len() .try_into().unwrap() } /// Get the value of the `nTypes` field. /// /// The `nTypes` field is used as the length field of the `types` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_types(&self) -> u16 { self.types.len() .try_into().unwrap() } /// Get the value of the `nCompatMaps` field. /// /// The `nCompatMaps` field is used as the length field of the `compatMaps` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_compat_maps(&self) -> u16 { self.compat_maps.len() .try_into().unwrap() } /// Get the value of the `nSymbols` field. /// /// The `nSymbols` field is used as the length field of the `symbols` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_symbols(&self) -> u16 { self.symbols.len() .try_into().unwrap() } /// Get the value of the `nGeometries` field. /// /// The `nGeometries` field is used as the length field of the `geometries` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_geometries(&self) -> u16 { self.geometries.len() .try_into().unwrap() } } /// Opcode for the GetKbdByName request pub const GET_KBD_BY_NAME_REQUEST: u8 = 23; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetKbdByNameRequest { pub device_spec: DeviceSpec, pub need: u16, pub want: u16, pub load: bool, } impl GetKbdByNameRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let need_bytes = self.need.serialize(); let want_bytes = self.want.serialize(); let load_bytes = self.load.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_KBD_BY_NAME_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], need_bytes[0], need_bytes[1], want_bytes[0], want_bytes[1], load_bytes[0], 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_KBD_BY_NAME_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (need, remaining) = u16::try_parse(remaining)?; let (want, remaining) = u16::try_parse(remaining)?; let (load, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GetKbdByNameRequest { device_spec, need, want, load, }) } } impl Request for GetKbdByNameRequest { type Reply = GetKbdByNameReply; } pub fn get_kbd_by_name(conn: &Conn, device_spec: DeviceSpec, need: A, want: B, load: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let need: u16 = need.into(); let want: u16 = want.into(); let request0 = GetKbdByNameRequest { device_spec, need, want, load, }; request0.send(conn) } #[derive(Debug, Clone)] pub struct GetKbdByNameRepliesTypesMapBitcase3 { pub acts_rtrn_count: Vec, pub acts_rtrn_acts: Vec, } impl GetKbdByNameRepliesTypesMapBitcase3 { pub fn try_parse(remaining: &[u8], n_key_actions: u8, total_actions: u16) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (acts_rtrn_count, remaining) = crate::x11_utils::parse_u8_list(remaining, n_key_actions.try_to_usize()?)?; let acts_rtrn_count = acts_rtrn_count.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (acts_rtrn_acts, remaining) = crate::x11_utils::parse_list::(remaining, total_actions.try_to_usize()?)?; let result = GetKbdByNameRepliesTypesMapBitcase3 { acts_rtrn_count, acts_rtrn_acts }; Ok((result, remaining)) } } #[derive(Debug, Clone, Default)] pub struct GetKbdByNameRepliesTypesMap { pub types_rtrn: Option>, pub syms_rtrn: Option>, pub bitcase3: Option, pub behaviors_rtrn: Option>, pub vmods_rtrn: Option>, pub explicit_rtrn: Option>, pub modmap_rtrn: Option>, pub vmodmap_rtrn: Option>, } impl GetKbdByNameRepliesTypesMap { fn try_parse(value: &[u8], present: u16, n_types: u8, n_key_syms: u8, n_key_actions: u8, total_actions: u16, total_key_behaviors: u8, virtual_mods: u16, total_key_explicit: u8, total_mod_map_keys: u8, total_v_mod_map_keys: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(present); let mut outer_remaining = value; let types_rtrn = if switch_expr & u32::from(MapPart::KEY_TYPES) != 0 { let remaining = outer_remaining; let (types_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, n_types.try_to_usize()?)?; outer_remaining = remaining; Some(types_rtrn) } else { None }; let syms_rtrn = if switch_expr & u32::from(MapPart::KEY_SYMS) != 0 { let remaining = outer_remaining; let (syms_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, n_key_syms.try_to_usize()?)?; outer_remaining = remaining; Some(syms_rtrn) } else { None }; let bitcase3 = if switch_expr & u32::from(MapPart::KEY_ACTIONS) != 0 { let (bitcase3, new_remaining) = GetKbdByNameRepliesTypesMapBitcase3::try_parse(outer_remaining, n_key_actions, total_actions)?; outer_remaining = new_remaining; Some(bitcase3) } else { None }; let behaviors_rtrn = if switch_expr & u32::from(MapPart::KEY_BEHAVIORS) != 0 { let remaining = outer_remaining; let (behaviors_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_key_behaviors.try_to_usize()?)?; outer_remaining = remaining; Some(behaviors_rtrn) } else { None }; let vmods_rtrn = if switch_expr & u32::from(MapPart::VIRTUAL_MODS) != 0 { let remaining = outer_remaining; let value = remaining; let (vmods_rtrn, remaining) = crate::x11_utils::parse_u8_list(remaining, virtual_mods.count_ones().try_to_usize()?)?; let vmods_rtrn = vmods_rtrn.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; Some(vmods_rtrn) } else { None }; let explicit_rtrn = if switch_expr & u32::from(MapPart::EXPLICIT_COMPONENTS) != 0 { let remaining = outer_remaining; let value = remaining; let (explicit_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_key_explicit.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; Some(explicit_rtrn) } else { None }; let modmap_rtrn = if switch_expr & u32::from(MapPart::MODIFIER_MAP) != 0 { let remaining = outer_remaining; let value = remaining; let (modmap_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_mod_map_keys.try_to_usize()?)?; // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; outer_remaining = remaining; Some(modmap_rtrn) } else { None }; let vmodmap_rtrn = if switch_expr & u32::from(MapPart::VIRTUAL_MOD_MAP) != 0 { let remaining = outer_remaining; let (vmodmap_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, total_v_mod_map_keys.try_to_usize()?)?; outer_remaining = remaining; Some(vmodmap_rtrn) } else { None }; let result = GetKbdByNameRepliesTypesMap { types_rtrn, syms_rtrn, bitcase3, behaviors_rtrn, vmods_rtrn, explicit_rtrn, modmap_rtrn, vmodmap_rtrn }; Ok((result, outer_remaining)) } } #[derive(Debug, Clone)] pub struct GetKbdByNameRepliesTypes { pub getmap_type: u8, pub type_device_id: u8, pub getmap_sequence: u16, pub getmap_length: u32, pub type_min_key_code: xproto::Keycode, pub type_max_key_code: xproto::Keycode, pub first_type: u8, pub n_types: u8, pub total_types: u8, pub first_key_sym: xproto::Keycode, pub total_syms: u16, pub n_key_syms: u8, pub first_key_action: xproto::Keycode, pub total_actions: u16, pub n_key_actions: u8, pub first_key_behavior: xproto::Keycode, pub n_key_behaviors: u8, pub total_key_behaviors: u8, pub first_key_explicit: xproto::Keycode, pub n_key_explicit: u8, pub total_key_explicit: u8, pub first_mod_map_key: xproto::Keycode, pub n_mod_map_keys: u8, pub total_mod_map_keys: u8, pub first_v_mod_map_key: xproto::Keycode, pub n_v_mod_map_keys: u8, pub total_v_mod_map_keys: u8, pub virtual_mods: u16, pub map: GetKbdByNameRepliesTypesMap, } impl TryParse for GetKbdByNameRepliesTypes { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (getmap_type, remaining) = u8::try_parse(remaining)?; let (type_device_id, remaining) = u8::try_parse(remaining)?; let (getmap_sequence, remaining) = u16::try_parse(remaining)?; let (getmap_length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (type_min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (type_max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (present, remaining) = u16::try_parse(remaining)?; let (first_type, remaining) = u8::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (total_types, remaining) = u8::try_parse(remaining)?; let (first_key_sym, remaining) = xproto::Keycode::try_parse(remaining)?; let (total_syms, remaining) = u16::try_parse(remaining)?; let (n_key_syms, remaining) = u8::try_parse(remaining)?; let (first_key_action, remaining) = xproto::Keycode::try_parse(remaining)?; let (total_actions, remaining) = u16::try_parse(remaining)?; let (n_key_actions, remaining) = u8::try_parse(remaining)?; let (first_key_behavior, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_behaviors, remaining) = u8::try_parse(remaining)?; let (total_key_behaviors, remaining) = u8::try_parse(remaining)?; let (first_key_explicit, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_explicit, remaining) = u8::try_parse(remaining)?; let (total_key_explicit, remaining) = u8::try_parse(remaining)?; let (first_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (total_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (first_v_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (total_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (map, remaining) = GetKbdByNameRepliesTypesMap::try_parse(remaining, present, n_types, n_key_syms, n_key_actions, total_actions, total_key_behaviors, virtual_mods, total_key_explicit, total_mod_map_keys, total_v_mod_map_keys)?; let result = GetKbdByNameRepliesTypes { getmap_type, type_device_id, getmap_sequence, getmap_length, type_min_key_code, type_max_key_code, first_type, n_types, total_types, first_key_sym, total_syms, n_key_syms, first_key_action, total_actions, n_key_actions, first_key_behavior, n_key_behaviors, total_key_behaviors, first_key_explicit, n_key_explicit, total_key_explicit, first_mod_map_key, n_mod_map_keys, total_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, total_v_mod_map_keys, virtual_mods, map }; Ok((result, remaining)) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetKbdByNameRepliesCompatMap { pub compatmap_type: u8, pub compat_device_id: u8, pub compatmap_sequence: u16, pub compatmap_length: u32, pub groups_rtrn: u8, pub first_si_rtrn: u16, pub n_total_si: u16, pub si_rtrn: Vec, pub group_rtrn: Vec, } impl TryParse for GetKbdByNameRepliesCompatMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (compatmap_type, remaining) = u8::try_parse(remaining)?; let (compat_device_id, remaining) = u8::try_parse(remaining)?; let (compatmap_sequence, remaining) = u16::try_parse(remaining)?; let (compatmap_length, remaining) = u32::try_parse(remaining)?; let (groups_rtrn, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (first_si_rtrn, remaining) = u16::try_parse(remaining)?; let (n_si_rtrn, remaining) = u16::try_parse(remaining)?; let (n_total_si, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (si_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, n_si_rtrn.try_to_usize()?)?; let (group_rtrn, remaining) = crate::x11_utils::parse_list::(remaining, groups_rtrn.count_ones().try_to_usize()?)?; let result = GetKbdByNameRepliesCompatMap { compatmap_type, compat_device_id, compatmap_sequence, compatmap_length, groups_rtrn, first_si_rtrn, n_total_si, si_rtrn, group_rtrn }; Ok((result, remaining)) } } impl GetKbdByNameRepliesCompatMap { /// Get the value of the `nSIRtrn` field. /// /// The `nSIRtrn` field is used as the length field of the `si_rtrn` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_si_rtrn(&self) -> u16 { self.si_rtrn.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetKbdByNameRepliesIndicatorMaps { pub indicatormap_type: u8, pub indicator_device_id: u8, pub indicatormap_sequence: u16, pub indicatormap_length: u32, pub which: u32, pub real_indicators: u32, pub maps: Vec, } impl TryParse for GetKbdByNameRepliesIndicatorMaps { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (indicatormap_type, remaining) = u8::try_parse(remaining)?; let (indicator_device_id, remaining) = u8::try_parse(remaining)?; let (indicatormap_sequence, remaining) = u16::try_parse(remaining)?; let (indicatormap_length, remaining) = u32::try_parse(remaining)?; let (which, remaining) = u32::try_parse(remaining)?; let (real_indicators, remaining) = u32::try_parse(remaining)?; let (n_indicators, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(15..).ok_or(ParseError::InsufficientData)?; let (maps, remaining) = crate::x11_utils::parse_list::(remaining, n_indicators.try_to_usize()?)?; let result = GetKbdByNameRepliesIndicatorMaps { indicatormap_type, indicator_device_id, indicatormap_sequence, indicatormap_length, which, real_indicators, maps }; Ok((result, remaining)) } } impl GetKbdByNameRepliesIndicatorMaps { /// Get the value of the `nIndicators` field. /// /// The `nIndicators` field is used as the length field of the `maps` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_indicators(&self) -> u8 { self.maps.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetKbdByNameRepliesKeyNamesValueListBitcase8 { pub n_levels_per_type: Vec, pub kt_level_names: Vec, } impl GetKbdByNameRepliesKeyNamesValueListBitcase8 { pub fn try_parse(remaining: &[u8], n_types: u8) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (n_levels_per_type, remaining) = crate::x11_utils::parse_u8_list(remaining, n_types.try_to_usize()?)?; let n_levels_per_type = n_levels_per_type.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (kt_level_names, remaining) = crate::x11_utils::parse_list::(remaining, n_levels_per_type.iter().try_fold(0u32, |acc, x| acc.checked_add(u32::from(*x)).ok_or(ParseError::InvalidExpression))?.try_to_usize()?)?; let result = GetKbdByNameRepliesKeyNamesValueListBitcase8 { n_levels_per_type, kt_level_names }; Ok((result, remaining)) } } #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct GetKbdByNameRepliesKeyNamesValueList { pub keycodes_name: Option, pub geometry_name: Option, pub symbols_name: Option, pub phys_symbols_name: Option, pub types_name: Option, pub compat_name: Option, pub type_names: Option>, pub bitcase8: Option, pub indicator_names: Option>, pub virtual_mod_names: Option>, pub groups: Option>, pub key_names: Option>, pub key_aliases: Option>, pub radio_group_names: Option>, } impl GetKbdByNameRepliesKeyNamesValueList { fn try_parse(value: &[u8], which: u32, n_types: u8, indicators: u32, virtual_mods: u16, group_names: u8, n_keys: u8, n_key_aliases: u8, n_radio_groups: u8) -> Result<(Self, &[u8]), ParseError> { let switch_expr = which; let mut outer_remaining = value; let keycodes_name = if switch_expr & u32::from(NameDetail::KEYCODES) != 0 { let remaining = outer_remaining; let (keycodes_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(keycodes_name) } else { None }; let geometry_name = if switch_expr & u32::from(NameDetail::GEOMETRY) != 0 { let remaining = outer_remaining; let (geometry_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(geometry_name) } else { None }; let symbols_name = if switch_expr & u32::from(NameDetail::SYMBOLS) != 0 { let remaining = outer_remaining; let (symbols_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(symbols_name) } else { None }; let phys_symbols_name = if switch_expr & u32::from(NameDetail::PHYS_SYMBOLS) != 0 { let remaining = outer_remaining; let (phys_symbols_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(phys_symbols_name) } else { None }; let types_name = if switch_expr & u32::from(NameDetail::TYPES) != 0 { let remaining = outer_remaining; let (types_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(types_name) } else { None }; let compat_name = if switch_expr & u32::from(NameDetail::COMPAT) != 0 { let remaining = outer_remaining; let (compat_name, remaining) = xproto::Atom::try_parse(remaining)?; outer_remaining = remaining; Some(compat_name) } else { None }; let type_names = if switch_expr & u32::from(NameDetail::KEY_TYPE_NAMES) != 0 { let remaining = outer_remaining; let (type_names, remaining) = crate::x11_utils::parse_list::(remaining, n_types.try_to_usize()?)?; outer_remaining = remaining; Some(type_names) } else { None }; let bitcase8 = if switch_expr & u32::from(NameDetail::KT_LEVEL_NAMES) != 0 { let (bitcase8, new_remaining) = GetKbdByNameRepliesKeyNamesValueListBitcase8::try_parse(outer_remaining, n_types)?; outer_remaining = new_remaining; Some(bitcase8) } else { None }; let indicator_names = if switch_expr & u32::from(NameDetail::INDICATOR_NAMES) != 0 { let remaining = outer_remaining; let (indicator_names, remaining) = crate::x11_utils::parse_list::(remaining, indicators.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(indicator_names) } else { None }; let virtual_mod_names = if switch_expr & u32::from(NameDetail::VIRTUAL_MOD_NAMES) != 0 { let remaining = outer_remaining; let (virtual_mod_names, remaining) = crate::x11_utils::parse_list::(remaining, virtual_mods.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(virtual_mod_names) } else { None }; let groups = if switch_expr & u32::from(NameDetail::GROUP_NAMES) != 0 { let remaining = outer_remaining; let (groups, remaining) = crate::x11_utils::parse_list::(remaining, group_names.count_ones().try_to_usize()?)?; outer_remaining = remaining; Some(groups) } else { None }; let key_names = if switch_expr & u32::from(NameDetail::KEY_NAMES) != 0 { let remaining = outer_remaining; let (key_names, remaining) = crate::x11_utils::parse_list::(remaining, n_keys.try_to_usize()?)?; outer_remaining = remaining; Some(key_names) } else { None }; let key_aliases = if switch_expr & u32::from(NameDetail::KEY_ALIASES) != 0 { let remaining = outer_remaining; let (key_aliases, remaining) = crate::x11_utils::parse_list::(remaining, n_key_aliases.try_to_usize()?)?; outer_remaining = remaining; Some(key_aliases) } else { None }; let radio_group_names = if switch_expr & u32::from(NameDetail::RG_NAMES) != 0 { let remaining = outer_remaining; let (radio_group_names, remaining) = crate::x11_utils::parse_list::(remaining, n_radio_groups.try_to_usize()?)?; outer_remaining = remaining; Some(radio_group_names) } else { None }; let result = GetKbdByNameRepliesKeyNamesValueList { keycodes_name, geometry_name, symbols_name, phys_symbols_name, types_name, compat_name, type_names, bitcase8, indicator_names, virtual_mod_names, groups, key_names, key_aliases, radio_group_names }; Ok((result, outer_remaining)) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetKbdByNameRepliesKeyNames { pub keyname_type: u8, pub key_device_id: u8, pub keyname_sequence: u16, pub keyname_length: u32, pub key_min_key_code: xproto::Keycode, pub key_max_key_code: xproto::Keycode, pub n_types: u8, pub group_names: u8, pub virtual_mods: u16, pub first_key: xproto::Keycode, pub n_keys: u8, pub indicators: u32, pub n_radio_groups: u8, pub n_key_aliases: u8, pub n_kt_levels: u16, pub value_list: GetKbdByNameRepliesKeyNamesValueList, } impl TryParse for GetKbdByNameRepliesKeyNames { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (keyname_type, remaining) = u8::try_parse(remaining)?; let (key_device_id, remaining) = u8::try_parse(remaining)?; let (keyname_sequence, remaining) = u16::try_parse(remaining)?; let (keyname_length, remaining) = u32::try_parse(remaining)?; let (which, remaining) = u32::try_parse(remaining)?; let (key_min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (key_max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (group_names, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let (first_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; let (indicators, remaining) = u32::try_parse(remaining)?; let (n_radio_groups, remaining) = u8::try_parse(remaining)?; let (n_key_aliases, remaining) = u8::try_parse(remaining)?; let (n_kt_levels, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (value_list, remaining) = GetKbdByNameRepliesKeyNamesValueList::try_parse(remaining, which, n_types, indicators, virtual_mods, group_names, n_keys, n_key_aliases, n_radio_groups)?; let result = GetKbdByNameRepliesKeyNames { keyname_type, key_device_id, keyname_sequence, keyname_length, key_min_key_code, key_max_key_code, n_types, group_names, virtual_mods, first_key, n_keys, indicators, n_radio_groups, n_key_aliases, n_kt_levels, value_list }; Ok((result, remaining)) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetKbdByNameRepliesGeometry { pub geometry_type: u8, pub geometry_device_id: u8, pub geometry_sequence: u16, pub geometry_length: u32, pub name: xproto::Atom, pub geometry_found: bool, pub width_mm: u16, pub height_mm: u16, pub n_properties: u16, pub n_colors: u16, pub n_shapes: u16, pub n_sections: u16, pub n_doodads: u16, pub n_key_aliases: u16, pub base_color_ndx: u8, pub label_color_ndx: u8, pub label_font: CountedString16, } impl TryParse for GetKbdByNameRepliesGeometry { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (geometry_type, remaining) = u8::try_parse(remaining)?; let (geometry_device_id, remaining) = u8::try_parse(remaining)?; let (geometry_sequence, remaining) = u16::try_parse(remaining)?; let (geometry_length, remaining) = u32::try_parse(remaining)?; let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (geometry_found, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (width_mm, remaining) = u16::try_parse(remaining)?; let (height_mm, remaining) = u16::try_parse(remaining)?; let (n_properties, remaining) = u16::try_parse(remaining)?; let (n_colors, remaining) = u16::try_parse(remaining)?; let (n_shapes, remaining) = u16::try_parse(remaining)?; let (n_sections, remaining) = u16::try_parse(remaining)?; let (n_doodads, remaining) = u16::try_parse(remaining)?; let (n_key_aliases, remaining) = u16::try_parse(remaining)?; let (base_color_ndx, remaining) = u8::try_parse(remaining)?; let (label_color_ndx, remaining) = u8::try_parse(remaining)?; let (label_font, remaining) = CountedString16::try_parse(remaining)?; let result = GetKbdByNameRepliesGeometry { geometry_type, geometry_device_id, geometry_sequence, geometry_length, name, geometry_found, width_mm, height_mm, n_properties, n_colors, n_shapes, n_sections, n_doodads, n_key_aliases, base_color_ndx, label_color_ndx, label_font }; Ok((result, remaining)) } } #[derive(Debug, Clone, Default)] pub struct GetKbdByNameReplies { pub types: Option, pub compat_map: Option, pub indicator_maps: Option, pub key_names: Option, pub geometry: Option, } impl GetKbdByNameReplies { fn try_parse(value: &[u8], reported: u16) -> Result<(Self, &[u8]), ParseError> { let switch_expr = u32::from(reported); let mut outer_remaining = value; let types = if switch_expr & u32::from(GBNDetail::TYPES) != 0 || switch_expr & u32::from(GBNDetail::CLIENT_SYMBOLS) != 0 || switch_expr & u32::from(GBNDetail::SERVER_SYMBOLS) != 0 { let (types, new_remaining) = GetKbdByNameRepliesTypes::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(types) } else { None }; let compat_map = if switch_expr & u32::from(GBNDetail::COMPAT_MAP) != 0 { let (compat_map, new_remaining) = GetKbdByNameRepliesCompatMap::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(compat_map) } else { None }; let indicator_maps = if switch_expr & u32::from(GBNDetail::INDICATOR_MAPS) != 0 { let (indicator_maps, new_remaining) = GetKbdByNameRepliesIndicatorMaps::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(indicator_maps) } else { None }; let key_names = if switch_expr & u32::from(GBNDetail::KEY_NAMES) != 0 || switch_expr & u32::from(GBNDetail::OTHER_NAMES) != 0 { let (key_names, new_remaining) = GetKbdByNameRepliesKeyNames::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(key_names) } else { None }; let geometry = if switch_expr & u32::from(GBNDetail::GEOMETRY) != 0 { let (geometry, new_remaining) = GetKbdByNameRepliesGeometry::try_parse(outer_remaining)?; outer_remaining = new_remaining; Some(geometry) } else { None }; let result = GetKbdByNameReplies { types, compat_map, indicator_maps, key_names, geometry }; Ok((result, outer_remaining)) } } #[derive(Debug, Clone)] pub struct GetKbdByNameReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub min_key_code: xproto::Keycode, pub max_key_code: xproto::Keycode, pub loaded: bool, pub new_keyboard: bool, pub found: u16, pub reported: u16, pub replies: GetKbdByNameReplies, } impl TryParse for GetKbdByNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (loaded, remaining) = bool::try_parse(remaining)?; let (new_keyboard, remaining) = bool::try_parse(remaining)?; let (found, remaining) = u16::try_parse(remaining)?; let (reported, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (replies, remaining) = GetKbdByNameReplies::try_parse(remaining, reported)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetKbdByNameReply { device_id, sequence, length, min_key_code, max_key_code, loaded, new_keyboard, found, reported, replies }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the GetDeviceInfo request pub const GET_DEVICE_INFO_REQUEST: u8 = 24; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceInfoRequest { pub device_spec: DeviceSpec, pub wanted: u16, pub all_buttons: bool, pub first_button: u8, pub n_buttons: u8, pub led_class: LedClass, pub led_id: IDSpec, } impl GetDeviceInfoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let wanted_bytes = self.wanted.serialize(); let all_buttons_bytes = self.all_buttons.serialize(); let first_button_bytes = self.first_button.serialize(); let n_buttons_bytes = self.n_buttons.serialize(); let led_class_bytes = LedClassSpec::from(self.led_class).serialize(); let led_id_bytes = self.led_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_INFO_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], wanted_bytes[0], wanted_bytes[1], all_buttons_bytes[0], first_button_bytes[0], n_buttons_bytes[0], 0, led_class_bytes[0], led_class_bytes[1], led_id_bytes[0], led_id_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (wanted, remaining) = u16::try_parse(remaining)?; let (all_buttons, remaining) = bool::try_parse(remaining)?; let (first_button, remaining) = u8::try_parse(remaining)?; let (n_buttons, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (led_class, remaining) = LedClassSpec::try_parse(remaining)?; let led_class = led_class.into(); let (led_id, remaining) = IDSpec::try_parse(remaining)?; let _ = remaining; Ok(GetDeviceInfoRequest { device_spec, wanted, all_buttons, first_button, n_buttons, led_class, led_id, }) } } impl Request for GetDeviceInfoRequest { type Reply = GetDeviceInfoReply; } pub fn get_device_info(conn: &Conn, device_spec: DeviceSpec, wanted: A, all_buttons: bool, first_button: u8, n_buttons: u8, led_class: LedClass, led_id: B) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, B: Into, { let wanted: u16 = wanted.into(); let led_id: IDSpec = led_id.into(); let request0 = GetDeviceInfoRequest { device_spec, wanted, all_buttons, first_button, n_buttons, led_class, led_id, }; request0.send(conn) } #[derive(Debug, Clone)] pub struct GetDeviceInfoReply { pub device_id: u8, pub sequence: u16, pub length: u32, pub present: u16, pub supported: u16, pub unsupported: u16, pub first_btn_wanted: u8, pub n_btns_wanted: u8, pub first_btn_rtrn: u8, pub total_btns: u8, pub has_own_state: bool, pub dflt_kbd_fb: u16, pub dflt_led_fb: u16, pub dev_type: xproto::Atom, pub name: Vec, pub btn_actions: Vec, pub leds: Vec, } impl TryParse for GetDeviceInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (present, remaining) = u16::try_parse(remaining)?; let (supported, remaining) = u16::try_parse(remaining)?; let (unsupported, remaining) = u16::try_parse(remaining)?; let (n_device_led_f_bs, remaining) = u16::try_parse(remaining)?; let (first_btn_wanted, remaining) = u8::try_parse(remaining)?; let (n_btns_wanted, remaining) = u8::try_parse(remaining)?; let (first_btn_rtrn, remaining) = u8::try_parse(remaining)?; let (n_btns_rtrn, remaining) = u8::try_parse(remaining)?; let (total_btns, remaining) = u8::try_parse(remaining)?; let (has_own_state, remaining) = bool::try_parse(remaining)?; let (dflt_kbd_fb, remaining) = u16::try_parse(remaining)?; let (dflt_led_fb, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (dev_type, remaining) = xproto::Atom::try_parse(remaining)?; let (name_len, remaining) = u16::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (btn_actions, remaining) = crate::x11_utils::parse_list::(remaining, n_btns_rtrn.try_to_usize()?)?; let (leds, remaining) = crate::x11_utils::parse_list::(remaining, n_device_led_f_bs.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceInfoReply { device_id, sequence, length, present, supported, unsupported, first_btn_wanted, n_btns_wanted, first_btn_rtrn, total_btns, has_own_state, dflt_kbd_fb, dflt_led_fb, dev_type, name, btn_actions, leds }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceInfoReply { /// Get the value of the `nDeviceLedFBs` field. /// /// The `nDeviceLedFBs` field is used as the length field of the `leds` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_device_led_f_bs(&self) -> u16 { self.leds.len() .try_into().unwrap() } /// Get the value of the `nBtnsRtrn` field. /// /// The `nBtnsRtrn` field is used as the length field of the `btnActions` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn n_btns_rtrn(&self) -> u8 { self.btn_actions.len() .try_into().unwrap() } /// Get the value of the `nameLen` field. /// /// The `nameLen` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u16 { self.name.len() .try_into().unwrap() } } /// Opcode for the SetDeviceInfo request pub const SET_DEVICE_INFO_REQUEST: u8 = 25; #[derive(Debug, Clone)] pub struct SetDeviceInfoRequest<'input> { pub device_spec: DeviceSpec, pub first_btn: u8, pub change: u16, pub btn_actions: Cow<'input, [Action]>, pub leds: Cow<'input, [DeviceLedInfo]>, } impl<'input> SetDeviceInfoRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_spec_bytes = self.device_spec.serialize(); let first_btn_bytes = self.first_btn.serialize(); let n_btns = u8::try_from(self.btn_actions.len()).expect("`btn_actions` has too many elements"); let n_btns_bytes = n_btns.serialize(); let change_bytes = self.change.serialize(); let n_device_led_f_bs = u16::try_from(self.leds.len()).expect("`leds` has too many elements"); let n_device_led_f_bs_bytes = n_device_led_f_bs.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_INFO_REQUEST, 0, 0, device_spec_bytes[0], device_spec_bytes[1], first_btn_bytes[0], n_btns_bytes[0], change_bytes[0], change_bytes[1], n_device_led_f_bs_bytes[0], n_device_led_f_bs_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let btn_actions_bytes = self.btn_actions.serialize(); let length_so_far = length_so_far + btn_actions_bytes.len(); let leds_bytes = self.leds.serialize(); let length_so_far = length_so_far + leds_bytes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), btn_actions_bytes.into(), leds_bytes.into(), padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_DEVICE_INFO_REQUEST { return Err(ParseError::InvalidValue); } let (device_spec, remaining) = DeviceSpec::try_parse(value)?; let (first_btn, remaining) = u8::try_parse(remaining)?; let (n_btns, remaining) = u8::try_parse(remaining)?; let (change, remaining) = u16::try_parse(remaining)?; let (n_device_led_f_bs, remaining) = u16::try_parse(remaining)?; let (btn_actions, remaining) = crate::x11_utils::parse_list::(remaining, n_btns.try_to_usize()?)?; let (leds, remaining) = crate::x11_utils::parse_list::(remaining, n_device_led_f_bs.try_to_usize()?)?; let _ = remaining; Ok(SetDeviceInfoRequest { device_spec, first_btn, change, btn_actions: Cow::Owned(btn_actions), leds: Cow::Owned(leds), }) } /// Clone all borrowed data in this SetDeviceInfoRequest. pub fn into_owned(self) -> SetDeviceInfoRequest<'static> { SetDeviceInfoRequest { device_spec: self.device_spec, first_btn: self.first_btn, change: self.change, btn_actions: Cow::Owned(self.btn_actions.into_owned()), leds: Cow::Owned(self.leds.into_owned()), } } } impl<'input> Request for SetDeviceInfoRequest<'input> { type Reply = (); } pub fn set_device_info<'c, 'input, Conn, A>(conn: &'c Conn, device_spec: DeviceSpec, first_btn: u8, change: A, btn_actions: &'input [Action], leds: &'input [DeviceLedInfo]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let change: u16 = change.into(); let request0 = SetDeviceInfoRequest { device_spec, first_btn, change, btn_actions: Cow::Borrowed(btn_actions), leds: Cow::Borrowed(leds), }; request0.send(conn) } /// Opcode for the SetDebuggingFlags request pub const SET_DEBUGGING_FLAGS_REQUEST: u8 = 101; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetDebuggingFlagsRequest<'input> { pub affect_flags: u32, pub flags: u32, pub affect_ctrls: u32, pub ctrls: u32, pub message: Cow<'input, [String8]>, } impl<'input> SetDebuggingFlagsRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let msg_length = u16::try_from(self.message.len()).expect("`message` has too many elements"); let msg_length_bytes = msg_length.serialize(); let affect_flags_bytes = self.affect_flags.serialize(); let flags_bytes = self.flags.serialize(); let affect_ctrls_bytes = self.affect_ctrls.serialize(); let ctrls_bytes = self.ctrls.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEBUGGING_FLAGS_REQUEST, 0, 0, msg_length_bytes[0], msg_length_bytes[1], 0, 0, affect_flags_bytes[0], affect_flags_bytes[1], affect_flags_bytes[2], affect_flags_bytes[3], flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], affect_ctrls_bytes[0], affect_ctrls_bytes[1], affect_ctrls_bytes[2], affect_ctrls_bytes[3], ctrls_bytes[0], ctrls_bytes[1], ctrls_bytes[2], ctrls_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.message.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.message, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_DEBUGGING_FLAGS_REQUEST { return Err(ParseError::InvalidValue); } let (msg_length, remaining) = u16::try_parse(value)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (affect_flags, remaining) = u32::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let (affect_ctrls, remaining) = u32::try_parse(remaining)?; let (ctrls, remaining) = u32::try_parse(remaining)?; let (message, remaining) = crate::x11_utils::parse_u8_list(remaining, msg_length.try_to_usize()?)?; let _ = remaining; Ok(SetDebuggingFlagsRequest { affect_flags, flags, affect_ctrls, ctrls, message: Cow::Borrowed(message), }) } /// Clone all borrowed data in this SetDebuggingFlagsRequest. pub fn into_owned(self) -> SetDebuggingFlagsRequest<'static> { SetDebuggingFlagsRequest { affect_flags: self.affect_flags, flags: self.flags, affect_ctrls: self.affect_ctrls, ctrls: self.ctrls, message: Cow::Owned(self.message.into_owned()), } } } impl<'input> Request for SetDebuggingFlagsRequest<'input> { type Reply = SetDebuggingFlagsReply; } pub fn set_debugging_flags<'c, 'input, Conn>(conn: &'c Conn, affect_flags: u32, flags: u32, affect_ctrls: u32, ctrls: u32, message: &'input [String8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetDebuggingFlagsRequest { affect_flags, flags, affect_ctrls, ctrls, message: Cow::Borrowed(message), }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetDebuggingFlagsReply { pub sequence: u16, pub length: u32, pub current_flags: u32, pub current_ctrls: u32, pub supported_flags: u32, pub supported_ctrls: u32, } impl TryParse for SetDebuggingFlagsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (current_flags, remaining) = u32::try_parse(remaining)?; let (current_ctrls, remaining) = u32::try_parse(remaining)?; let (supported_flags, remaining) = u32::try_parse(remaining)?; let (supported_ctrls, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = SetDebuggingFlagsReply { sequence, length, current_flags, current_ctrls, supported_flags, supported_ctrls }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the NewKeyboardNotify event pub const NEW_KEYBOARD_NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NewKeyboardNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub old_device_id: u8, pub min_key_code: xproto::Keycode, pub max_key_code: xproto::Keycode, pub old_min_key_code: xproto::Keycode, pub old_max_key_code: xproto::Keycode, pub request_major: u8, pub request_minor: u8, pub changed: u16, } impl TryParse for NewKeyboardNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (old_device_id, remaining) = u8::try_parse(remaining)?; let (min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (old_min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (old_max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (request_major, remaining) = u8::try_parse(remaining)?; let (request_minor, remaining) = u8::try_parse(remaining)?; let (changed, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(14..).ok_or(ParseError::InsufficientData)?; let result = NewKeyboardNotifyEvent { response_type, xkb_type, sequence, time, device_id, old_device_id, min_key_code, max_key_code, old_min_key_code, old_max_key_code, request_major, request_minor, changed }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NewKeyboardNotifyEvent> for [u8; 32] { fn from(input: &NewKeyboardNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let old_device_id_bytes = input.old_device_id.serialize(); let min_key_code_bytes = input.min_key_code.serialize(); let max_key_code_bytes = input.max_key_code.serialize(); let old_min_key_code_bytes = input.old_min_key_code.serialize(); let old_max_key_code_bytes = input.old_max_key_code.serialize(); let request_major_bytes = input.request_major.serialize(); let request_minor_bytes = input.request_minor.serialize(); let changed_bytes = input.changed.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], old_device_id_bytes[0], min_key_code_bytes[0], max_key_code_bytes[0], old_min_key_code_bytes[0], old_max_key_code_bytes[0], request_major_bytes[0], request_minor_bytes[0], changed_bytes[0], changed_bytes[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: NewKeyboardNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the MapNotify event pub const MAP_NOTIFY_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MapNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub ptr_btn_actions: u8, pub changed: u16, pub min_key_code: xproto::Keycode, pub max_key_code: xproto::Keycode, pub first_type: u8, pub n_types: u8, pub first_key_sym: xproto::Keycode, pub n_key_syms: u8, pub first_key_act: xproto::Keycode, pub n_key_acts: u8, pub first_key_behavior: xproto::Keycode, pub n_key_behavior: u8, pub first_key_explicit: xproto::Keycode, pub n_key_explicit: u8, pub first_mod_map_key: xproto::Keycode, pub n_mod_map_keys: u8, pub first_v_mod_map_key: xproto::Keycode, pub n_v_mod_map_keys: u8, pub virtual_mods: u16, } impl TryParse for MapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (ptr_btn_actions, remaining) = u8::try_parse(remaining)?; let (changed, remaining) = u16::try_parse(remaining)?; let (min_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (max_key_code, remaining) = xproto::Keycode::try_parse(remaining)?; let (first_type, remaining) = u8::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (first_key_sym, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_syms, remaining) = u8::try_parse(remaining)?; let (first_key_act, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_acts, remaining) = u8::try_parse(remaining)?; let (first_key_behavior, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_behavior, remaining) = u8::try_parse(remaining)?; let (first_key_explicit, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_key_explicit, remaining) = u8::try_parse(remaining)?; let (first_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (first_v_mod_map_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_v_mod_map_keys, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let result = MapNotifyEvent { response_type, xkb_type, sequence, time, device_id, ptr_btn_actions, changed, min_key_code, max_key_code, first_type, n_types, first_key_sym, n_key_syms, first_key_act, n_key_acts, first_key_behavior, n_key_behavior, first_key_explicit, n_key_explicit, first_mod_map_key, n_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, virtual_mods }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&MapNotifyEvent> for [u8; 32] { fn from(input: &MapNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let ptr_btn_actions_bytes = input.ptr_btn_actions.serialize(); let changed_bytes = input.changed.serialize(); let min_key_code_bytes = input.min_key_code.serialize(); let max_key_code_bytes = input.max_key_code.serialize(); let first_type_bytes = input.first_type.serialize(); let n_types_bytes = input.n_types.serialize(); let first_key_sym_bytes = input.first_key_sym.serialize(); let n_key_syms_bytes = input.n_key_syms.serialize(); let first_key_act_bytes = input.first_key_act.serialize(); let n_key_acts_bytes = input.n_key_acts.serialize(); let first_key_behavior_bytes = input.first_key_behavior.serialize(); let n_key_behavior_bytes = input.n_key_behavior.serialize(); let first_key_explicit_bytes = input.first_key_explicit.serialize(); let n_key_explicit_bytes = input.n_key_explicit.serialize(); let first_mod_map_key_bytes = input.first_mod_map_key.serialize(); let n_mod_map_keys_bytes = input.n_mod_map_keys.serialize(); let first_v_mod_map_key_bytes = input.first_v_mod_map_key.serialize(); let n_v_mod_map_keys_bytes = input.n_v_mod_map_keys.serialize(); let virtual_mods_bytes = input.virtual_mods.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], ptr_btn_actions_bytes[0], changed_bytes[0], changed_bytes[1], min_key_code_bytes[0], max_key_code_bytes[0], first_type_bytes[0], n_types_bytes[0], first_key_sym_bytes[0], n_key_syms_bytes[0], first_key_act_bytes[0], n_key_acts_bytes[0], first_key_behavior_bytes[0], n_key_behavior_bytes[0], first_key_explicit_bytes[0], n_key_explicit_bytes[0], first_mod_map_key_bytes[0], n_mod_map_keys_bytes[0], first_v_mod_map_key_bytes[0], n_v_mod_map_keys_bytes[0], virtual_mods_bytes[0], virtual_mods_bytes[1], 0, 0, ] } } impl From for [u8; 32] { fn from(input: MapNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the StateNotify event pub const STATE_NOTIFY_EVENT: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct StateNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub mods: u8, pub base_mods: u8, pub latched_mods: u8, pub locked_mods: u8, pub group: Group, pub base_group: i16, pub latched_group: i16, pub locked_group: Group, pub compat_state: u8, pub grab_mods: u8, pub compat_grab_mods: u8, pub lookup_mods: u8, pub compat_loockup_mods: u8, pub ptr_btn_state: u16, pub changed: u16, pub keycode: xproto::Keycode, pub event_type: u8, pub request_major: u8, pub request_minor: u8, } impl TryParse for StateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let (base_mods, remaining) = u8::try_parse(remaining)?; let (latched_mods, remaining) = u8::try_parse(remaining)?; let (locked_mods, remaining) = u8::try_parse(remaining)?; let (group, remaining) = u8::try_parse(remaining)?; let (base_group, remaining) = i16::try_parse(remaining)?; let (latched_group, remaining) = i16::try_parse(remaining)?; let (locked_group, remaining) = u8::try_parse(remaining)?; let (compat_state, remaining) = u8::try_parse(remaining)?; let (grab_mods, remaining) = u8::try_parse(remaining)?; let (compat_grab_mods, remaining) = u8::try_parse(remaining)?; let (lookup_mods, remaining) = u8::try_parse(remaining)?; let (compat_loockup_mods, remaining) = u8::try_parse(remaining)?; let (ptr_btn_state, remaining) = u16::try_parse(remaining)?; let (changed, remaining) = u16::try_parse(remaining)?; let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (event_type, remaining) = u8::try_parse(remaining)?; let (request_major, remaining) = u8::try_parse(remaining)?; let (request_minor, remaining) = u8::try_parse(remaining)?; let group = group.into(); let locked_group = locked_group.into(); let result = StateNotifyEvent { response_type, xkb_type, sequence, time, device_id, mods, base_mods, latched_mods, locked_mods, group, base_group, latched_group, locked_group, compat_state, grab_mods, compat_grab_mods, lookup_mods, compat_loockup_mods, ptr_btn_state, changed, keycode, event_type, request_major, request_minor }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&StateNotifyEvent> for [u8; 32] { fn from(input: &StateNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let mods_bytes = input.mods.serialize(); let base_mods_bytes = input.base_mods.serialize(); let latched_mods_bytes = input.latched_mods.serialize(); let locked_mods_bytes = input.locked_mods.serialize(); let group_bytes = u8::from(input.group).serialize(); let base_group_bytes = input.base_group.serialize(); let latched_group_bytes = input.latched_group.serialize(); let locked_group_bytes = u8::from(input.locked_group).serialize(); let compat_state_bytes = input.compat_state.serialize(); let grab_mods_bytes = input.grab_mods.serialize(); let compat_grab_mods_bytes = input.compat_grab_mods.serialize(); let lookup_mods_bytes = input.lookup_mods.serialize(); let compat_loockup_mods_bytes = input.compat_loockup_mods.serialize(); let ptr_btn_state_bytes = input.ptr_btn_state.serialize(); let changed_bytes = input.changed.serialize(); let keycode_bytes = input.keycode.serialize(); let event_type_bytes = input.event_type.serialize(); let request_major_bytes = input.request_major.serialize(); let request_minor_bytes = input.request_minor.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], mods_bytes[0], base_mods_bytes[0], latched_mods_bytes[0], locked_mods_bytes[0], group_bytes[0], base_group_bytes[0], base_group_bytes[1], latched_group_bytes[0], latched_group_bytes[1], locked_group_bytes[0], compat_state_bytes[0], grab_mods_bytes[0], compat_grab_mods_bytes[0], lookup_mods_bytes[0], compat_loockup_mods_bytes[0], ptr_btn_state_bytes[0], ptr_btn_state_bytes[1], changed_bytes[0], changed_bytes[1], keycode_bytes[0], event_type_bytes[0], request_major_bytes[0], request_minor_bytes[0], ] } } impl From for [u8; 32] { fn from(input: StateNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the ControlsNotify event pub const CONTROLS_NOTIFY_EVENT: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ControlsNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub num_groups: u8, pub changed_controls: u32, pub enabled_controls: u32, pub enabled_control_changes: u32, pub keycode: xproto::Keycode, pub event_type: u8, pub request_major: u8, pub request_minor: u8, } impl TryParse for ControlsNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (num_groups, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (changed_controls, remaining) = u32::try_parse(remaining)?; let (enabled_controls, remaining) = u32::try_parse(remaining)?; let (enabled_control_changes, remaining) = u32::try_parse(remaining)?; let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (event_type, remaining) = u8::try_parse(remaining)?; let (request_major, remaining) = u8::try_parse(remaining)?; let (request_minor, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let result = ControlsNotifyEvent { response_type, xkb_type, sequence, time, device_id, num_groups, changed_controls, enabled_controls, enabled_control_changes, keycode, event_type, request_major, request_minor }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ControlsNotifyEvent> for [u8; 32] { fn from(input: &ControlsNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let num_groups_bytes = input.num_groups.serialize(); let changed_controls_bytes = input.changed_controls.serialize(); let enabled_controls_bytes = input.enabled_controls.serialize(); let enabled_control_changes_bytes = input.enabled_control_changes.serialize(); let keycode_bytes = input.keycode.serialize(); let event_type_bytes = input.event_type.serialize(); let request_major_bytes = input.request_major.serialize(); let request_minor_bytes = input.request_minor.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], num_groups_bytes[0], 0, 0, changed_controls_bytes[0], changed_controls_bytes[1], changed_controls_bytes[2], changed_controls_bytes[3], enabled_controls_bytes[0], enabled_controls_bytes[1], enabled_controls_bytes[2], enabled_controls_bytes[3], enabled_control_changes_bytes[0], enabled_control_changes_bytes[1], enabled_control_changes_bytes[2], enabled_control_changes_bytes[3], keycode_bytes[0], event_type_bytes[0], request_major_bytes[0], request_minor_bytes[0], 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ControlsNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the IndicatorStateNotify event pub const INDICATOR_STATE_NOTIFY_EVENT: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IndicatorStateNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub state: u32, pub state_changed: u32, } impl TryParse for IndicatorStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (state, remaining) = u32::try_parse(remaining)?; let (state_changed, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let result = IndicatorStateNotifyEvent { response_type, xkb_type, sequence, time, device_id, state, state_changed }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&IndicatorStateNotifyEvent> for [u8; 32] { fn from(input: &IndicatorStateNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let state_bytes = input.state.serialize(); let state_changed_bytes = input.state_changed.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], 0, 0, 0, state_bytes[0], state_bytes[1], state_bytes[2], state_bytes[3], state_changed_bytes[0], state_changed_bytes[1], state_changed_bytes[2], state_changed_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: IndicatorStateNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the IndicatorMapNotify event pub const INDICATOR_MAP_NOTIFY_EVENT: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct IndicatorMapNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub state: u32, pub map_changed: u32, } impl TryParse for IndicatorMapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (state, remaining) = u32::try_parse(remaining)?; let (map_changed, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let result = IndicatorMapNotifyEvent { response_type, xkb_type, sequence, time, device_id, state, map_changed }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&IndicatorMapNotifyEvent> for [u8; 32] { fn from(input: &IndicatorMapNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let state_bytes = input.state.serialize(); let map_changed_bytes = input.map_changed.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], 0, 0, 0, state_bytes[0], state_bytes[1], state_bytes[2], state_bytes[3], map_changed_bytes[0], map_changed_bytes[1], map_changed_bytes[2], map_changed_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: IndicatorMapNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the NamesNotify event pub const NAMES_NOTIFY_EVENT: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NamesNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub changed: u16, pub first_type: u8, pub n_types: u8, pub first_level_name: u8, pub n_level_names: u8, pub n_radio_groups: u8, pub n_key_aliases: u8, pub changed_group_names: u8, pub changed_virtual_mods: u16, pub first_key: xproto::Keycode, pub n_keys: u8, pub changed_indicators: u32, } impl TryParse for NamesNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (changed, remaining) = u16::try_parse(remaining)?; let (first_type, remaining) = u8::try_parse(remaining)?; let (n_types, remaining) = u8::try_parse(remaining)?; let (first_level_name, remaining) = u8::try_parse(remaining)?; let (n_level_names, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (n_radio_groups, remaining) = u8::try_parse(remaining)?; let (n_key_aliases, remaining) = u8::try_parse(remaining)?; let (changed_group_names, remaining) = u8::try_parse(remaining)?; let (changed_virtual_mods, remaining) = u16::try_parse(remaining)?; let (first_key, remaining) = xproto::Keycode::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; let (changed_indicators, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let result = NamesNotifyEvent { response_type, xkb_type, sequence, time, device_id, changed, first_type, n_types, first_level_name, n_level_names, n_radio_groups, n_key_aliases, changed_group_names, changed_virtual_mods, first_key, n_keys, changed_indicators }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NamesNotifyEvent> for [u8; 32] { fn from(input: &NamesNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let changed_bytes = input.changed.serialize(); let first_type_bytes = input.first_type.serialize(); let n_types_bytes = input.n_types.serialize(); let first_level_name_bytes = input.first_level_name.serialize(); let n_level_names_bytes = input.n_level_names.serialize(); let n_radio_groups_bytes = input.n_radio_groups.serialize(); let n_key_aliases_bytes = input.n_key_aliases.serialize(); let changed_group_names_bytes = input.changed_group_names.serialize(); let changed_virtual_mods_bytes = input.changed_virtual_mods.serialize(); let first_key_bytes = input.first_key.serialize(); let n_keys_bytes = input.n_keys.serialize(); let changed_indicators_bytes = input.changed_indicators.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], 0, changed_bytes[0], changed_bytes[1], first_type_bytes[0], n_types_bytes[0], first_level_name_bytes[0], n_level_names_bytes[0], 0, n_radio_groups_bytes[0], n_key_aliases_bytes[0], changed_group_names_bytes[0], changed_virtual_mods_bytes[0], changed_virtual_mods_bytes[1], first_key_bytes[0], n_keys_bytes[0], changed_indicators_bytes[0], changed_indicators_bytes[1], changed_indicators_bytes[2], changed_indicators_bytes[3], 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: NamesNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the CompatMapNotify event pub const COMPAT_MAP_NOTIFY_EVENT: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CompatMapNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub changed_groups: u8, pub first_si: u16, pub n_si: u16, pub n_total_si: u16, } impl TryParse for CompatMapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (changed_groups, remaining) = u8::try_parse(remaining)?; let (first_si, remaining) = u16::try_parse(remaining)?; let (n_si, remaining) = u16::try_parse(remaining)?; let (n_total_si, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let result = CompatMapNotifyEvent { response_type, xkb_type, sequence, time, device_id, changed_groups, first_si, n_si, n_total_si }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&CompatMapNotifyEvent> for [u8; 32] { fn from(input: &CompatMapNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let changed_groups_bytes = input.changed_groups.serialize(); let first_si_bytes = input.first_si.serialize(); let n_si_bytes = input.n_si.serialize(); let n_total_si_bytes = input.n_total_si.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], changed_groups_bytes[0], first_si_bytes[0], first_si_bytes[1], n_si_bytes[0], n_si_bytes[1], n_total_si_bytes[0], n_total_si_bytes[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: CompatMapNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the BellNotify event pub const BELL_NOTIFY_EVENT: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BellNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub bell_class: BellClassResult, pub bell_id: u8, pub percent: u8, pub pitch: u16, pub duration: u16, pub name: xproto::Atom, pub window: xproto::Window, pub event_only: bool, } impl TryParse for BellNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (bell_class, remaining) = u8::try_parse(remaining)?; let (bell_id, remaining) = u8::try_parse(remaining)?; let (percent, remaining) = u8::try_parse(remaining)?; let (pitch, remaining) = u16::try_parse(remaining)?; let (duration, remaining) = u16::try_parse(remaining)?; let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (event_only, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(7..).ok_or(ParseError::InsufficientData)?; let bell_class = bell_class.into(); let result = BellNotifyEvent { response_type, xkb_type, sequence, time, device_id, bell_class, bell_id, percent, pitch, duration, name, window, event_only }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&BellNotifyEvent> for [u8; 32] { fn from(input: &BellNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let bell_class_bytes = u8::from(input.bell_class).serialize(); let bell_id_bytes = input.bell_id.serialize(); let percent_bytes = input.percent.serialize(); let pitch_bytes = input.pitch.serialize(); let duration_bytes = input.duration.serialize(); let name_bytes = input.name.serialize(); let window_bytes = input.window.serialize(); let event_only_bytes = input.event_only.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], bell_class_bytes[0], bell_id_bytes[0], percent_bytes[0], pitch_bytes[0], pitch_bytes[1], duration_bytes[0], duration_bytes[1], name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], event_only_bytes[0], 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: BellNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the ActionMessage event pub const ACTION_MESSAGE_EVENT: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ActionMessageEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub keycode: xproto::Keycode, pub press: bool, pub key_event_follows: bool, pub mods: u8, pub group: Group, pub message: [String8; 8], } impl TryParse for ActionMessageEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (press, remaining) = bool::try_parse(remaining)?; let (key_event_follows, remaining) = bool::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let (group, remaining) = u8::try_parse(remaining)?; let (message, remaining) = crate::x11_utils::parse_u8_list(remaining, 8)?; let message = <[u8; 8]>::try_from(message).unwrap(); let remaining = remaining.get(10..).ok_or(ParseError::InsufficientData)?; let group = group.into(); let result = ActionMessageEvent { response_type, xkb_type, sequence, time, device_id, keycode, press, key_event_follows, mods, group, message }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ActionMessageEvent> for [u8; 32] { fn from(input: &ActionMessageEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let keycode_bytes = input.keycode.serialize(); let press_bytes = input.press.serialize(); let key_event_follows_bytes = input.key_event_follows.serialize(); let mods_bytes = input.mods.serialize(); let group_bytes = u8::from(input.group).serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], keycode_bytes[0], press_bytes[0], key_event_follows_bytes[0], mods_bytes[0], group_bytes[0], input.message[0], input.message[1], input.message[2], input.message[3], input.message[4], input.message[5], input.message[6], input.message[7], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ActionMessageEvent) -> Self { Self::from(&input) } } /// Opcode for the AccessXNotify event pub const ACCESS_X_NOTIFY_EVENT: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AccessXNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub keycode: xproto::Keycode, pub detailt: u16, pub slow_keys_delay: u16, pub debounce_delay: u16, } impl TryParse for AccessXNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (detailt, remaining) = u16::try_parse(remaining)?; let (slow_keys_delay, remaining) = u16::try_parse(remaining)?; let (debounce_delay, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let result = AccessXNotifyEvent { response_type, xkb_type, sequence, time, device_id, keycode, detailt, slow_keys_delay, debounce_delay }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&AccessXNotifyEvent> for [u8; 32] { fn from(input: &AccessXNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let keycode_bytes = input.keycode.serialize(); let detailt_bytes = input.detailt.serialize(); let slow_keys_delay_bytes = input.slow_keys_delay.serialize(); let debounce_delay_bytes = input.debounce_delay.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], keycode_bytes[0], detailt_bytes[0], detailt_bytes[1], slow_keys_delay_bytes[0], slow_keys_delay_bytes[1], debounce_delay_bytes[0], debounce_delay_bytes[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: AccessXNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the ExtensionDeviceNotify event pub const EXTENSION_DEVICE_NOTIFY_EVENT: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ExtensionDeviceNotifyEvent { pub response_type: u8, pub xkb_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub device_id: u8, pub reason: u16, pub led_class: LedClassResult, pub led_id: u16, pub leds_defined: u32, pub led_state: u32, pub first_button: u8, pub n_buttons: u8, pub supported: u16, pub unsupported: u16, } impl TryParse for ExtensionDeviceNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (reason, remaining) = u16::try_parse(remaining)?; let (led_class, remaining) = u16::try_parse(remaining)?; let (led_id, remaining) = u16::try_parse(remaining)?; let (leds_defined, remaining) = u32::try_parse(remaining)?; let (led_state, remaining) = u32::try_parse(remaining)?; let (first_button, remaining) = u8::try_parse(remaining)?; let (n_buttons, remaining) = u8::try_parse(remaining)?; let (supported, remaining) = u16::try_parse(remaining)?; let (unsupported, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let led_class = led_class.into(); let result = ExtensionDeviceNotifyEvent { response_type, xkb_type, sequence, time, device_id, reason, led_class, led_id, leds_defined, led_state, first_button, n_buttons, supported, unsupported }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ExtensionDeviceNotifyEvent> for [u8; 32] { fn from(input: &ExtensionDeviceNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let xkb_type_bytes = input.xkb_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let device_id_bytes = input.device_id.serialize(); let reason_bytes = input.reason.serialize(); let led_class_bytes = u16::from(input.led_class).serialize(); let led_id_bytes = input.led_id.serialize(); let leds_defined_bytes = input.leds_defined.serialize(); let led_state_bytes = input.led_state.serialize(); let first_button_bytes = input.first_button.serialize(); let n_buttons_bytes = input.n_buttons.serialize(); let supported_bytes = input.supported.serialize(); let unsupported_bytes = input.unsupported.serialize(); [ response_type_bytes[0], xkb_type_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], device_id_bytes[0], 0, reason_bytes[0], reason_bytes[1], led_class_bytes[0], led_class_bytes[1], led_id_bytes[0], led_id_bytes[1], leds_defined_bytes[0], leds_defined_bytes[1], leds_defined_bytes[2], leds_defined_bytes[3], led_state_bytes[0], led_state_bytes[1], led_state_bytes[2], led_state_bytes[3], first_button_bytes[0], n_buttons_bytes[0], supported_bytes[0], supported_bytes[1], unsupported_bytes[0], unsupported_bytes[1], 0, 0, ] } } impl From for [u8; 32] { fn from(input: ExtensionDeviceNotifyEvent) -> Self { Self::from(&input) } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xkb_use_extension(&self, wanted_major: u16, wanted_minor: u16) -> Result, ConnectionError> { use_extension(self, wanted_major, wanted_minor) } fn xkb_select_events<'c, 'input, A, B, C, D>(&'c self, device_spec: DeviceSpec, clear: A, select_all: B, affect_map: C, map: D, details: &'input SelectEventsAux) -> Result, ConnectionError> where A: Into, B: Into, C: Into, D: Into, { select_events(self, device_spec, clear, select_all, affect_map, map, details) } fn xkb_bell(&self, device_spec: DeviceSpec, bell_class: BellClassSpec, bell_id: IDSpec, percent: i8, force_sound: bool, event_only: bool, pitch: i16, duration: i16, name: xproto::Atom, window: xproto::Window) -> Result, ConnectionError> { bell(self, device_spec, bell_class, bell_id, percent, force_sound, event_only, pitch, duration, name, window) } fn xkb_get_state(&self, device_spec: DeviceSpec) -> Result, ConnectionError> { get_state(self, device_spec) } fn xkb_latch_lock_state(&self, device_spec: DeviceSpec, affect_mod_locks: A, mod_locks: B, lock_group: bool, group_lock: Group, affect_mod_latches: C, latch_group: bool, group_latch: u16) -> Result, ConnectionError> where A: Into, B: Into, C: Into, { latch_lock_state(self, device_spec, affect_mod_locks, mod_locks, lock_group, group_lock, affect_mod_latches, latch_group, group_latch) } fn xkb_get_controls(&self, device_spec: DeviceSpec) -> Result, ConnectionError> { get_controls(self, device_spec) } fn xkb_set_controls<'c, 'input, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(&'c self, device_spec: DeviceSpec, affect_internal_real_mods: A, internal_real_mods: B, affect_ignore_lock_real_mods: C, ignore_lock_real_mods: D, affect_internal_virtual_mods: E, internal_virtual_mods: F, affect_ignore_lock_virtual_mods: G, ignore_lock_virtual_mods: H, mouse_keys_dflt_btn: u8, groups_wrap: u8, access_x_options: I, affect_enabled_controls: J, enabled_controls: K, change_controls: L, repeat_delay: u16, repeat_interval: u16, slow_keys_delay: u16, debounce_delay: u16, mouse_keys_delay: u16, mouse_keys_interval: u16, mouse_keys_time_to_max: u16, mouse_keys_max_speed: u16, mouse_keys_curve: i16, access_x_timeout: u16, access_x_timeout_mask: M, access_x_timeout_values: N, access_x_timeout_options_mask: O, access_x_timeout_options_values: P, per_key_repeat: &'input [u8; 32]) -> Result, ConnectionError> where A: Into, B: Into, C: Into, D: Into, E: Into, F: Into, G: Into, H: Into, I: Into, J: Into, K: Into, L: Into, M: Into, N: Into, O: Into, P: Into, { set_controls(self, device_spec, affect_internal_real_mods, internal_real_mods, affect_ignore_lock_real_mods, ignore_lock_real_mods, affect_internal_virtual_mods, internal_virtual_mods, affect_ignore_lock_virtual_mods, ignore_lock_virtual_mods, mouse_keys_dflt_btn, groups_wrap, access_x_options, affect_enabled_controls, enabled_controls, change_controls, repeat_delay, repeat_interval, slow_keys_delay, debounce_delay, mouse_keys_delay, mouse_keys_interval, mouse_keys_time_to_max, mouse_keys_max_speed, mouse_keys_curve, access_x_timeout, access_x_timeout_mask, access_x_timeout_values, access_x_timeout_options_mask, access_x_timeout_options_values, per_key_repeat) } fn xkb_get_map(&self, device_spec: DeviceSpec, full: A, partial: B, first_type: u8, n_types: u8, first_key_sym: xproto::Keycode, n_key_syms: u8, first_key_action: xproto::Keycode, n_key_actions: u8, first_key_behavior: xproto::Keycode, n_key_behaviors: u8, virtual_mods: C, first_key_explicit: xproto::Keycode, n_key_explicit: u8, first_mod_map_key: xproto::Keycode, n_mod_map_keys: u8, first_v_mod_map_key: xproto::Keycode, n_v_mod_map_keys: u8) -> Result, ConnectionError> where A: Into, B: Into, C: Into, { get_map(self, device_spec, full, partial, first_type, n_types, first_key_sym, n_key_syms, first_key_action, n_key_actions, first_key_behavior, n_key_behaviors, virtual_mods, first_key_explicit, n_key_explicit, first_mod_map_key, n_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys) } fn xkb_set_map<'c, 'input, A, B>(&'c self, device_spec: DeviceSpec, flags: A, min_key_code: xproto::Keycode, max_key_code: xproto::Keycode, first_type: u8, n_types: u8, first_key_sym: xproto::Keycode, n_key_syms: u8, total_syms: u16, first_key_action: xproto::Keycode, n_key_actions: u8, total_actions: u16, first_key_behavior: xproto::Keycode, n_key_behaviors: u8, total_key_behaviors: u8, first_key_explicit: xproto::Keycode, n_key_explicit: u8, total_key_explicit: u8, first_mod_map_key: xproto::Keycode, n_mod_map_keys: u8, total_mod_map_keys: u8, first_v_mod_map_key: xproto::Keycode, n_v_mod_map_keys: u8, total_v_mod_map_keys: u8, virtual_mods: B, values: &'input SetMapAux) -> Result, ConnectionError> where A: Into, B: Into, { set_map(self, device_spec, flags, min_key_code, max_key_code, first_type, n_types, first_key_sym, n_key_syms, total_syms, first_key_action, n_key_actions, total_actions, first_key_behavior, n_key_behaviors, total_key_behaviors, first_key_explicit, n_key_explicit, total_key_explicit, first_mod_map_key, n_mod_map_keys, total_mod_map_keys, first_v_mod_map_key, n_v_mod_map_keys, total_v_mod_map_keys, virtual_mods, values) } fn xkb_get_compat_map(&self, device_spec: DeviceSpec, groups: A, get_all_si: bool, first_si: u16, n_si: u16) -> Result, ConnectionError> where A: Into, { get_compat_map(self, device_spec, groups, get_all_si, first_si, n_si) } fn xkb_set_compat_map<'c, 'input, A>(&'c self, device_spec: DeviceSpec, recompute_actions: bool, truncate_si: bool, groups: A, first_si: u16, si: &'input [SymInterpret], group_maps: &'input [ModDef]) -> Result, ConnectionError> where A: Into, { set_compat_map(self, device_spec, recompute_actions, truncate_si, groups, first_si, si, group_maps) } fn xkb_get_indicator_state(&self, device_spec: DeviceSpec) -> Result, ConnectionError> { get_indicator_state(self, device_spec) } fn xkb_get_indicator_map(&self, device_spec: DeviceSpec, which: u32) -> Result, ConnectionError> { get_indicator_map(self, device_spec, which) } fn xkb_set_indicator_map<'c, 'input>(&'c self, device_spec: DeviceSpec, which: u32, maps: &'input [IndicatorMap]) -> Result, ConnectionError> { set_indicator_map(self, device_spec, which, maps) } fn xkb_get_named_indicator(&self, device_spec: DeviceSpec, led_class: LedClass, led_id: A, indicator: xproto::Atom) -> Result, ConnectionError> where A: Into, { get_named_indicator(self, device_spec, led_class, led_id, indicator) } fn xkb_set_named_indicator(&self, device_spec: DeviceSpec, led_class: LedClass, led_id: A, indicator: xproto::Atom, set_state: bool, on: bool, set_map: bool, create_map: bool, map_flags: B, map_which_groups: C, map_groups: D, map_which_mods: E, map_real_mods: F, map_vmods: G, map_ctrls: H) -> Result, ConnectionError> where A: Into, B: Into, C: Into, D: Into, E: Into, F: Into, G: Into, H: Into, { set_named_indicator(self, device_spec, led_class, led_id, indicator, set_state, on, set_map, create_map, map_flags, map_which_groups, map_groups, map_which_mods, map_real_mods, map_vmods, map_ctrls) } fn xkb_get_names(&self, device_spec: DeviceSpec, which: A) -> Result, ConnectionError> where A: Into, { get_names(self, device_spec, which) } fn xkb_set_names<'c, 'input, A, B>(&'c self, device_spec: DeviceSpec, virtual_mods: A, first_type: u8, n_types: u8, first_kt_levelt: u8, n_kt_levels: u8, indicators: u32, group_names: B, n_radio_groups: u8, first_key: xproto::Keycode, n_keys: u8, n_key_aliases: u8, total_kt_level_names: u16, values: &'input SetNamesAux) -> Result, ConnectionError> where A: Into, B: Into, { set_names(self, device_spec, virtual_mods, first_type, n_types, first_kt_levelt, n_kt_levels, indicators, group_names, n_radio_groups, first_key, n_keys, n_key_aliases, total_kt_level_names, values) } fn xkb_per_client_flags(&self, device_spec: DeviceSpec, change: A, value: B, ctrls_to_change: C, auto_ctrls: D, auto_ctrls_values: E) -> Result, ConnectionError> where A: Into, B: Into, C: Into, D: Into, E: Into, { per_client_flags(self, device_spec, change, value, ctrls_to_change, auto_ctrls, auto_ctrls_values) } fn xkb_list_components(&self, device_spec: DeviceSpec, max_names: u16) -> Result, ConnectionError> { list_components(self, device_spec, max_names) } fn xkb_get_kbd_by_name(&self, device_spec: DeviceSpec, need: A, want: B, load: bool) -> Result, ConnectionError> where A: Into, B: Into, { get_kbd_by_name(self, device_spec, need, want, load) } fn xkb_get_device_info(&self, device_spec: DeviceSpec, wanted: A, all_buttons: bool, first_button: u8, n_buttons: u8, led_class: LedClass, led_id: B) -> Result, ConnectionError> where A: Into, B: Into, { get_device_info(self, device_spec, wanted, all_buttons, first_button, n_buttons, led_class, led_id) } fn xkb_set_device_info<'c, 'input, A>(&'c self, device_spec: DeviceSpec, first_btn: u8, change: A, btn_actions: &'input [Action], leds: &'input [DeviceLedInfo]) -> Result, ConnectionError> where A: Into, { set_device_info(self, device_spec, first_btn, change, btn_actions, leds) } fn xkb_set_debugging_flags<'c, 'input>(&'c self, affect_flags: u32, flags: u32, affect_ctrls: u32, ctrls: u32, message: &'input [String8]) -> Result, ConnectionError> { set_debugging_flags(self, affect_flags, flags, affect_ctrls, ctrls, message) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xprint.rs010064400017500001750000003225011402220031600151510ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `XPrint` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XpExtension"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 0); pub type String8 = u8; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Printer { pub name: Vec, pub description: Vec, } impl TryParse for Printer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (name_len, remaining) = u32::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (desc_len, remaining) = u32::try_parse(remaining)?; let (description, remaining) = crate::x11_utils::parse_u8_list(remaining, desc_len.try_to_usize()?)?; let description = description.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = Printer { name, description }; Ok((result, remaining)) } } impl Serialize for Printer { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { let name_len = u32::try_from(self.name.len()).expect("`name` has too many elements"); name_len.serialize_into(bytes); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); let desc_len = u32::try_from(self.description.len()).expect("`description` has too many elements"); desc_len.serialize_into(bytes); bytes.extend_from_slice(&self.description); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl Printer { /// Get the value of the `nameLen` field. /// /// The `nameLen` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_len(&self) -> u32 { self.name.len() .try_into().unwrap() } /// Get the value of the `descLen` field. /// /// The `descLen` field is used as the length field of the `description` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn desc_len(&self) -> u32 { self.description.len() .try_into().unwrap() } } pub type Pcontext = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct GetDoc(bool); impl GetDoc { pub const FINISHED: Self = Self(false); pub const SECOND_CONSUMER: Self = Self(true); } impl From for bool { #[inline] fn from(input: GetDoc) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GetDoc) -> Self { Some(input.0) } } impl From for u8 { #[inline] fn from(input: GetDoc) -> Self { u8::from(input.0) } } impl From for Option { #[inline] fn from(input: GetDoc) -> Self { Some(u8::from(input.0)) } } impl From for u16 { #[inline] fn from(input: GetDoc) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: GetDoc) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: GetDoc) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: GetDoc) -> Self { Some(u32::from(input.0)) } } impl From for GetDoc { #[inline] fn from(value: bool) -> Self { Self(value) } } impl std::fmt::Debug for GetDoc { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::FINISHED.0.into(), "FINISHED", "Finished"), (Self::SECOND_CONSUMER.0.into(), "SECOND_CONSUMER", "SecondConsumer"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct EvMask(u8); impl EvMask { pub const NO_EVENT_MASK: Self = Self(0); pub const PRINT_MASK: Self = Self(1 << 0); pub const ATTRIBUTE_MASK: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: EvMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: EvMask) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: EvMask) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: EvMask) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: EvMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: EvMask) -> Self { Some(u32::from(input.0)) } } impl From for EvMask { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for EvMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_EVENT_MASK.0.into(), "NO_EVENT_MASK", "NoEventMask"), (Self::PRINT_MASK.0.into(), "PRINT_MASK", "PrintMask"), (Self::ATTRIBUTE_MASK.0.into(), "ATTRIBUTE_MASK", "AttributeMask"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(EvMask, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct Detail(u8); impl Detail { pub const START_JOB_NOTIFY: Self = Self(1); pub const END_JOB_NOTIFY: Self = Self(2); pub const START_DOC_NOTIFY: Self = Self(3); pub const END_DOC_NOTIFY: Self = Self(4); pub const START_PAGE_NOTIFY: Self = Self(5); pub const END_PAGE_NOTIFY: Self = Self(6); } impl From for u8 { #[inline] fn from(input: Detail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Detail) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Detail) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Detail) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Detail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Detail) -> Self { Some(u32::from(input.0)) } } impl From for Detail { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Detail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::START_JOB_NOTIFY.0.into(), "START_JOB_NOTIFY", "StartJobNotify"), (Self::END_JOB_NOTIFY.0.into(), "END_JOB_NOTIFY", "EndJobNotify"), (Self::START_DOC_NOTIFY.0.into(), "START_DOC_NOTIFY", "StartDocNotify"), (Self::END_DOC_NOTIFY.0.into(), "END_DOC_NOTIFY", "EndDocNotify"), (Self::START_PAGE_NOTIFY.0.into(), "START_PAGE_NOTIFY", "StartPageNotify"), (Self::END_PAGE_NOTIFY.0.into(), "END_PAGE_NOTIFY", "EndPageNotify"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Attr(u8); impl Attr { pub const JOB_ATTR: Self = Self(1); pub const DOC_ATTR: Self = Self(2); pub const PAGE_ATTR: Self = Self(3); pub const PRINTER_ATTR: Self = Self(4); pub const SERVER_ATTR: Self = Self(5); pub const MEDIUM_ATTR: Self = Self(6); pub const SPOOLER_ATTR: Self = Self(7); } impl From for u8 { #[inline] fn from(input: Attr) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Attr) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Attr) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Attr) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Attr) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Attr) -> Self { Some(u32::from(input.0)) } } impl From for Attr { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Attr { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::JOB_ATTR.0.into(), "JOB_ATTR", "JobAttr"), (Self::DOC_ATTR.0.into(), "DOC_ATTR", "DocAttr"), (Self::PAGE_ATTR.0.into(), "PAGE_ATTR", "PageAttr"), (Self::PRINTER_ATTR.0.into(), "PRINTER_ATTR", "PrinterAttr"), (Self::SERVER_ATTR.0.into(), "SERVER_ATTR", "ServerAttr"), (Self::MEDIUM_ATTR.0.into(), "MEDIUM_ATTR", "MediumAttr"), (Self::SPOOLER_ATTR.0.into(), "SPOOLER_ATTR", "SpoolerAttr"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the PrintQueryVersion request pub const PRINT_QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintQueryVersionRequest; impl PrintQueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, PRINT_QUERY_VERSION_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(PrintQueryVersionRequest ) } } impl Request for PrintQueryVersionRequest { type Reply = PrintQueryVersionReply; } pub fn print_query_version(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintQueryVersionRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintQueryVersionReply { pub sequence: u16, pub length: u32, pub major_version: u16, pub minor_version: u16, } impl TryParse for PrintQueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major_version, remaining) = u16::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintQueryVersionReply { sequence, length, major_version, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PrintGetPrinterList request pub const PRINT_GET_PRINTER_LIST_REQUEST: u8 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintGetPrinterListRequest<'input> { pub printer_name: Cow<'input, [String8]>, pub locale: Cow<'input, [String8]>, } impl<'input> PrintGetPrinterListRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let printer_name_len = u32::try_from(self.printer_name.len()).expect("`printer_name` has too many elements"); let printer_name_len_bytes = printer_name_len.serialize(); let locale_len = u32::try_from(self.locale.len()).expect("`locale` has too many elements"); let locale_len_bytes = locale_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_PRINTER_LIST_REQUEST, 0, 0, printer_name_len_bytes[0], printer_name_len_bytes[1], printer_name_len_bytes[2], printer_name_len_bytes[3], locale_len_bytes[0], locale_len_bytes[1], locale_len_bytes[2], locale_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.printer_name.len(); let length_so_far = length_so_far + self.locale.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.printer_name, self.locale, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != PRINT_GET_PRINTER_LIST_REQUEST { return Err(ParseError::InvalidValue); } let (printer_name_len, remaining) = u32::try_parse(value)?; let (locale_len, remaining) = u32::try_parse(remaining)?; let (printer_name, remaining) = crate::x11_utils::parse_u8_list(remaining, printer_name_len.try_to_usize()?)?; let (locale, remaining) = crate::x11_utils::parse_u8_list(remaining, locale_len.try_to_usize()?)?; let _ = remaining; Ok(PrintGetPrinterListRequest { printer_name: Cow::Borrowed(printer_name), locale: Cow::Borrowed(locale), }) } /// Clone all borrowed data in this PrintGetPrinterListRequest. pub fn into_owned(self) -> PrintGetPrinterListRequest<'static> { PrintGetPrinterListRequest { printer_name: Cow::Owned(self.printer_name.into_owned()), locale: Cow::Owned(self.locale.into_owned()), } } } impl<'input> Request for PrintGetPrinterListRequest<'input> { type Reply = PrintGetPrinterListReply; } pub fn print_get_printer_list<'c, 'input, Conn>(conn: &'c Conn, printer_name: &'input [String8], locale: &'input [String8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetPrinterListRequest { printer_name: Cow::Borrowed(printer_name), locale: Cow::Borrowed(locale), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintGetPrinterListReply { pub sequence: u16, pub length: u32, pub printers: Vec, } impl TryParse for PrintGetPrinterListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (list_count, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (printers, remaining) = crate::x11_utils::parse_list::(remaining, list_count.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetPrinterListReply { sequence, length, printers }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl PrintGetPrinterListReply { /// Get the value of the `listCount` field. /// /// The `listCount` field is used as the length field of the `printers` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn list_count(&self) -> u32 { self.printers.len() .try_into().unwrap() } } /// Opcode for the PrintRehashPrinterList request pub const PRINT_REHASH_PRINTER_LIST_REQUEST: u8 = 20; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintRehashPrinterListRequest; impl PrintRehashPrinterListRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, PRINT_REHASH_PRINTER_LIST_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_REHASH_PRINTER_LIST_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(PrintRehashPrinterListRequest ) } } impl Request for PrintRehashPrinterListRequest { type Reply = (); } pub fn print_rehash_printer_list(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintRehashPrinterListRequest; request0.send(conn) } /// Opcode for the CreateContext request pub const CREATE_CONTEXT_REQUEST: u8 = 2; #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateContextRequest<'input> { pub context_id: u32, pub printer_name: Cow<'input, [String8]>, pub locale: Cow<'input, [String8]>, } impl<'input> CreateContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_id_bytes = self.context_id.serialize(); let printer_name_len = u32::try_from(self.printer_name.len()).expect("`printer_name` has too many elements"); let printer_name_len_bytes = printer_name_len.serialize(); let locale_len = u32::try_from(self.locale.len()).expect("`locale` has too many elements"); let locale_len_bytes = locale_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CONTEXT_REQUEST, 0, 0, context_id_bytes[0], context_id_bytes[1], context_id_bytes[2], context_id_bytes[3], printer_name_len_bytes[0], printer_name_len_bytes[1], printer_name_len_bytes[2], printer_name_len_bytes[3], locale_len_bytes[0], locale_len_bytes[1], locale_len_bytes[2], locale_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.printer_name.len(); let length_so_far = length_so_far + self.locale.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.printer_name, self.locale, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_id, remaining) = u32::try_parse(value)?; let (printer_name_len, remaining) = u32::try_parse(remaining)?; let (locale_len, remaining) = u32::try_parse(remaining)?; let (printer_name, remaining) = crate::x11_utils::parse_u8_list(remaining, printer_name_len.try_to_usize()?)?; let (locale, remaining) = crate::x11_utils::parse_u8_list(remaining, locale_len.try_to_usize()?)?; let _ = remaining; Ok(CreateContextRequest { context_id, printer_name: Cow::Borrowed(printer_name), locale: Cow::Borrowed(locale), }) } /// Clone all borrowed data in this CreateContextRequest. pub fn into_owned(self) -> CreateContextRequest<'static> { CreateContextRequest { context_id: self.context_id, printer_name: Cow::Owned(self.printer_name.into_owned()), locale: Cow::Owned(self.locale.into_owned()), } } } impl<'input> Request for CreateContextRequest<'input> { type Reply = (); } pub fn create_context<'c, 'input, Conn>(conn: &'c Conn, context_id: u32, printer_name: &'input [String8], locale: &'input [String8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateContextRequest { context_id, printer_name: Cow::Borrowed(printer_name), locale: Cow::Borrowed(locale), }; request0.send(conn) } /// Opcode for the PrintSetContext request pub const PRINT_SET_CONTEXT_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintSetContextRequest { pub context: u32, } impl PrintSetContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_SET_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_SET_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(PrintSetContextRequest { context, }) } } impl Request for PrintSetContextRequest { type Reply = (); } pub fn print_set_context(conn: &Conn, context: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintSetContextRequest { context, }; request0.send(conn) } /// Opcode for the PrintGetContext request pub const PRINT_GET_CONTEXT_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetContextRequest; impl PrintGetContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_GET_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(PrintGetContextRequest ) } } impl Request for PrintGetContextRequest { type Reply = PrintGetContextReply; } pub fn print_get_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetContextRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetContextReply { pub sequence: u16, pub length: u32, pub context: u32, } impl TryParse for PrintGetContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PrintDestroyContext request pub const PRINT_DESTROY_CONTEXT_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintDestroyContextRequest { pub context: u32, } impl PrintDestroyContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_DESTROY_CONTEXT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_DESTROY_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(PrintDestroyContextRequest { context, }) } } impl Request for PrintDestroyContextRequest { type Reply = (); } pub fn print_destroy_context(conn: &Conn, context: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintDestroyContextRequest { context, }; request0.send(conn) } /// Opcode for the PrintGetScreenOfContext request pub const PRINT_GET_SCREEN_OF_CONTEXT_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetScreenOfContextRequest; impl PrintGetScreenOfContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_SCREEN_OF_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_GET_SCREEN_OF_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(PrintGetScreenOfContextRequest ) } } impl Request for PrintGetScreenOfContextRequest { type Reply = PrintGetScreenOfContextReply; } pub fn print_get_screen_of_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetScreenOfContextRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetScreenOfContextReply { pub sequence: u16, pub length: u32, pub root: xproto::Window, } impl TryParse for PrintGetScreenOfContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetScreenOfContextReply { sequence, length, root }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PrintStartJob request pub const PRINT_START_JOB_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintStartJobRequest { pub output_mode: u8, } impl PrintStartJobRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let output_mode_bytes = self.output_mode.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_START_JOB_REQUEST, 0, 0, output_mode_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_START_JOB_REQUEST { return Err(ParseError::InvalidValue); } let (output_mode, remaining) = u8::try_parse(value)?; let _ = remaining; Ok(PrintStartJobRequest { output_mode, }) } } impl Request for PrintStartJobRequest { type Reply = (); } pub fn print_start_job(conn: &Conn, output_mode: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintStartJobRequest { output_mode, }; request0.send(conn) } /// Opcode for the PrintEndJob request pub const PRINT_END_JOB_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintEndJobRequest { pub cancel: bool, } impl PrintEndJobRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cancel_bytes = self.cancel.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_END_JOB_REQUEST, 0, 0, cancel_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_END_JOB_REQUEST { return Err(ParseError::InvalidValue); } let (cancel, remaining) = bool::try_parse(value)?; let _ = remaining; Ok(PrintEndJobRequest { cancel, }) } } impl Request for PrintEndJobRequest { type Reply = (); } pub fn print_end_job(conn: &Conn, cancel: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintEndJobRequest { cancel, }; request0.send(conn) } /// Opcode for the PrintStartDoc request pub const PRINT_START_DOC_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintStartDocRequest { pub driver_mode: u8, } impl PrintStartDocRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let driver_mode_bytes = self.driver_mode.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_START_DOC_REQUEST, 0, 0, driver_mode_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_START_DOC_REQUEST { return Err(ParseError::InvalidValue); } let (driver_mode, remaining) = u8::try_parse(value)?; let _ = remaining; Ok(PrintStartDocRequest { driver_mode, }) } } impl Request for PrintStartDocRequest { type Reply = (); } pub fn print_start_doc(conn: &Conn, driver_mode: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintStartDocRequest { driver_mode, }; request0.send(conn) } /// Opcode for the PrintEndDoc request pub const PRINT_END_DOC_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintEndDocRequest { pub cancel: bool, } impl PrintEndDocRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cancel_bytes = self.cancel.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_END_DOC_REQUEST, 0, 0, cancel_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_END_DOC_REQUEST { return Err(ParseError::InvalidValue); } let (cancel, remaining) = bool::try_parse(value)?; let _ = remaining; Ok(PrintEndDocRequest { cancel, }) } } impl Request for PrintEndDocRequest { type Reply = (); } pub fn print_end_doc(conn: &Conn, cancel: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintEndDocRequest { cancel, }; request0.send(conn) } /// Opcode for the PrintPutDocumentData request pub const PRINT_PUT_DOCUMENT_DATA_REQUEST: u8 = 11; #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintPutDocumentDataRequest<'input> { pub drawable: xproto::Drawable, pub data: Cow<'input, [u8]>, pub doc_format: Cow<'input, [String8]>, pub options: Cow<'input, [String8]>, } impl<'input> PrintPutDocumentDataRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let len_data = u32::try_from(self.data.len()).expect("`data` has too many elements"); let len_data_bytes = len_data.serialize(); let len_fmt = u16::try_from(self.doc_format.len()).expect("`doc_format` has too many elements"); let len_fmt_bytes = len_fmt.serialize(); let len_options = u16::try_from(self.options.len()).expect("`options` has too many elements"); let len_options_bytes = len_options.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_PUT_DOCUMENT_DATA_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], len_data_bytes[0], len_data_bytes[1], len_data_bytes[2], len_data_bytes[3], len_fmt_bytes[0], len_fmt_bytes[1], len_options_bytes[0], len_options_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.data.len(); let length_so_far = length_so_far + self.doc_format.len(); let length_so_far = length_so_far + self.options.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, self.doc_format, self.options, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != PRINT_PUT_DOCUMENT_DATA_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (len_data, remaining) = u32::try_parse(remaining)?; let (len_fmt, remaining) = u16::try_parse(remaining)?; let (len_options, remaining) = u16::try_parse(remaining)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, len_data.try_to_usize()?)?; let (doc_format, remaining) = crate::x11_utils::parse_u8_list(remaining, len_fmt.try_to_usize()?)?; let (options, remaining) = crate::x11_utils::parse_u8_list(remaining, len_options.try_to_usize()?)?; let _ = remaining; Ok(PrintPutDocumentDataRequest { drawable, data: Cow::Borrowed(data), doc_format: Cow::Borrowed(doc_format), options: Cow::Borrowed(options), }) } /// Clone all borrowed data in this PrintPutDocumentDataRequest. pub fn into_owned(self) -> PrintPutDocumentDataRequest<'static> { PrintPutDocumentDataRequest { drawable: self.drawable, data: Cow::Owned(self.data.into_owned()), doc_format: Cow::Owned(self.doc_format.into_owned()), options: Cow::Owned(self.options.into_owned()), } } } impl<'input> Request for PrintPutDocumentDataRequest<'input> { type Reply = (); } pub fn print_put_document_data<'c, 'input, Conn>(conn: &'c Conn, drawable: xproto::Drawable, data: &'input [u8], doc_format: &'input [String8], options: &'input [String8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintPutDocumentDataRequest { drawable, data: Cow::Borrowed(data), doc_format: Cow::Borrowed(doc_format), options: Cow::Borrowed(options), }; request0.send(conn) } /// Opcode for the PrintGetDocumentData request pub const PRINT_GET_DOCUMENT_DATA_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetDocumentDataRequest { pub context: Pcontext, pub max_bytes: u32, } impl PrintGetDocumentDataRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let max_bytes_bytes = self.max_bytes.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_DOCUMENT_DATA_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], max_bytes_bytes[0], max_bytes_bytes[1], max_bytes_bytes[2], max_bytes_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_GET_DOCUMENT_DATA_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let (max_bytes, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(PrintGetDocumentDataRequest { context, max_bytes, }) } } impl Request for PrintGetDocumentDataRequest { type Reply = PrintGetDocumentDataReply; } pub fn print_get_document_data(conn: &Conn, context: Pcontext, max_bytes: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetDocumentDataRequest { context, max_bytes, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintGetDocumentDataReply { pub sequence: u16, pub length: u32, pub status_code: u32, pub finished_flag: u32, pub data: Vec, } impl TryParse for PrintGetDocumentDataReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (status_code, remaining) = u32::try_parse(remaining)?; let (finished_flag, remaining) = u32::try_parse(remaining)?; let (data_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, data_len.try_to_usize()?)?; let data = data.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetDocumentDataReply { sequence, length, status_code, finished_flag, data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl PrintGetDocumentDataReply { /// Get the value of the `dataLen` field. /// /// The `dataLen` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn data_len(&self) -> u32 { self.data.len() .try_into().unwrap() } } /// Opcode for the PrintStartPage request pub const PRINT_START_PAGE_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintStartPageRequest { pub window: xproto::Window, } impl PrintStartPageRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_START_PAGE_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_START_PAGE_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(PrintStartPageRequest { window, }) } } impl Request for PrintStartPageRequest { type Reply = (); } pub fn print_start_page(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintStartPageRequest { window, }; request0.send(conn) } /// Opcode for the PrintEndPage request pub const PRINT_END_PAGE_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintEndPageRequest { pub cancel: bool, } impl PrintEndPageRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let cancel_bytes = self.cancel.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_END_PAGE_REQUEST, 0, 0, cancel_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_END_PAGE_REQUEST { return Err(ParseError::InvalidValue); } let (cancel, remaining) = bool::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(PrintEndPageRequest { cancel, }) } } impl Request for PrintEndPageRequest { type Reply = (); } pub fn print_end_page(conn: &Conn, cancel: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintEndPageRequest { cancel, }; request0.send(conn) } /// Opcode for the PrintSelectInput request pub const PRINT_SELECT_INPUT_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintSelectInputRequest { pub context: Pcontext, pub event_mask: u32, } impl PrintSelectInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let event_mask_bytes = self.event_mask.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_SELECT_INPUT_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], event_mask_bytes[0], event_mask_bytes[1], event_mask_bytes[2], event_mask_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_SELECT_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let (event_mask, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(PrintSelectInputRequest { context, event_mask, }) } } impl Request for PrintSelectInputRequest { type Reply = (); } pub fn print_select_input(conn: &Conn, context: Pcontext, event_mask: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintSelectInputRequest { context, event_mask, }; request0.send(conn) } /// Opcode for the PrintInputSelected request pub const PRINT_INPUT_SELECTED_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintInputSelectedRequest { pub context: Pcontext, } impl PrintInputSelectedRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_INPUT_SELECTED_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_INPUT_SELECTED_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let _ = remaining; Ok(PrintInputSelectedRequest { context, }) } } impl Request for PrintInputSelectedRequest { type Reply = PrintInputSelectedReply; } pub fn print_input_selected(conn: &Conn, context: Pcontext) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintInputSelectedRequest { context, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintInputSelectedReply { pub sequence: u16, pub length: u32, pub event_mask: u32, pub all_events_mask: u32, } impl TryParse for PrintInputSelectedReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (event_mask, remaining) = u32::try_parse(remaining)?; let (all_events_mask, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintInputSelectedReply { sequence, length, event_mask, all_events_mask }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PrintGetAttributes request pub const PRINT_GET_ATTRIBUTES_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetAttributesRequest { pub context: Pcontext, pub pool: u8, } impl PrintGetAttributesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let pool_bytes = self.pool.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_ATTRIBUTES_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], pool_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_GET_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let (pool, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(PrintGetAttributesRequest { context, pool, }) } } impl Request for PrintGetAttributesRequest { type Reply = PrintGetAttributesReply; } pub fn print_get_attributes(conn: &Conn, context: Pcontext, pool: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetAttributesRequest { context, pool, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintGetAttributesReply { pub sequence: u16, pub length: u32, pub attributes: Vec, } impl TryParse for PrintGetAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (string_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (attributes, remaining) = crate::x11_utils::parse_u8_list(remaining, string_len.try_to_usize()?)?; let attributes = attributes.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetAttributesReply { sequence, length, attributes }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl PrintGetAttributesReply { /// Get the value of the `stringLen` field. /// /// The `stringLen` field is used as the length field of the `attributes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn string_len(&self) -> u32 { self.attributes.len() .try_into().unwrap() } } /// Opcode for the PrintGetOneAttributes request pub const PRINT_GET_ONE_ATTRIBUTES_REQUEST: u8 = 19; #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintGetOneAttributesRequest<'input> { pub context: Pcontext, pub pool: u8, pub name: Cow<'input, [String8]>, } impl<'input> PrintGetOneAttributesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let name_len = u32::try_from(self.name.len()).expect("`name` has too many elements"); let name_len_bytes = name_len.serialize(); let pool_bytes = self.pool.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_ONE_ATTRIBUTES_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], name_len_bytes[0], name_len_bytes[1], name_len_bytes[2], name_len_bytes[3], pool_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.name.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.name, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != PRINT_GET_ONE_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let (name_len, remaining) = u32::try_parse(remaining)?; let (pool, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_to_usize()?)?; let _ = remaining; Ok(PrintGetOneAttributesRequest { context, pool, name: Cow::Borrowed(name), }) } /// Clone all borrowed data in this PrintGetOneAttributesRequest. pub fn into_owned(self) -> PrintGetOneAttributesRequest<'static> { PrintGetOneAttributesRequest { context: self.context, pool: self.pool, name: Cow::Owned(self.name.into_owned()), } } } impl<'input> Request for PrintGetOneAttributesRequest<'input> { type Reply = PrintGetOneAttributesReply; } pub fn print_get_one_attributes<'c, 'input, Conn>(conn: &'c Conn, context: Pcontext, pool: u8, name: &'input [String8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetOneAttributesRequest { context, pool, name: Cow::Borrowed(name), }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintGetOneAttributesReply { pub sequence: u16, pub length: u32, pub value: Vec, } impl TryParse for PrintGetOneAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (value_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (value, remaining) = crate::x11_utils::parse_u8_list(remaining, value_len.try_to_usize()?)?; let value = value.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetOneAttributesReply { sequence, length, value }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl PrintGetOneAttributesReply { /// Get the value of the `valueLen` field. /// /// The `valueLen` field is used as the length field of the `value` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn value_len(&self) -> u32 { self.value.len() .try_into().unwrap() } } /// Opcode for the PrintSetAttributes request pub const PRINT_SET_ATTRIBUTES_REQUEST: u8 = 18; #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintSetAttributesRequest<'input> { pub context: Pcontext, pub string_len: u32, pub pool: u8, pub rule: u8, pub attributes: Cow<'input, [String8]>, } impl<'input> PrintSetAttributesRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let string_len_bytes = self.string_len.serialize(); let pool_bytes = self.pool.serialize(); let rule_bytes = self.rule.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_SET_ATTRIBUTES_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], string_len_bytes[0], string_len_bytes[1], string_len_bytes[2], string_len_bytes[3], pool_bytes[0], rule_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.attributes.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.attributes, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != PRINT_SET_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let (string_len, remaining) = u32::try_parse(remaining)?; let (pool, remaining) = u8::try_parse(remaining)?; let (rule, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (attributes, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(PrintSetAttributesRequest { context, string_len, pool, rule, attributes: Cow::Borrowed(attributes), }) } /// Clone all borrowed data in this PrintSetAttributesRequest. pub fn into_owned(self) -> PrintSetAttributesRequest<'static> { PrintSetAttributesRequest { context: self.context, string_len: self.string_len, pool: self.pool, rule: self.rule, attributes: Cow::Owned(self.attributes.into_owned()), } } } impl<'input> Request for PrintSetAttributesRequest<'input> { type Reply = (); } pub fn print_set_attributes<'c, 'input, Conn>(conn: &'c Conn, context: Pcontext, string_len: u32, pool: u8, rule: u8, attributes: &'input [String8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintSetAttributesRequest { context, string_len, pool, rule, attributes: Cow::Borrowed(attributes), }; request0.send(conn) } /// Opcode for the PrintGetPageDimensions request pub const PRINT_GET_PAGE_DIMENSIONS_REQUEST: u8 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetPageDimensionsRequest { pub context: Pcontext, } impl PrintGetPageDimensionsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_PAGE_DIMENSIONS_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_GET_PAGE_DIMENSIONS_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let _ = remaining; Ok(PrintGetPageDimensionsRequest { context, }) } } impl Request for PrintGetPageDimensionsRequest { type Reply = PrintGetPageDimensionsReply; } pub fn print_get_page_dimensions(conn: &Conn, context: Pcontext) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetPageDimensionsRequest { context, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetPageDimensionsReply { pub sequence: u16, pub length: u32, pub width: u16, pub height: u16, pub offset_x: u16, pub offset_y: u16, pub reproducible_width: u16, pub reproducible_height: u16, } impl TryParse for PrintGetPageDimensionsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (offset_x, remaining) = u16::try_parse(remaining)?; let (offset_y, remaining) = u16::try_parse(remaining)?; let (reproducible_width, remaining) = u16::try_parse(remaining)?; let (reproducible_height, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetPageDimensionsReply { sequence, length, width, height, offset_x, offset_y, reproducible_width, reproducible_height }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PrintQueryScreens request pub const PRINT_QUERY_SCREENS_REQUEST: u8 = 22; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintQueryScreensRequest; impl PrintQueryScreensRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, PRINT_QUERY_SCREENS_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_QUERY_SCREENS_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(PrintQueryScreensRequest ) } } impl Request for PrintQueryScreensRequest { type Reply = PrintQueryScreensReply; } pub fn print_query_screens(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintQueryScreensRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct PrintQueryScreensReply { pub sequence: u16, pub length: u32, pub roots: Vec, } impl TryParse for PrintQueryScreensReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (list_count, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (roots, remaining) = crate::x11_utils::parse_list::(remaining, list_count.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintQueryScreensReply { sequence, length, roots }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl PrintQueryScreensReply { /// Get the value of the `listCount` field. /// /// The `listCount` field is used as the length field of the `roots` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn list_count(&self) -> u32 { self.roots.len() .try_into().unwrap() } } /// Opcode for the PrintSetImageResolution request pub const PRINT_SET_IMAGE_RESOLUTION_REQUEST: u8 = 23; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintSetImageResolutionRequest { pub context: Pcontext, pub image_resolution: u16, } impl PrintSetImageResolutionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let image_resolution_bytes = self.image_resolution.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_SET_IMAGE_RESOLUTION_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], image_resolution_bytes[0], image_resolution_bytes[1], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_SET_IMAGE_RESOLUTION_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let (image_resolution, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(PrintSetImageResolutionRequest { context, image_resolution, }) } } impl Request for PrintSetImageResolutionRequest { type Reply = PrintSetImageResolutionReply; } pub fn print_set_image_resolution(conn: &Conn, context: Pcontext, image_resolution: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintSetImageResolutionRequest { context, image_resolution, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintSetImageResolutionReply { pub status: bool, pub sequence: u16, pub length: u32, pub previous_resolutions: u16, } impl TryParse for PrintSetImageResolutionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (previous_resolutions, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintSetImageResolutionReply { status, sequence, length, previous_resolutions }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the PrintGetImageResolution request pub const PRINT_GET_IMAGE_RESOLUTION_REQUEST: u8 = 24; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetImageResolutionRequest { pub context: Pcontext, } impl PrintGetImageResolutionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_bytes = self.context.serialize(); let mut request0 = vec![ extension_information.major_opcode, PRINT_GET_IMAGE_RESOLUTION_REQUEST, 0, 0, context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PRINT_GET_IMAGE_RESOLUTION_REQUEST { return Err(ParseError::InvalidValue); } let (context, remaining) = Pcontext::try_parse(value)?; let _ = remaining; Ok(PrintGetImageResolutionRequest { context, }) } } impl Request for PrintGetImageResolutionRequest { type Reply = PrintGetImageResolutionReply; } pub fn print_get_image_resolution(conn: &Conn, context: Pcontext) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PrintGetImageResolutionRequest { context, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PrintGetImageResolutionReply { pub sequence: u16, pub length: u32, pub image_resolution: u16, } impl TryParse for PrintGetImageResolutionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (image_resolution, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = PrintGetImageResolutionReply { sequence, length, image_resolution }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the Notify event pub const NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NotifyEvent { pub response_type: u8, pub detail: u8, pub sequence: u16, pub context: Pcontext, pub cancel: bool, } impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (context, remaining) = Pcontext::try_parse(remaining)?; let (cancel, remaining) = bool::try_parse(remaining)?; let result = NotifyEvent { response_type, detail, sequence, context, cancel }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NotifyEvent> for [u8; 32] { fn from(input: &NotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = input.detail.serialize(); let sequence_bytes = input.sequence.serialize(); let context_bytes = input.context.serialize(); let cancel_bytes = input.cancel.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], cancel_bytes[0], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: NotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the AttributNotify event pub const ATTRIBUT_NOTIFY_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AttributNotifyEvent { pub response_type: u8, pub detail: u8, pub sequence: u16, pub context: Pcontext, } impl TryParse for AttributNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (context, remaining) = Pcontext::try_parse(remaining)?; let result = AttributNotifyEvent { response_type, detail, sequence, context }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&AttributNotifyEvent> for [u8; 32] { fn from(input: &AttributNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = input.detail.serialize(); let sequence_bytes = input.sequence.serialize(); let context_bytes = input.context.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: AttributNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the BadContext error pub const BAD_CONTEXT_ERROR: u8 = 0; /// Opcode for the BadSequence error pub const BAD_SEQUENCE_ERROR: u8 = 1; /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xprint_print_query_version(&self) -> Result, ConnectionError> { print_query_version(self) } fn xprint_print_get_printer_list<'c, 'input>(&'c self, printer_name: &'input [String8], locale: &'input [String8]) -> Result, ConnectionError> { print_get_printer_list(self, printer_name, locale) } fn xprint_print_rehash_printer_list(&self) -> Result, ConnectionError> { print_rehash_printer_list(self) } fn xprint_create_context<'c, 'input>(&'c self, context_id: u32, printer_name: &'input [String8], locale: &'input [String8]) -> Result, ConnectionError> { create_context(self, context_id, printer_name, locale) } fn xprint_print_set_context(&self, context: u32) -> Result, ConnectionError> { print_set_context(self, context) } fn xprint_print_get_context(&self) -> Result, ConnectionError> { print_get_context(self) } fn xprint_print_destroy_context(&self, context: u32) -> Result, ConnectionError> { print_destroy_context(self, context) } fn xprint_print_get_screen_of_context(&self) -> Result, ConnectionError> { print_get_screen_of_context(self) } fn xprint_print_start_job(&self, output_mode: u8) -> Result, ConnectionError> { print_start_job(self, output_mode) } fn xprint_print_end_job(&self, cancel: bool) -> Result, ConnectionError> { print_end_job(self, cancel) } fn xprint_print_start_doc(&self, driver_mode: u8) -> Result, ConnectionError> { print_start_doc(self, driver_mode) } fn xprint_print_end_doc(&self, cancel: bool) -> Result, ConnectionError> { print_end_doc(self, cancel) } fn xprint_print_put_document_data<'c, 'input>(&'c self, drawable: xproto::Drawable, data: &'input [u8], doc_format: &'input [String8], options: &'input [String8]) -> Result, ConnectionError> { print_put_document_data(self, drawable, data, doc_format, options) } fn xprint_print_get_document_data(&self, context: Pcontext, max_bytes: u32) -> Result, ConnectionError> { print_get_document_data(self, context, max_bytes) } fn xprint_print_start_page(&self, window: xproto::Window) -> Result, ConnectionError> { print_start_page(self, window) } fn xprint_print_end_page(&self, cancel: bool) -> Result, ConnectionError> { print_end_page(self, cancel) } fn xprint_print_select_input(&self, context: Pcontext, event_mask: u32) -> Result, ConnectionError> { print_select_input(self, context, event_mask) } fn xprint_print_input_selected(&self, context: Pcontext) -> Result, ConnectionError> { print_input_selected(self, context) } fn xprint_print_get_attributes(&self, context: Pcontext, pool: u8) -> Result, ConnectionError> { print_get_attributes(self, context, pool) } fn xprint_print_get_one_attributes<'c, 'input>(&'c self, context: Pcontext, pool: u8, name: &'input [String8]) -> Result, ConnectionError> { print_get_one_attributes(self, context, pool, name) } fn xprint_print_set_attributes<'c, 'input>(&'c self, context: Pcontext, string_len: u32, pool: u8, rule: u8, attributes: &'input [String8]) -> Result, ConnectionError> { print_set_attributes(self, context, string_len, pool, rule, attributes) } fn xprint_print_get_page_dimensions(&self, context: Pcontext) -> Result, ConnectionError> { print_get_page_dimensions(self, context) } fn xprint_print_query_screens(&self) -> Result, ConnectionError> { print_query_screens(self) } fn xprint_print_set_image_resolution(&self, context: Pcontext, image_resolution: u16) -> Result, ConnectionError> { print_set_image_resolution(self, context, image_resolution) } fn xprint_print_get_image_resolution(&self, context: Pcontext) -> Result, ConnectionError> { print_get_image_resolution(self, context) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xproto.rs010064400017500001750000036642501402220031600151750ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the core X11 protocol. //! //! For more documentation on the X11 protocol, see the //! [protocol reference manual](https://www.x.org/releases/X11R7.6/doc/xproto/x11protocol.html). //! This is especially recommended for looking up the exact semantics of //! specific errors, events, or requests. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::cookie::ListFontsWithInfoCookie; use crate::errors::{ConnectionError, ParseError}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Char2b { pub byte1: u8, pub byte2: u8, } impl TryParse for Char2b { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (byte1, remaining) = u8::try_parse(remaining)?; let (byte2, remaining) = u8::try_parse(remaining)?; let result = Char2b { byte1, byte2 }; Ok((result, remaining)) } } impl Serialize for Char2b { type Bytes = [u8; 2]; fn serialize(&self) -> [u8; 2] { let byte1_bytes = self.byte1.serialize(); let byte2_bytes = self.byte2.serialize(); [ byte1_bytes[0], byte2_bytes[0], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(2); self.byte1.serialize_into(bytes); self.byte2.serialize_into(bytes); } } pub type Window = u32; pub type Pixmap = u32; pub type Cursor = u32; pub type Font = u32; pub type Gcontext = u32; pub type Colormap = u32; pub type Atom = u32; pub type Drawable = u32; pub type Fontable = u32; pub type Bool32 = u32; pub type Visualid = u32; pub type Timestamp = u32; pub type Keysym = u32; pub type Keycode = u8; pub type Keycode32 = u32; pub type Button = u8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Point { pub x: i16, pub y: i16, } impl TryParse for Point { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let result = Point { x, y }; Ok((result, remaining)) } } impl Serialize for Point { type Bytes = [u8; 4]; fn serialize(&self) -> [u8; 4] { let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); [ x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(4); self.x.serialize_into(bytes); self.y.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Rectangle { pub x: i16, pub y: i16, pub width: u16, pub height: u16, } impl TryParse for Rectangle { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let result = Rectangle { x, y, width, height }; Ok((result, remaining)) } } impl Serialize for Rectangle { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); [ x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.x.serialize_into(bytes); self.y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Arc { pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub angle1: i16, pub angle2: i16, } impl TryParse for Arc { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (angle1, remaining) = i16::try_parse(remaining)?; let (angle2, remaining) = i16::try_parse(remaining)?; let result = Arc { x, y, width, height, angle1, angle2 }; Ok((result, remaining)) } } impl Serialize for Arc { type Bytes = [u8; 12]; fn serialize(&self) -> [u8; 12] { let x_bytes = self.x.serialize(); let y_bytes = self.y.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let angle1_bytes = self.angle1.serialize(); let angle2_bytes = self.angle2.serialize(); [ x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], angle1_bytes[0], angle1_bytes[1], angle2_bytes[0], angle2_bytes[1], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.x.serialize_into(bytes); self.y.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); self.angle1.serialize_into(bytes); self.angle2.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Format { pub depth: u8, pub bits_per_pixel: u8, pub scanline_pad: u8, } impl TryParse for Format { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (depth, remaining) = u8::try_parse(remaining)?; let (bits_per_pixel, remaining) = u8::try_parse(remaining)?; let (scanline_pad, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(5..).ok_or(ParseError::InsufficientData)?; let result = Format { depth, bits_per_pixel, scanline_pad }; Ok((result, remaining)) } } impl Serialize for Format { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let depth_bytes = self.depth.serialize(); let bits_per_pixel_bytes = self.bits_per_pixel.serialize(); let scanline_pad_bytes = self.scanline_pad.serialize(); [ depth_bytes[0], bits_per_pixel_bytes[0], scanline_pad_bytes[0], 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.depth.serialize_into(bytes); self.bits_per_pixel.serialize_into(bytes); self.scanline_pad.serialize_into(bytes); bytes.extend_from_slice(&[0; 5]); } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct VisualClass(u8); impl VisualClass { pub const STATIC_GRAY: Self = Self(0); pub const GRAY_SCALE: Self = Self(1); pub const STATIC_COLOR: Self = Self(2); pub const PSEUDO_COLOR: Self = Self(3); pub const TRUE_COLOR: Self = Self(4); pub const DIRECT_COLOR: Self = Self(5); } impl From for u8 { #[inline] fn from(input: VisualClass) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: VisualClass) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: VisualClass) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: VisualClass) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: VisualClass) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: VisualClass) -> Self { Some(u32::from(input.0)) } } impl From for VisualClass { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for VisualClass { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::STATIC_GRAY.0.into(), "STATIC_GRAY", "StaticGray"), (Self::GRAY_SCALE.0.into(), "GRAY_SCALE", "GrayScale"), (Self::STATIC_COLOR.0.into(), "STATIC_COLOR", "StaticColor"), (Self::PSEUDO_COLOR.0.into(), "PSEUDO_COLOR", "PseudoColor"), (Self::TRUE_COLOR.0.into(), "TRUE_COLOR", "TrueColor"), (Self::DIRECT_COLOR.0.into(), "DIRECT_COLOR", "DirectColor"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Visualtype { pub visual_id: Visualid, pub class: VisualClass, pub bits_per_rgb_value: u8, pub colormap_entries: u16, pub red_mask: u32, pub green_mask: u32, pub blue_mask: u32, } impl TryParse for Visualtype { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (visual_id, remaining) = Visualid::try_parse(remaining)?; let (class, remaining) = u8::try_parse(remaining)?; let (bits_per_rgb_value, remaining) = u8::try_parse(remaining)?; let (colormap_entries, remaining) = u16::try_parse(remaining)?; let (red_mask, remaining) = u32::try_parse(remaining)?; let (green_mask, remaining) = u32::try_parse(remaining)?; let (blue_mask, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let class = class.into(); let result = Visualtype { visual_id, class, bits_per_rgb_value, colormap_entries, red_mask, green_mask, blue_mask }; Ok((result, remaining)) } } impl Serialize for Visualtype { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let visual_id_bytes = self.visual_id.serialize(); let class_bytes = u8::from(self.class).serialize(); let bits_per_rgb_value_bytes = self.bits_per_rgb_value.serialize(); let colormap_entries_bytes = self.colormap_entries.serialize(); let red_mask_bytes = self.red_mask.serialize(); let green_mask_bytes = self.green_mask.serialize(); let blue_mask_bytes = self.blue_mask.serialize(); [ visual_id_bytes[0], visual_id_bytes[1], visual_id_bytes[2], visual_id_bytes[3], class_bytes[0], bits_per_rgb_value_bytes[0], colormap_entries_bytes[0], colormap_entries_bytes[1], red_mask_bytes[0], red_mask_bytes[1], red_mask_bytes[2], red_mask_bytes[3], green_mask_bytes[0], green_mask_bytes[1], green_mask_bytes[2], green_mask_bytes[3], blue_mask_bytes[0], blue_mask_bytes[1], blue_mask_bytes[2], blue_mask_bytes[3], 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.visual_id.serialize_into(bytes); u8::from(self.class).serialize_into(bytes); self.bits_per_rgb_value.serialize_into(bytes); self.colormap_entries.serialize_into(bytes); self.red_mask.serialize_into(bytes); self.green_mask.serialize_into(bytes); self.blue_mask.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Depth { pub depth: u8, pub visuals: Vec, } impl TryParse for Depth { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (visuals_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (visuals, remaining) = crate::x11_utils::parse_list::(remaining, visuals_len.try_to_usize()?)?; let result = Depth { depth, visuals }; Ok((result, remaining)) } } impl Serialize for Depth { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.depth.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); let visuals_len = u16::try_from(self.visuals.len()).expect("`visuals` has too many elements"); visuals_len.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); self.visuals.serialize_into(bytes); } } impl Depth { /// Get the value of the `visuals_len` field. /// /// The `visuals_len` field is used as the length field of the `visuals` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn visuals_len(&self) -> u16 { self.visuals.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct EventMask(u32); impl EventMask { pub const NO_EVENT: Self = Self(0); pub const KEY_PRESS: Self = Self(1 << 0); pub const KEY_RELEASE: Self = Self(1 << 1); pub const BUTTON_PRESS: Self = Self(1 << 2); pub const BUTTON_RELEASE: Self = Self(1 << 3); pub const ENTER_WINDOW: Self = Self(1 << 4); pub const LEAVE_WINDOW: Self = Self(1 << 5); pub const POINTER_MOTION: Self = Self(1 << 6); pub const POINTER_MOTION_HINT: Self = Self(1 << 7); pub const BUTTON1_MOTION: Self = Self(1 << 8); pub const BUTTON2_MOTION: Self = Self(1 << 9); pub const BUTTON3_MOTION: Self = Self(1 << 10); pub const BUTTON4_MOTION: Self = Self(1 << 11); pub const BUTTON5_MOTION: Self = Self(1 << 12); pub const BUTTON_MOTION: Self = Self(1 << 13); pub const KEYMAP_STATE: Self = Self(1 << 14); pub const EXPOSURE: Self = Self(1 << 15); pub const VISIBILITY_CHANGE: Self = Self(1 << 16); pub const STRUCTURE_NOTIFY: Self = Self(1 << 17); pub const RESIZE_REDIRECT: Self = Self(1 << 18); pub const SUBSTRUCTURE_NOTIFY: Self = Self(1 << 19); pub const SUBSTRUCTURE_REDIRECT: Self = Self(1 << 20); pub const FOCUS_CHANGE: Self = Self(1 << 21); pub const PROPERTY_CHANGE: Self = Self(1 << 22); pub const COLOR_MAP_CHANGE: Self = Self(1 << 23); pub const OWNER_GRAB_BUTTON: Self = Self(1 << 24); } impl From for u32 { #[inline] fn from(input: EventMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: EventMask) -> Self { Some(input.0) } } impl From for EventMask { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for EventMask { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for EventMask { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for EventMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NO_EVENT.0, "NO_EVENT", "NoEvent"), (Self::KEY_PRESS.0, "KEY_PRESS", "KeyPress"), (Self::KEY_RELEASE.0, "KEY_RELEASE", "KeyRelease"), (Self::BUTTON_PRESS.0, "BUTTON_PRESS", "ButtonPress"), (Self::BUTTON_RELEASE.0, "BUTTON_RELEASE", "ButtonRelease"), (Self::ENTER_WINDOW.0, "ENTER_WINDOW", "EnterWindow"), (Self::LEAVE_WINDOW.0, "LEAVE_WINDOW", "LeaveWindow"), (Self::POINTER_MOTION.0, "POINTER_MOTION", "PointerMotion"), (Self::POINTER_MOTION_HINT.0, "POINTER_MOTION_HINT", "PointerMotionHint"), (Self::BUTTON1_MOTION.0, "BUTTON1_MOTION", "Button1Motion"), (Self::BUTTON2_MOTION.0, "BUTTON2_MOTION", "Button2Motion"), (Self::BUTTON3_MOTION.0, "BUTTON3_MOTION", "Button3Motion"), (Self::BUTTON4_MOTION.0, "BUTTON4_MOTION", "Button4Motion"), (Self::BUTTON5_MOTION.0, "BUTTON5_MOTION", "Button5Motion"), (Self::BUTTON_MOTION.0, "BUTTON_MOTION", "ButtonMotion"), (Self::KEYMAP_STATE.0, "KEYMAP_STATE", "KeymapState"), (Self::EXPOSURE.0, "EXPOSURE", "Exposure"), (Self::VISIBILITY_CHANGE.0, "VISIBILITY_CHANGE", "VisibilityChange"), (Self::STRUCTURE_NOTIFY.0, "STRUCTURE_NOTIFY", "StructureNotify"), (Self::RESIZE_REDIRECT.0, "RESIZE_REDIRECT", "ResizeRedirect"), (Self::SUBSTRUCTURE_NOTIFY.0, "SUBSTRUCTURE_NOTIFY", "SubstructureNotify"), (Self::SUBSTRUCTURE_REDIRECT.0, "SUBSTRUCTURE_REDIRECT", "SubstructureRedirect"), (Self::FOCUS_CHANGE.0, "FOCUS_CHANGE", "FocusChange"), (Self::PROPERTY_CHANGE.0, "PROPERTY_CHANGE", "PropertyChange"), (Self::COLOR_MAP_CHANGE.0, "COLOR_MAP_CHANGE", "ColorMapChange"), (Self::OWNER_GRAB_BUTTON.0, "OWNER_GRAB_BUTTON", "OwnerGrabButton"), ]; pretty_print_bitmask(fmt, self.0, &variants) } } bitmask_binop!(EventMask, u32); #[derive(Clone, Copy, PartialEq, Eq)] pub struct BackingStore(u32); impl BackingStore { pub const NOT_USEFUL: Self = Self(0); pub const WHEN_MAPPED: Self = Self(1); pub const ALWAYS: Self = Self(2); } impl From for u32 { #[inline] fn from(input: BackingStore) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: BackingStore) -> Self { Some(input.0) } } impl From for BackingStore { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for BackingStore { #[inline] fn from(value: u16) -> Self { Self(value.into()) } } impl From for BackingStore { #[inline] fn from(value: u32) -> Self { Self(value) } } impl std::fmt::Debug for BackingStore { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NOT_USEFUL.0, "NOT_USEFUL", "NotUseful"), (Self::WHEN_MAPPED.0, "WHEN_MAPPED", "WhenMapped"), (Self::ALWAYS.0, "ALWAYS", "Always"), ]; pretty_print_enum(fmt, self.0, &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Screen { pub root: Window, pub default_colormap: Colormap, pub white_pixel: u32, pub black_pixel: u32, pub current_input_masks: u32, pub width_in_pixels: u16, pub height_in_pixels: u16, pub width_in_millimeters: u16, pub height_in_millimeters: u16, pub min_installed_maps: u16, pub max_installed_maps: u16, pub root_visual: Visualid, pub backing_stores: BackingStore, pub save_unders: bool, pub root_depth: u8, pub allowed_depths: Vec, } impl TryParse for Screen { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (root, remaining) = Window::try_parse(remaining)?; let (default_colormap, remaining) = Colormap::try_parse(remaining)?; let (white_pixel, remaining) = u32::try_parse(remaining)?; let (black_pixel, remaining) = u32::try_parse(remaining)?; let (current_input_masks, remaining) = u32::try_parse(remaining)?; let (width_in_pixels, remaining) = u16::try_parse(remaining)?; let (height_in_pixels, remaining) = u16::try_parse(remaining)?; let (width_in_millimeters, remaining) = u16::try_parse(remaining)?; let (height_in_millimeters, remaining) = u16::try_parse(remaining)?; let (min_installed_maps, remaining) = u16::try_parse(remaining)?; let (max_installed_maps, remaining) = u16::try_parse(remaining)?; let (root_visual, remaining) = Visualid::try_parse(remaining)?; let (backing_stores, remaining) = u8::try_parse(remaining)?; let (save_unders, remaining) = bool::try_parse(remaining)?; let (root_depth, remaining) = u8::try_parse(remaining)?; let (allowed_depths_len, remaining) = u8::try_parse(remaining)?; let (allowed_depths, remaining) = crate::x11_utils::parse_list::(remaining, allowed_depths_len.try_to_usize()?)?; let backing_stores = backing_stores.into(); let result = Screen { root, default_colormap, white_pixel, black_pixel, current_input_masks, width_in_pixels, height_in_pixels, width_in_millimeters, height_in_millimeters, min_installed_maps, max_installed_maps, root_visual, backing_stores, save_unders, root_depth, allowed_depths }; Ok((result, remaining)) } } impl Serialize for Screen { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(40); self.root.serialize_into(bytes); self.default_colormap.serialize_into(bytes); self.white_pixel.serialize_into(bytes); self.black_pixel.serialize_into(bytes); self.current_input_masks.serialize_into(bytes); self.width_in_pixels.serialize_into(bytes); self.height_in_pixels.serialize_into(bytes); self.width_in_millimeters.serialize_into(bytes); self.height_in_millimeters.serialize_into(bytes); self.min_installed_maps.serialize_into(bytes); self.max_installed_maps.serialize_into(bytes); self.root_visual.serialize_into(bytes); (u32::from(self.backing_stores) as u8).serialize_into(bytes); self.save_unders.serialize_into(bytes); self.root_depth.serialize_into(bytes); let allowed_depths_len = u8::try_from(self.allowed_depths.len()).expect("`allowed_depths` has too many elements"); allowed_depths_len.serialize_into(bytes); self.allowed_depths.serialize_into(bytes); } } impl Screen { /// Get the value of the `allowed_depths_len` field. /// /// The `allowed_depths_len` field is used as the length field of the `allowed_depths` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn allowed_depths_len(&self) -> u8 { self.allowed_depths.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetupRequest { pub byte_order: u8, pub protocol_major_version: u16, pub protocol_minor_version: u16, pub authorization_protocol_name: Vec, pub authorization_protocol_data: Vec, } impl TryParse for SetupRequest { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (byte_order, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (protocol_major_version, remaining) = u16::try_parse(remaining)?; let (protocol_minor_version, remaining) = u16::try_parse(remaining)?; let (authorization_protocol_name_len, remaining) = u16::try_parse(remaining)?; let (authorization_protocol_data_len, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (authorization_protocol_name, remaining) = crate::x11_utils::parse_u8_list(remaining, authorization_protocol_name_len.try_to_usize()?)?; let authorization_protocol_name = authorization_protocol_name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (authorization_protocol_data, remaining) = crate::x11_utils::parse_u8_list(remaining, authorization_protocol_data_len.try_to_usize()?)?; let authorization_protocol_data = authorization_protocol_data.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = SetupRequest { byte_order, protocol_major_version, protocol_minor_version, authorization_protocol_name, authorization_protocol_data }; Ok((result, remaining)) } } impl Serialize for SetupRequest { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.byte_order.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.protocol_major_version.serialize_into(bytes); self.protocol_minor_version.serialize_into(bytes); let authorization_protocol_name_len = u16::try_from(self.authorization_protocol_name.len()).expect("`authorization_protocol_name` has too many elements"); authorization_protocol_name_len.serialize_into(bytes); let authorization_protocol_data_len = u16::try_from(self.authorization_protocol_data.len()).expect("`authorization_protocol_data` has too many elements"); authorization_protocol_data_len.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); bytes.extend_from_slice(&self.authorization_protocol_name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); bytes.extend_from_slice(&self.authorization_protocol_data); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl SetupRequest { /// Get the value of the `authorization_protocol_name_len` field. /// /// The `authorization_protocol_name_len` field is used as the length field of the `authorization_protocol_name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn authorization_protocol_name_len(&self) -> u16 { self.authorization_protocol_name.len() .try_into().unwrap() } /// Get the value of the `authorization_protocol_data_len` field. /// /// The `authorization_protocol_data_len` field is used as the length field of the `authorization_protocol_data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn authorization_protocol_data_len(&self) -> u16 { self.authorization_protocol_data.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetupFailed { pub status: u8, pub protocol_major_version: u16, pub protocol_minor_version: u16, pub length: u16, pub reason: Vec, } impl TryParse for SetupFailed { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (status, remaining) = u8::try_parse(remaining)?; let (reason_len, remaining) = u8::try_parse(remaining)?; let (protocol_major_version, remaining) = u16::try_parse(remaining)?; let (protocol_minor_version, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u16::try_parse(remaining)?; let (reason, remaining) = crate::x11_utils::parse_u8_list(remaining, reason_len.try_to_usize()?)?; let reason = reason.to_vec(); let result = SetupFailed { status, protocol_major_version, protocol_minor_version, length, reason }; Ok((result, remaining)) } } impl Serialize for SetupFailed { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.status.serialize_into(bytes); let reason_len = u8::try_from(self.reason.len()).expect("`reason` has too many elements"); reason_len.serialize_into(bytes); self.protocol_major_version.serialize_into(bytes); self.protocol_minor_version.serialize_into(bytes); self.length.serialize_into(bytes); bytes.extend_from_slice(&self.reason); } } impl SetupFailed { /// Get the value of the `reason_len` field. /// /// The `reason_len` field is used as the length field of the `reason` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn reason_len(&self) -> u8 { self.reason.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetupAuthenticate { pub status: u8, pub reason: Vec, } impl TryParse for SetupAuthenticate { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(5..).ok_or(ParseError::InsufficientData)?; let (length, remaining) = u16::try_parse(remaining)?; let (reason, remaining) = crate::x11_utils::parse_u8_list(remaining, u32::from(length).checked_mul(4u32).ok_or(ParseError::InvalidExpression)?.try_to_usize()?)?; let reason = reason.to_vec(); let result = SetupAuthenticate { status, reason }; Ok((result, remaining)) } } impl Serialize for SetupAuthenticate { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.status.serialize_into(bytes); bytes.extend_from_slice(&[0; 5]); assert_eq!(self.reason.len() % 4, 0, "`reason` has an incorrect length, must be a multiple of 4"); let length = u16::try_from(self.reason.len() / 4).expect("`reason` has too many elements"); length.serialize_into(bytes); bytes.extend_from_slice(&self.reason); } } impl SetupAuthenticate { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `reason` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u16 { self.reason.len() .checked_div(4).unwrap() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ImageOrder(u8); impl ImageOrder { pub const LSB_FIRST: Self = Self(0); pub const MSB_FIRST: Self = Self(1); } impl From for u8 { #[inline] fn from(input: ImageOrder) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ImageOrder) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ImageOrder) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ImageOrder) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ImageOrder) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ImageOrder) -> Self { Some(u32::from(input.0)) } } impl From for ImageOrder { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ImageOrder { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::LSB_FIRST.0.into(), "LSB_FIRST", "LSBFirst"), (Self::MSB_FIRST.0.into(), "MSB_FIRST", "MSBFirst"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Setup { pub status: u8, pub protocol_major_version: u16, pub protocol_minor_version: u16, pub length: u16, pub release_number: u32, pub resource_id_base: u32, pub resource_id_mask: u32, pub motion_buffer_size: u32, pub maximum_request_length: u16, pub image_byte_order: ImageOrder, pub bitmap_format_bit_order: ImageOrder, pub bitmap_format_scanline_unit: u8, pub bitmap_format_scanline_pad: u8, pub min_keycode: Keycode, pub max_keycode: Keycode, pub vendor: Vec, pub pixmap_formats: Vec, pub roots: Vec, } impl TryParse for Setup { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (protocol_major_version, remaining) = u16::try_parse(remaining)?; let (protocol_minor_version, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u16::try_parse(remaining)?; let (release_number, remaining) = u32::try_parse(remaining)?; let (resource_id_base, remaining) = u32::try_parse(remaining)?; let (resource_id_mask, remaining) = u32::try_parse(remaining)?; let (motion_buffer_size, remaining) = u32::try_parse(remaining)?; let (vendor_len, remaining) = u16::try_parse(remaining)?; let (maximum_request_length, remaining) = u16::try_parse(remaining)?; let (roots_len, remaining) = u8::try_parse(remaining)?; let (pixmap_formats_len, remaining) = u8::try_parse(remaining)?; let (image_byte_order, remaining) = u8::try_parse(remaining)?; let (bitmap_format_bit_order, remaining) = u8::try_parse(remaining)?; let (bitmap_format_scanline_unit, remaining) = u8::try_parse(remaining)?; let (bitmap_format_scanline_pad, remaining) = u8::try_parse(remaining)?; let (min_keycode, remaining) = Keycode::try_parse(remaining)?; let (max_keycode, remaining) = Keycode::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (vendor, remaining) = crate::x11_utils::parse_u8_list(remaining, vendor_len.try_to_usize()?)?; let vendor = vendor.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (pixmap_formats, remaining) = crate::x11_utils::parse_list::(remaining, pixmap_formats_len.try_to_usize()?)?; let (roots, remaining) = crate::x11_utils::parse_list::(remaining, roots_len.try_to_usize()?)?; let image_byte_order = image_byte_order.into(); let bitmap_format_bit_order = bitmap_format_bit_order.into(); let result = Setup { status, protocol_major_version, protocol_minor_version, length, release_number, resource_id_base, resource_id_mask, motion_buffer_size, maximum_request_length, image_byte_order, bitmap_format_bit_order, bitmap_format_scanline_unit, bitmap_format_scanline_pad, min_keycode, max_keycode, vendor, pixmap_formats, roots }; Ok((result, remaining)) } } impl Serialize for Setup { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(40); self.status.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); self.protocol_major_version.serialize_into(bytes); self.protocol_minor_version.serialize_into(bytes); self.length.serialize_into(bytes); self.release_number.serialize_into(bytes); self.resource_id_base.serialize_into(bytes); self.resource_id_mask.serialize_into(bytes); self.motion_buffer_size.serialize_into(bytes); let vendor_len = u16::try_from(self.vendor.len()).expect("`vendor` has too many elements"); vendor_len.serialize_into(bytes); self.maximum_request_length.serialize_into(bytes); let roots_len = u8::try_from(self.roots.len()).expect("`roots` has too many elements"); roots_len.serialize_into(bytes); let pixmap_formats_len = u8::try_from(self.pixmap_formats.len()).expect("`pixmap_formats` has too many elements"); pixmap_formats_len.serialize_into(bytes); u8::from(self.image_byte_order).serialize_into(bytes); u8::from(self.bitmap_format_bit_order).serialize_into(bytes); self.bitmap_format_scanline_unit.serialize_into(bytes); self.bitmap_format_scanline_pad.serialize_into(bytes); self.min_keycode.serialize_into(bytes); self.max_keycode.serialize_into(bytes); bytes.extend_from_slice(&[0; 4]); bytes.extend_from_slice(&self.vendor); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); self.pixmap_formats.serialize_into(bytes); self.roots.serialize_into(bytes); } } impl Setup { /// Get the value of the `vendor_len` field. /// /// The `vendor_len` field is used as the length field of the `vendor` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn vendor_len(&self) -> u16 { self.vendor.len() .try_into().unwrap() } /// Get the value of the `roots_len` field. /// /// The `roots_len` field is used as the length field of the `roots` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn roots_len(&self) -> u8 { self.roots.len() .try_into().unwrap() } /// Get the value of the `pixmap_formats_len` field. /// /// The `pixmap_formats_len` field is used as the length field of the `pixmap_formats` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn pixmap_formats_len(&self) -> u8 { self.pixmap_formats.len() .try_into().unwrap() } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ModMask(u16); impl ModMask { pub const SHIFT: Self = Self(1 << 0); pub const LOCK: Self = Self(1 << 1); pub const CONTROL: Self = Self(1 << 2); pub const M1: Self = Self(1 << 3); pub const M2: Self = Self(1 << 4); pub const M3: Self = Self(1 << 5); pub const M4: Self = Self(1 << 6); pub const M5: Self = Self(1 << 7); pub const ANY: Self = Self(1 << 15); } impl From for u16 { #[inline] fn from(input: ModMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ModMask) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: ModMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ModMask) -> Self { Some(u32::from(input.0)) } } impl From for ModMask { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for ModMask { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for ModMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SHIFT.0.into(), "SHIFT", "Shift"), (Self::LOCK.0.into(), "LOCK", "Lock"), (Self::CONTROL.0.into(), "CONTROL", "Control"), (Self::M1.0.into(), "M1", "M1"), (Self::M2.0.into(), "M2", "M2"), (Self::M3.0.into(), "M3", "M3"), (Self::M4.0.into(), "M4", "M4"), (Self::M5.0.into(), "M5", "M5"), (Self::ANY.0.into(), "ANY", "Any"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ModMask, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct KeyButMask(u16); impl KeyButMask { pub const SHIFT: Self = Self(1 << 0); pub const LOCK: Self = Self(1 << 1); pub const CONTROL: Self = Self(1 << 2); pub const MOD1: Self = Self(1 << 3); pub const MOD2: Self = Self(1 << 4); pub const MOD3: Self = Self(1 << 5); pub const MOD4: Self = Self(1 << 6); pub const MOD5: Self = Self(1 << 7); pub const BUTTON1: Self = Self(1 << 8); pub const BUTTON2: Self = Self(1 << 9); pub const BUTTON3: Self = Self(1 << 10); pub const BUTTON4: Self = Self(1 << 11); pub const BUTTON5: Self = Self(1 << 12); } impl From for u16 { #[inline] fn from(input: KeyButMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: KeyButMask) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: KeyButMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: KeyButMask) -> Self { Some(u32::from(input.0)) } } impl From for KeyButMask { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for KeyButMask { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for KeyButMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SHIFT.0.into(), "SHIFT", "Shift"), (Self::LOCK.0.into(), "LOCK", "Lock"), (Self::CONTROL.0.into(), "CONTROL", "Control"), (Self::MOD1.0.into(), "MOD1", "Mod1"), (Self::MOD2.0.into(), "MOD2", "Mod2"), (Self::MOD3.0.into(), "MOD3", "Mod3"), (Self::MOD4.0.into(), "MOD4", "Mod4"), (Self::MOD5.0.into(), "MOD5", "Mod5"), (Self::BUTTON1.0.into(), "BUTTON1", "Button1"), (Self::BUTTON2.0.into(), "BUTTON2", "Button2"), (Self::BUTTON3.0.into(), "BUTTON3", "Button3"), (Self::BUTTON4.0.into(), "BUTTON4", "Button4"), (Self::BUTTON5.0.into(), "BUTTON5", "Button5"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(KeyButMask, u16); #[derive(Clone, Copy, PartialEq, Eq)] pub struct WindowEnum(u8); impl WindowEnum { pub const NONE: Self = Self(0); } impl From for u8 { #[inline] fn from(input: WindowEnum) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: WindowEnum) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: WindowEnum) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: WindowEnum) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: WindowEnum) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: WindowEnum) -> Self { Some(u32::from(input.0)) } } impl From for WindowEnum { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for WindowEnum { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NONE.0.into(), "NONE", "None"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the KeyPress event pub const KEY_PRESS_EVENT: u8 = 2; /// a key was pressed/released. /// /// # Fields /// /// * `detail` - The keycode (a number representing a physical key on the keyboard) of the key /// which was pressed. /// * `time` - Time when the event was generated (in milliseconds). /// * `root` - The root window of `child`. /// * `same_screen` - Whether the `event` window is on the same screen as the `root` window. /// * `event_x` - If `same_screen` is true, this is the X coordinate relative to the `event` /// window's origin. Otherwise, `event_x` will be set to zero. /// * `event_y` - If `same_screen` is true, this is the Y coordinate relative to the `event` /// window's origin. Otherwise, `event_y` will be set to zero. /// * `root_x` - The X coordinate of the pointer relative to the `root` window at the time of /// the event. /// * `root_y` - The Y coordinate of the pointer relative to the `root` window at the time of /// the event. /// * `state` - The logical state of the pointer buttons and modifier keys just prior to the /// event. /// /// # See /// /// * `GrabKey`: request /// * `GrabKeyboard`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeyPressEvent { pub response_type: u8, pub detail: Keycode, pub sequence: u16, pub time: Timestamp, pub root: Window, pub event: Window, pub child: Window, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub same_screen: bool, } impl TryParse for KeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = Keycode::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = Timestamp::try_parse(remaining)?; let (root, remaining) = Window::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (child, remaining) = Window::try_parse(remaining)?; let (root_x, remaining) = i16::try_parse(remaining)?; let (root_y, remaining) = i16::try_parse(remaining)?; let (event_x, remaining) = i16::try_parse(remaining)?; let (event_y, remaining) = i16::try_parse(remaining)?; let (state, remaining) = u16::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = KeyPressEvent { response_type, detail, sequence, time, root, event, child, root_x, root_y, event_x, event_y, state, same_screen }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&KeyPressEvent> for [u8; 32] { fn from(input: &KeyPressEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = input.detail.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let root_bytes = input.root.serialize(); let event_bytes = input.event.serialize(); let child_bytes = input.child.serialize(); let root_x_bytes = input.root_x.serialize(); let root_y_bytes = input.root_y.serialize(); let event_x_bytes = input.event_x.serialize(); let event_y_bytes = input.event_y.serialize(); let state_bytes = input.state.serialize(); let same_screen_bytes = input.same_screen.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], child_bytes[0], child_bytes[1], child_bytes[2], child_bytes[3], root_x_bytes[0], root_x_bytes[1], root_y_bytes[0], root_y_bytes[1], event_x_bytes[0], event_x_bytes[1], event_y_bytes[0], event_y_bytes[1], state_bytes[0], state_bytes[1], same_screen_bytes[0], 0, ] } } impl From for [u8; 32] { fn from(input: KeyPressEvent) -> Self { Self::from(&input) } } /// Opcode for the KeyRelease event pub const KEY_RELEASE_EVENT: u8 = 3; pub type KeyReleaseEvent = KeyPressEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct ButtonMask(u16); impl ButtonMask { pub const M1: Self = Self(1 << 8); pub const M2: Self = Self(1 << 9); pub const M3: Self = Self(1 << 10); pub const M4: Self = Self(1 << 11); pub const M5: Self = Self(1 << 12); pub const ANY: Self = Self(1 << 15); } impl From for u16 { #[inline] fn from(input: ButtonMask) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ButtonMask) -> Self { Some(input.0) } } impl From for u32 { #[inline] fn from(input: ButtonMask) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ButtonMask) -> Self { Some(u32::from(input.0)) } } impl From for ButtonMask { #[inline] fn from(value: u8) -> Self { Self(value.into()) } } impl From for ButtonMask { #[inline] fn from(value: u16) -> Self { Self(value) } } impl std::fmt::Debug for ButtonMask { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::M1.0.into(), "M1", "M1"), (Self::M2.0.into(), "M2", "M2"), (Self::M3.0.into(), "M3", "M3"), (Self::M4.0.into(), "M4", "M4"), (Self::M5.0.into(), "M5", "M5"), (Self::ANY.0.into(), "ANY", "Any"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(ButtonMask, u16); /// Opcode for the ButtonPress event pub const BUTTON_PRESS_EVENT: u8 = 4; /// a mouse button was pressed/released. /// /// # Fields /// /// * `detail` - The keycode (a number representing a physical key on the keyboard) of the key /// which was pressed. /// * `time` - Time when the event was generated (in milliseconds). /// * `root` - The root window of `child`. /// * `same_screen` - Whether the `event` window is on the same screen as the `root` window. /// * `event_x` - If `same_screen` is true, this is the X coordinate relative to the `event` /// window's origin. Otherwise, `event_x` will be set to zero. /// * `event_y` - If `same_screen` is true, this is the Y coordinate relative to the `event` /// window's origin. Otherwise, `event_y` will be set to zero. /// * `root_x` - The X coordinate of the pointer relative to the `root` window at the time of /// the event. /// * `root_y` - The Y coordinate of the pointer relative to the `root` window at the time of /// the event. /// * `state` - The logical state of the pointer buttons and modifier keys just prior to the /// event. /// /// # See /// /// * `GrabButton`: request /// * `GrabPointer`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ButtonPressEvent { pub response_type: u8, pub detail: Button, pub sequence: u16, pub time: Timestamp, pub root: Window, pub event: Window, pub child: Window, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub same_screen: bool, } impl TryParse for ButtonPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = Button::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = Timestamp::try_parse(remaining)?; let (root, remaining) = Window::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (child, remaining) = Window::try_parse(remaining)?; let (root_x, remaining) = i16::try_parse(remaining)?; let (root_y, remaining) = i16::try_parse(remaining)?; let (event_x, remaining) = i16::try_parse(remaining)?; let (event_y, remaining) = i16::try_parse(remaining)?; let (state, remaining) = u16::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = ButtonPressEvent { response_type, detail, sequence, time, root, event, child, root_x, root_y, event_x, event_y, state, same_screen }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ButtonPressEvent> for [u8; 32] { fn from(input: &ButtonPressEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = input.detail.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let root_bytes = input.root.serialize(); let event_bytes = input.event.serialize(); let child_bytes = input.child.serialize(); let root_x_bytes = input.root_x.serialize(); let root_y_bytes = input.root_y.serialize(); let event_x_bytes = input.event_x.serialize(); let event_y_bytes = input.event_y.serialize(); let state_bytes = input.state.serialize(); let same_screen_bytes = input.same_screen.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], child_bytes[0], child_bytes[1], child_bytes[2], child_bytes[3], root_x_bytes[0], root_x_bytes[1], root_y_bytes[0], root_y_bytes[1], event_x_bytes[0], event_x_bytes[1], event_y_bytes[0], event_y_bytes[1], state_bytes[0], state_bytes[1], same_screen_bytes[0], 0, ] } } impl From for [u8; 32] { fn from(input: ButtonPressEvent) -> Self { Self::from(&input) } } /// Opcode for the ButtonRelease event pub const BUTTON_RELEASE_EVENT: u8 = 5; pub type ButtonReleaseEvent = ButtonPressEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Motion(u8); impl Motion { pub const NORMAL: Self = Self(0); pub const HINT: Self = Self(1); } impl From for u8 { #[inline] fn from(input: Motion) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Motion) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Motion) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Motion) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Motion) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Motion) -> Self { Some(u32::from(input.0)) } } impl From for Motion { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Motion { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NORMAL.0.into(), "NORMAL", "Normal"), (Self::HINT.0.into(), "HINT", "Hint"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the MotionNotify event pub const MOTION_NOTIFY_EVENT: u8 = 6; /// a key was pressed. /// /// # Fields /// /// * `detail` - The keycode (a number representing a physical key on the keyboard) of the key /// which was pressed. /// * `time` - Time when the event was generated (in milliseconds). /// * `root` - The root window of `child`. /// * `same_screen` - Whether the `event` window is on the same screen as the `root` window. /// * `event_x` - If `same_screen` is true, this is the X coordinate relative to the `event` /// window's origin. Otherwise, `event_x` will be set to zero. /// * `event_y` - If `same_screen` is true, this is the Y coordinate relative to the `event` /// window's origin. Otherwise, `event_y` will be set to zero. /// * `root_x` - The X coordinate of the pointer relative to the `root` window at the time of /// the event. /// * `root_y` - The Y coordinate of the pointer relative to the `root` window at the time of /// the event. /// * `state` - The logical state of the pointer buttons and modifier keys just prior to the /// event. /// /// # See /// /// * `GrabKey`: request /// * `GrabKeyboard`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MotionNotifyEvent { pub response_type: u8, pub detail: Motion, pub sequence: u16, pub time: Timestamp, pub root: Window, pub event: Window, pub child: Window, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub same_screen: bool, } impl TryParse for MotionNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = Timestamp::try_parse(remaining)?; let (root, remaining) = Window::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (child, remaining) = Window::try_parse(remaining)?; let (root_x, remaining) = i16::try_parse(remaining)?; let (root_y, remaining) = i16::try_parse(remaining)?; let (event_x, remaining) = i16::try_parse(remaining)?; let (event_y, remaining) = i16::try_parse(remaining)?; let (state, remaining) = u16::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let detail = detail.into(); let result = MotionNotifyEvent { response_type, detail, sequence, time, root, event, child, root_x, root_y, event_x, event_y, state, same_screen }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&MotionNotifyEvent> for [u8; 32] { fn from(input: &MotionNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = u8::from(input.detail).serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let root_bytes = input.root.serialize(); let event_bytes = input.event.serialize(); let child_bytes = input.child.serialize(); let root_x_bytes = input.root_x.serialize(); let root_y_bytes = input.root_y.serialize(); let event_x_bytes = input.event_x.serialize(); let event_y_bytes = input.event_y.serialize(); let state_bytes = input.state.serialize(); let same_screen_bytes = input.same_screen.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], child_bytes[0], child_bytes[1], child_bytes[2], child_bytes[3], root_x_bytes[0], root_x_bytes[1], root_y_bytes[0], root_y_bytes[1], event_x_bytes[0], event_x_bytes[1], event_y_bytes[0], event_y_bytes[1], state_bytes[0], state_bytes[1], same_screen_bytes[0], 0, ] } } impl From for [u8; 32] { fn from(input: MotionNotifyEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct NotifyDetail(u8); impl NotifyDetail { pub const ANCESTOR: Self = Self(0); pub const VIRTUAL: Self = Self(1); pub const INFERIOR: Self = Self(2); pub const NONLINEAR: Self = Self(3); pub const NONLINEAR_VIRTUAL: Self = Self(4); pub const POINTER: Self = Self(5); pub const POINTER_ROOT: Self = Self(6); pub const NONE: Self = Self(7); } impl From for u8 { #[inline] fn from(input: NotifyDetail) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: NotifyDetail) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: NotifyDetail) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyDetail) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: NotifyDetail) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyDetail) -> Self { Some(u32::from(input.0)) } } impl From for NotifyDetail { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for NotifyDetail { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ANCESTOR.0.into(), "ANCESTOR", "Ancestor"), (Self::VIRTUAL.0.into(), "VIRTUAL", "Virtual"), (Self::INFERIOR.0.into(), "INFERIOR", "Inferior"), (Self::NONLINEAR.0.into(), "NONLINEAR", "Nonlinear"), (Self::NONLINEAR_VIRTUAL.0.into(), "NONLINEAR_VIRTUAL", "NonlinearVirtual"), (Self::POINTER.0.into(), "POINTER", "Pointer"), (Self::POINTER_ROOT.0.into(), "POINTER_ROOT", "PointerRoot"), (Self::NONE.0.into(), "NONE", "None"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct NotifyMode(u8); impl NotifyMode { pub const NORMAL: Self = Self(0); pub const GRAB: Self = Self(1); pub const UNGRAB: Self = Self(2); pub const WHILE_GRABBED: Self = Self(3); } impl From for u8 { #[inline] fn from(input: NotifyMode) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: NotifyMode) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: NotifyMode) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyMode) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: NotifyMode) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: NotifyMode) -> Self { Some(u32::from(input.0)) } } impl From for NotifyMode { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for NotifyMode { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NORMAL.0.into(), "NORMAL", "Normal"), (Self::GRAB.0.into(), "GRAB", "Grab"), (Self::UNGRAB.0.into(), "UNGRAB", "Ungrab"), (Self::WHILE_GRABBED.0.into(), "WHILE_GRABBED", "WhileGrabbed"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the EnterNotify event pub const ENTER_NOTIFY_EVENT: u8 = 7; /// the pointer is in a different window. /// /// # Fields /// /// * `event` - The window on which the event was generated. /// * `child` - If the `event` window has subwindows and the final pointer position is in one /// of them, then `child` is set to that subwindow, `XCB_WINDOW_NONE` otherwise. /// * `root` - The root window for the final cursor position. /// * `root_x` - The pointer X coordinate relative to `root`'s origin at the time of the event. /// * `root_y` - The pointer Y coordinate relative to `root`'s origin at the time of the event. /// * `event_x` - If `event` is on the same screen as `root`, this is the pointer X coordinate /// relative to the event window's origin. /// * `event_y` - If `event` is on the same screen as `root`, this is the pointer Y coordinate /// relative to the event window's origin. /// * `mode` - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct EnterNotifyEvent { pub response_type: u8, pub detail: NotifyDetail, pub sequence: u16, pub time: Timestamp, pub root: Window, pub event: Window, pub child: Window, pub root_x: i16, pub root_y: i16, pub event_x: i16, pub event_y: i16, pub state: u16, pub mode: NotifyMode, pub same_screen_focus: u8, } impl TryParse for EnterNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = Timestamp::try_parse(remaining)?; let (root, remaining) = Window::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (child, remaining) = Window::try_parse(remaining)?; let (root_x, remaining) = i16::try_parse(remaining)?; let (root_y, remaining) = i16::try_parse(remaining)?; let (event_x, remaining) = i16::try_parse(remaining)?; let (event_y, remaining) = i16::try_parse(remaining)?; let (state, remaining) = u16::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (same_screen_focus, remaining) = u8::try_parse(remaining)?; let detail = detail.into(); let mode = mode.into(); let result = EnterNotifyEvent { response_type, detail, sequence, time, root, event, child, root_x, root_y, event_x, event_y, state, mode, same_screen_focus }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&EnterNotifyEvent> for [u8; 32] { fn from(input: &EnterNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = u8::from(input.detail).serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let root_bytes = input.root.serialize(); let event_bytes = input.event.serialize(); let child_bytes = input.child.serialize(); let root_x_bytes = input.root_x.serialize(); let root_y_bytes = input.root_y.serialize(); let event_x_bytes = input.event_x.serialize(); let event_y_bytes = input.event_y.serialize(); let state_bytes = input.state.serialize(); let mode_bytes = u8::from(input.mode).serialize(); let same_screen_focus_bytes = input.same_screen_focus.serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], child_bytes[0], child_bytes[1], child_bytes[2], child_bytes[3], root_x_bytes[0], root_x_bytes[1], root_y_bytes[0], root_y_bytes[1], event_x_bytes[0], event_x_bytes[1], event_y_bytes[0], event_y_bytes[1], state_bytes[0], state_bytes[1], mode_bytes[0], same_screen_focus_bytes[0], ] } } impl From for [u8; 32] { fn from(input: EnterNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the LeaveNotify event pub const LEAVE_NOTIFY_EVENT: u8 = 8; pub type LeaveNotifyEvent = EnterNotifyEvent; /// Opcode for the FocusIn event pub const FOCUS_IN_EVENT: u8 = 9; /// NOT YET DOCUMENTED. /// /// # Fields /// /// * `event` - The window on which the focus event was generated. This is the window used by /// the X server to report the event. /// * `detail` - /// * `mode` - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FocusInEvent { pub response_type: u8, pub detail: NotifyDetail, pub sequence: u16, pub event: Window, pub mode: NotifyMode, } impl TryParse for FocusInEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let detail = detail.into(); let mode = mode.into(); let result = FocusInEvent { response_type, detail, sequence, event, mode }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&FocusInEvent> for [u8; 32] { fn from(input: &FocusInEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let detail_bytes = u8::from(input.detail).serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let mode_bytes = u8::from(input.mode).serialize(); [ response_type_bytes[0], detail_bytes[0], sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], mode_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: FocusInEvent) -> Self { Self::from(&input) } } /// Opcode for the FocusOut event pub const FOCUS_OUT_EVENT: u8 = 10; pub type FocusOutEvent = FocusInEvent; /// Opcode for the KeymapNotify event pub const KEYMAP_NOTIFY_EVENT: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct KeymapNotifyEvent { pub response_type: u8, pub keys: [u8; 31], } impl TryParse for KeymapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (keys, remaining) = crate::x11_utils::parse_u8_list(remaining, 31)?; let keys = <[u8; 31]>::try_from(keys).unwrap(); let result = KeymapNotifyEvent { response_type, keys }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&KeymapNotifyEvent> for [u8; 32] { fn from(input: &KeymapNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); [ response_type_bytes[0], input.keys[0], input.keys[1], input.keys[2], input.keys[3], input.keys[4], input.keys[5], input.keys[6], input.keys[7], input.keys[8], input.keys[9], input.keys[10], input.keys[11], input.keys[12], input.keys[13], input.keys[14], input.keys[15], input.keys[16], input.keys[17], input.keys[18], input.keys[19], input.keys[20], input.keys[21], input.keys[22], input.keys[23], input.keys[24], input.keys[25], input.keys[26], input.keys[27], input.keys[28], input.keys[29], input.keys[30], ] } } impl From for [u8; 32] { fn from(input: KeymapNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the Expose event pub const EXPOSE_EVENT: u8 = 12; /// NOT YET DOCUMENTED. /// /// # Fields /// /// * `window` - The exposed (damaged) window. /// * `x` - The X coordinate of the left-upper corner of the exposed rectangle, relative to /// the `window`'s origin. /// * `y` - The Y coordinate of the left-upper corner of the exposed rectangle, relative to /// the `window`'s origin. /// * `width` - The width of the exposed rectangle. /// * `height` - The height of the exposed rectangle. /// * `count` - The amount of `Expose` events following this one. Simple applications that do /// not want to optimize redisplay by distinguishing between subareas of its window /// can just ignore all Expose events with nonzero counts and perform full /// redisplays on events with zero counts. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ExposeEvent { pub response_type: u8, pub sequence: u16, pub window: Window, pub x: u16, pub y: u16, pub width: u16, pub height: u16, pub count: u16, } impl TryParse for ExposeEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (x, remaining) = u16::try_parse(remaining)?; let (y, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (count, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let result = ExposeEvent { response_type, sequence, window, x, y, width, height, count }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ExposeEvent> for [u8; 32] { fn from(input: &ExposeEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let window_bytes = input.window.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); let count_bytes = input.count.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], count_bytes[0], count_bytes[1], 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ExposeEvent) -> Self { Self::from(&input) } } /// Opcode for the GraphicsExposure event pub const GRAPHICS_EXPOSURE_EVENT: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GraphicsExposureEvent { pub response_type: u8, pub sequence: u16, pub drawable: Drawable, pub x: u16, pub y: u16, pub width: u16, pub height: u16, pub minor_opcode: u16, pub count: u16, pub major_opcode: u8, } impl TryParse for GraphicsExposureEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (drawable, remaining) = Drawable::try_parse(remaining)?; let (x, remaining) = u16::try_parse(remaining)?; let (y, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (minor_opcode, remaining) = u16::try_parse(remaining)?; let (count, remaining) = u16::try_parse(remaining)?; let (major_opcode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let result = GraphicsExposureEvent { response_type, sequence, drawable, x, y, width, height, minor_opcode, count, major_opcode }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&GraphicsExposureEvent> for [u8; 32] { fn from(input: &GraphicsExposureEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let drawable_bytes = input.drawable.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); let minor_opcode_bytes = input.minor_opcode.serialize(); let count_bytes = input.count.serialize(); let major_opcode_bytes = input.major_opcode.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], minor_opcode_bytes[0], minor_opcode_bytes[1], count_bytes[0], count_bytes[1], major_opcode_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: GraphicsExposureEvent) -> Self { Self::from(&input) } } /// Opcode for the NoExposure event pub const NO_EXPOSURE_EVENT: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct NoExposureEvent { pub response_type: u8, pub sequence: u16, pub drawable: Drawable, pub minor_opcode: u16, pub major_opcode: u8, } impl TryParse for NoExposureEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (drawable, remaining) = Drawable::try_parse(remaining)?; let (minor_opcode, remaining) = u16::try_parse(remaining)?; let (major_opcode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = NoExposureEvent { response_type, sequence, drawable, minor_opcode, major_opcode }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&NoExposureEvent> for [u8; 32] { fn from(input: &NoExposureEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let drawable_bytes = input.drawable.serialize(); let minor_opcode_bytes = input.minor_opcode.serialize(); let major_opcode_bytes = input.major_opcode.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], minor_opcode_bytes[0], minor_opcode_bytes[1], major_opcode_bytes[0], 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: NoExposureEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Visibility(u8); impl Visibility { pub const UNOBSCURED: Self = Self(0); pub const PARTIALLY_OBSCURED: Self = Self(1); pub const FULLY_OBSCURED: Self = Self(2); } impl From for u8 { #[inline] fn from(input: Visibility) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Visibility) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Visibility) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Visibility) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Visibility) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Visibility) -> Self { Some(u32::from(input.0)) } } impl From for Visibility { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Visibility { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::UNOBSCURED.0.into(), "UNOBSCURED", "Unobscured"), (Self::PARTIALLY_OBSCURED.0.into(), "PARTIALLY_OBSCURED", "PartiallyObscured"), (Self::FULLY_OBSCURED.0.into(), "FULLY_OBSCURED", "FullyObscured"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the VisibilityNotify event pub const VISIBILITY_NOTIFY_EVENT: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct VisibilityNotifyEvent { pub response_type: u8, pub sequence: u16, pub window: Window, pub state: Visibility, } impl TryParse for VisibilityNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let state = state.into(); let result = VisibilityNotifyEvent { response_type, sequence, window, state }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&VisibilityNotifyEvent> for [u8; 32] { fn from(input: &VisibilityNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let window_bytes = input.window.serialize(); let state_bytes = u8::from(input.state).serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], state_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: VisibilityNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the CreateNotify event pub const CREATE_NOTIFY_EVENT: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateNotifyEvent { pub response_type: u8, pub sequence: u16, pub parent: Window, pub window: Window, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub border_width: u16, pub override_redirect: bool, } impl TryParse for CreateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (parent, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (border_width, remaining) = u16::try_parse(remaining)?; let (override_redirect, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = CreateNotifyEvent { response_type, sequence, parent, window, x, y, width, height, border_width, override_redirect }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&CreateNotifyEvent> for [u8; 32] { fn from(input: &CreateNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let parent_bytes = input.parent.serialize(); let window_bytes = input.window.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); let border_width_bytes = input.border_width.serialize(); let override_redirect_bytes = input.override_redirect.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], parent_bytes[0], parent_bytes[1], parent_bytes[2], parent_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], border_width_bytes[0], border_width_bytes[1], override_redirect_bytes[0], 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: CreateNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the DestroyNotify event pub const DESTROY_NOTIFY_EVENT: u8 = 17; /// a window is destroyed. /// /// # Fields /// /// * `event` - The reconfigured window or its parent, depending on whether `StructureNotify` /// or `SubstructureNotify` was selected. /// * `window` - The window that is destroyed. /// /// # See /// /// * `DestroyWindow`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyNotifyEvent { pub response_type: u8, pub sequence: u16, pub event: Window, pub window: Window, } impl TryParse for DestroyNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let result = DestroyNotifyEvent { response_type, sequence, event, window }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&DestroyNotifyEvent> for [u8; 32] { fn from(input: &DestroyNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let window_bytes = input.window.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: DestroyNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the UnmapNotify event pub const UNMAP_NOTIFY_EVENT: u8 = 18; /// a window is unmapped. /// /// # Fields /// /// * `event` - The reconfigured window or its parent, depending on whether `StructureNotify` /// or `SubstructureNotify` was selected. /// * `window` - The window that was unmapped. /// * `from_configure` - Set to 1 if the event was generated as a result of a resizing of the window's /// parent when `window` had a win_gravity of `UnmapGravity`. /// /// # See /// /// * `UnmapWindow`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UnmapNotifyEvent { pub response_type: u8, pub sequence: u16, pub event: Window, pub window: Window, pub from_configure: bool, } impl TryParse for UnmapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (from_configure, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let result = UnmapNotifyEvent { response_type, sequence, event, window, from_configure }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&UnmapNotifyEvent> for [u8; 32] { fn from(input: &UnmapNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let window_bytes = input.window.serialize(); let from_configure_bytes = input.from_configure.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], from_configure_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: UnmapNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the MapNotify event pub const MAP_NOTIFY_EVENT: u8 = 19; /// a window was mapped. /// /// # Fields /// /// * `event` - The window which was mapped or its parent, depending on whether /// `StructureNotify` or `SubstructureNotify` was selected. /// * `window` - The window that was mapped. /// * `override_redirect` - Window managers should ignore this window if `override_redirect` is 1. /// /// # See /// /// * `MapWindow`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MapNotifyEvent { pub response_type: u8, pub sequence: u16, pub event: Window, pub window: Window, pub override_redirect: bool, } impl TryParse for MapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (override_redirect, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let result = MapNotifyEvent { response_type, sequence, event, window, override_redirect }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&MapNotifyEvent> for [u8; 32] { fn from(input: &MapNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let window_bytes = input.window.serialize(); let override_redirect_bytes = input.override_redirect.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], override_redirect_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: MapNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the MapRequest event pub const MAP_REQUEST_EVENT: u8 = 20; /// window wants to be mapped. /// /// # Fields /// /// * `parent` - The parent of `window`. /// * `window` - The window to be mapped. /// /// # See /// /// * `MapWindow`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MapRequestEvent { pub response_type: u8, pub sequence: u16, pub parent: Window, pub window: Window, } impl TryParse for MapRequestEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (parent, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let result = MapRequestEvent { response_type, sequence, parent, window }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&MapRequestEvent> for [u8; 32] { fn from(input: &MapRequestEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let parent_bytes = input.parent.serialize(); let window_bytes = input.window.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], parent_bytes[0], parent_bytes[1], parent_bytes[2], parent_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: MapRequestEvent) -> Self { Self::from(&input) } } /// Opcode for the ReparentNotify event pub const REPARENT_NOTIFY_EVENT: u8 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ReparentNotifyEvent { pub response_type: u8, pub sequence: u16, pub event: Window, pub window: Window, pub parent: Window, pub x: i16, pub y: i16, pub override_redirect: bool, } impl TryParse for ReparentNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (parent, remaining) = Window::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (override_redirect, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let result = ReparentNotifyEvent { response_type, sequence, event, window, parent, x, y, override_redirect }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ReparentNotifyEvent> for [u8; 32] { fn from(input: &ReparentNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let window_bytes = input.window.serialize(); let parent_bytes = input.parent.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); let override_redirect_bytes = input.override_redirect.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], parent_bytes[0], parent_bytes[1], parent_bytes[2], parent_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], override_redirect_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ReparentNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the ConfigureNotify event pub const CONFIGURE_NOTIFY_EVENT: u8 = 22; /// NOT YET DOCUMENTED. /// /// # Fields /// /// * `event` - The reconfigured window or its parent, depending on whether `StructureNotify` /// or `SubstructureNotify` was selected. /// * `window` - The window whose size, position, border, and/or stacking order was changed. /// * `above_sibling` - If `XCB_NONE`, the `window` is on the bottom of the stack with respect to /// sibling windows. However, if set to a sibling window, the `window` is placed on /// top of this sibling window. /// * `x` - The X coordinate of the upper-left outside corner of `window`, relative to the /// parent window's origin. /// * `y` - The Y coordinate of the upper-left outside corner of `window`, relative to the /// parent window's origin. /// * `width` - The inside width of `window`, not including the border. /// * `height` - The inside height of `window`, not including the border. /// * `border_width` - The border width of `window`. /// * `override_redirect` - Window managers should ignore this window if `override_redirect` is 1. /// /// # See /// /// * `FreeColormap`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ConfigureNotifyEvent { pub response_type: u8, pub sequence: u16, pub event: Window, pub window: Window, pub above_sibling: Window, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub border_width: u16, pub override_redirect: bool, } impl TryParse for ConfigureNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (above_sibling, remaining) = Window::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (border_width, remaining) = u16::try_parse(remaining)?; let (override_redirect, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let result = ConfigureNotifyEvent { response_type, sequence, event, window, above_sibling, x, y, width, height, border_width, override_redirect }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ConfigureNotifyEvent> for [u8; 32] { fn from(input: &ConfigureNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let window_bytes = input.window.serialize(); let above_sibling_bytes = input.above_sibling.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); let border_width_bytes = input.border_width.serialize(); let override_redirect_bytes = input.override_redirect.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], above_sibling_bytes[0], above_sibling_bytes[1], above_sibling_bytes[2], above_sibling_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], border_width_bytes[0], border_width_bytes[1], override_redirect_bytes[0], 0, // trailing padding 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ConfigureNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the ConfigureRequest event pub const CONFIGURE_REQUEST_EVENT: u8 = 23; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ConfigureRequestEvent { pub response_type: u8, pub stack_mode: StackMode, pub sequence: u16, pub parent: Window, pub window: Window, pub sibling: Window, pub x: i16, pub y: i16, pub width: u16, pub height: u16, pub border_width: u16, pub value_mask: u16, } impl TryParse for ConfigureRequestEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (stack_mode, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (parent, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (sibling, remaining) = Window::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (border_width, remaining) = u16::try_parse(remaining)?; let (value_mask, remaining) = u16::try_parse(remaining)?; let stack_mode = stack_mode.into(); let result = ConfigureRequestEvent { response_type, stack_mode, sequence, parent, window, sibling, x, y, width, height, border_width, value_mask }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ConfigureRequestEvent> for [u8; 32] { fn from(input: &ConfigureRequestEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let stack_mode_bytes = (u32::from(input.stack_mode) as u8).serialize(); let sequence_bytes = input.sequence.serialize(); let parent_bytes = input.parent.serialize(); let window_bytes = input.window.serialize(); let sibling_bytes = input.sibling.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); let border_width_bytes = input.border_width.serialize(); let value_mask_bytes = input.value_mask.serialize(); [ response_type_bytes[0], stack_mode_bytes[0], sequence_bytes[0], sequence_bytes[1], parent_bytes[0], parent_bytes[1], parent_bytes[2], parent_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], sibling_bytes[0], sibling_bytes[1], sibling_bytes[2], sibling_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], border_width_bytes[0], border_width_bytes[1], value_mask_bytes[0], value_mask_bytes[1], // trailing padding 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ConfigureRequestEvent) -> Self { Self::from(&input) } } /// Opcode for the GravityNotify event pub const GRAVITY_NOTIFY_EVENT: u8 = 24; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GravityNotifyEvent { pub response_type: u8, pub sequence: u16, pub event: Window, pub window: Window, pub x: i16, pub y: i16, } impl TryParse for GravityNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let result = GravityNotifyEvent { response_type, sequence, event, window, x, y }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&GravityNotifyEvent> for [u8; 32] { fn from(input: &GravityNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let window_bytes = input.window.serialize(); let x_bytes = input.x.serialize(); let y_bytes = input.y.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], x_bytes[0], x_bytes[1], y_bytes[0], y_bytes[1], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: GravityNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the ResizeRequest event pub const RESIZE_REQUEST_EVENT: u8 = 25; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ResizeRequestEvent { pub response_type: u8, pub sequence: u16, pub window: Window, pub width: u16, pub height: u16, } impl TryParse for ResizeRequestEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let result = ResizeRequestEvent { response_type, sequence, window, width, height }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&ResizeRequestEvent> for [u8; 32] { fn from(input: &ResizeRequestEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let window_bytes = input.window.serialize(); let width_bytes = input.width.serialize(); let height_bytes = input.height.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: ResizeRequestEvent) -> Self { Self::from(&input) } } /// # Fields /// /// * `OnTop` - The window is now on top of all siblings. /// * `OnBottom` - The window is now below all siblings. #[derive(Clone, Copy, PartialEq, Eq)] pub struct Place(u8); impl Place { pub const ON_TOP: Self = Self(0); pub const ON_BOTTOM: Self = Self(1); } impl From for u8 { #[inline] fn from(input: Place) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Place) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Place) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Place) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Place) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Place) -> Self { Some(u32::from(input.0)) } } impl From for Place { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Place { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::ON_TOP.0.into(), "ON_TOP", "OnTop"), (Self::ON_BOTTOM.0.into(), "ON_BOTTOM", "OnBottom"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the CirculateNotify event pub const CIRCULATE_NOTIFY_EVENT: u8 = 26; /// NOT YET DOCUMENTED. /// /// # Fields /// /// * `event` - Either the restacked window or its parent, depending on whether /// `StructureNotify` or `SubstructureNotify` was selected. /// * `window` - The restacked window. /// * `place` - /// /// # See /// /// * `CirculateWindow`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CirculateNotifyEvent { pub response_type: u8, pub sequence: u16, pub event: Window, pub window: Window, pub place: Place, } impl TryParse for CirculateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (event, remaining) = Window::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let remaining = remaining.get(4..).ok_or(ParseError::InsufficientData)?; let (place, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let place = place.into(); let result = CirculateNotifyEvent { response_type, sequence, event, window, place }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&CirculateNotifyEvent> for [u8; 32] { fn from(input: &CirculateNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let event_bytes = input.event.serialize(); let window_bytes = input.window.serialize(); let place_bytes = u8::from(input.place).serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], event_bytes[0], event_bytes[1], event_bytes[2], event_bytes[3], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], 0, 0, 0, 0, place_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: CirculateNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the CirculateRequest event pub const CIRCULATE_REQUEST_EVENT: u8 = 27; pub type CirculateRequestEvent = CirculateNotifyEvent; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Property(u8); impl Property { pub const NEW_VALUE: Self = Self(0); pub const DELETE: Self = Self(1); } impl From for u8 { #[inline] fn from(input: Property) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Property) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Property) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Property) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Property) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Property) -> Self { Some(u32::from(input.0)) } } impl From for Property { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Property { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NEW_VALUE.0.into(), "NEW_VALUE", "NewValue"), (Self::DELETE.0.into(), "DELETE", "Delete"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the PropertyNotify event pub const PROPERTY_NOTIFY_EVENT: u8 = 28; /// a window property changed. /// /// # Fields /// /// * `window` - The window whose associated property was changed. /// * `atom` - The property's atom, to indicate which property was changed. /// * `time` - A timestamp of the server time when the property was changed. /// * `state` - /// /// # See /// /// * `ChangeProperty`: request #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PropertyNotifyEvent { pub response_type: u8, pub sequence: u16, pub window: Window, pub atom: Atom, pub time: Timestamp, pub state: Property, } impl TryParse for PropertyNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (window, remaining) = Window::try_parse(remaining)?; let (atom, remaining) = Atom::try_parse(remaining)?; let (time, remaining) = Timestamp::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let state = state.into(); let result = PropertyNotifyEvent { response_type, sequence, window, atom, time, state }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&PropertyNotifyEvent> for [u8; 32] { fn from(input: &PropertyNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let window_bytes = input.window.serialize(); let atom_bytes = input.atom.serialize(); let time_bytes = input.time.serialize(); let state_bytes = u8::from(input.state).serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], atom_bytes[0], atom_bytes[1], atom_bytes[2], atom_bytes[3], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], state_bytes[0], 0, 0, 0, // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: PropertyNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the SelectionClear event pub const SELECTION_CLEAR_EVENT: u8 = 29; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectionClearEvent { pub response_type: u8, pub sequence: u16, pub time: Timestamp, pub owner: Window, pub selection: Atom, } impl TryParse for SelectionClearEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = Timestamp::try_parse(remaining)?; let (owner, remaining) = Window::try_parse(remaining)?; let (selection, remaining) = Atom::try_parse(remaining)?; let result = SelectionClearEvent { response_type, sequence, time, owner, selection }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&SelectionClearEvent> for [u8; 32] { fn from(input: &SelectionClearEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let owner_bytes = input.owner.serialize(); let selection_bytes = input.selection.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], owner_bytes[0], owner_bytes[1], owner_bytes[2], owner_bytes[3], selection_bytes[0], selection_bytes[1], selection_bytes[2], selection_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: SelectionClearEvent) -> Self { Self::from(&input) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Time(u8); impl Time { pub const CURRENT_TIME: Self = Self(0); } impl From(&self, time: A) -> Result, ConnectionError> where A: Into, { ungrab_pointer(self, time) } /// Grab pointer button(s). /// /// This request establishes a passive grab. The pointer is actively grabbed as /// described in GrabPointer, the last-pointer-grab time is set to the time at /// which the button was pressed (as transmitted in the ButtonPress event), and the /// ButtonPress event is reported if all of the following conditions are true: /// /// The pointer is not grabbed and the specified button is logically pressed when /// the specified modifier keys are logically down, and no other buttons or /// modifier keys are logically down. /// /// The grab-window contains the pointer. /// /// The confine-to window (if any) is viewable. /// /// A passive grab on the same button/key combination does not exist on any /// ancestor of grab-window. /// /// The interpretation of the remaining arguments is the same as for GrabPointer. /// The active grab is terminated automatically when the logical state of the /// pointer has all buttons released, independent of the logical state of modifier /// keys. Note that the logical state of a device (as seen by means of the /// protocol) may lag the physical state if device event processing is frozen. This /// request overrides all previous passive grabs by the same client on the same /// button/key combinations on the same window. A modifier of AnyModifier is /// equivalent to issuing the request for all possible modifier combinations /// (including the combination of no modifiers). It is not required that all /// specified modifiers have currently assigned keycodes. A button of AnyButton is /// equivalent to issuing the request for all possible buttons. Otherwise, it is /// not required that the button specified currently be assigned to a physical /// button. /// /// An Access error is generated if some other client has already issued a /// GrabButton request with the same button/key combination on the same window. /// When using AnyModifier or AnyButton, the request fails completely (no grabs are /// established), and an Access error is generated if there is a conflicting grab /// for any combination. The request has no effect on an active grab. /// /// # Fields /// /// * `owner_events` - If 1, the `grab_window` will still get the pointer events. If 0, events are not /// reported to the `grab_window`. /// * `grab_window` - Specifies the window on which the pointer should be grabbed. /// * `event_mask` - Specifies which pointer events are reported to the client. /// /// TODO: which values? /// * `confine_to` - Specifies the window to confine the pointer in (the user will not be able to /// move the pointer out of that window). /// /// The special value `XCB_NONE` means don't confine the pointer. /// * `cursor` - Specifies the cursor that should be displayed or `XCB_NONE` to not change the /// cursor. /// * `modifiers` - The modifiers to grab. /// /// Using the special value `XCB_MOD_MASK_ANY` means grab the pointer with all /// possible modifier combinations. /// * `pointer_mode` - /// * `keyboard_mode` - /// * `button` - /// /// # Errors /// /// * `Access` - Another client has already issued a GrabButton with the same button/key /// combination on the same window. /// * `Value` - TODO: reasons? /// * `Cursor` - The specified `cursor` does not exist. /// * `Window` - The specified `window` does not exist. fn grab_button(&self, owner_events: bool, grab_window: Window, event_mask: A, pointer_mode: GrabMode, keyboard_mode: GrabMode, confine_to: B, cursor: C, button: ButtonIndex, modifiers: D) -> Result, ConnectionError> where A: Into, B: Into, C: Into, D: Into, { grab_button(self, owner_events, grab_window, event_mask, pointer_mode, keyboard_mode, confine_to, cursor, button, modifiers) } fn ungrab_button(&self, button: ButtonIndex, grab_window: Window, modifiers: A) -> Result, ConnectionError> where A: Into, { ungrab_button(self, button, grab_window, modifiers) } fn change_active_pointer_grab(&self, cursor: A, time: B, event_mask: C) -> Result, ConnectionError> where A: Into, B: Into, C: Into, { change_active_pointer_grab(self, cursor, time, event_mask) } /// Grab the keyboard. /// /// Actively grabs control of the keyboard and generates FocusIn and FocusOut /// events. Further key events are reported only to the grabbing client. /// /// Any active keyboard grab by this client is overridden. If the keyboard is /// actively grabbed by some other client, `AlreadyGrabbed` is returned. If /// `grab_window` is not viewable, `GrabNotViewable` is returned. If the keyboard /// is frozen by an active grab of another client, `GrabFrozen` is returned. If the /// specified `time` is earlier than the last-keyboard-grab time or later than the /// current X server time, `GrabInvalidTime` is returned. Otherwise, the /// last-keyboard-grab time is set to the specified time. /// /// # Fields /// /// * `owner_events` - If 1, the `grab_window` will still get the pointer events. If 0, events are not /// reported to the `grab_window`. /// * `grab_window` - Specifies the window on which the pointer should be grabbed. /// * `time` - Timestamp to avoid race conditions when running X over the network. /// /// The special value `XCB_CURRENT_TIME` will be replaced with the current server /// time. /// * `pointer_mode` - /// * `keyboard_mode` - /// /// # Errors /// /// * `Value` - TODO: reasons? /// * `Window` - The specified `window` does not exist. /// /// # See /// /// * `GrabPointer`: request /// /// # Example /// /// ```text /// /* /// * Grabs the keyboard actively /// * /// */ /// void my_example(xcb_connection_t *conn, xcb_screen_t *screen) { /// xcb_grab_keyboard_cookie_t cookie; /// xcb_grab_keyboard_reply_t *reply; /// /// cookie = xcb_grab_keyboard( /// conn, /// true, /* report events */ /// screen->root, /* grab the root window */ /// XCB_CURRENT_TIME, /// XCB_GRAB_MODE_ASYNC, /* process events as normal, do not require sync */ /// XCB_GRAB_MODE_ASYNC /// ); /// /// if ((reply = xcb_grab_keyboard_reply(conn, cookie, NULL))) { /// if (reply->status == XCB_GRAB_STATUS_SUCCESS) /// printf("successfully grabbed the keyboard\\n"); /// /// free(reply); /// } /// } /// ``` fn grab_keyboard(&self, owner_events: bool, grab_window: Window, time: A, pointer_mode: GrabMode, keyboard_mode: GrabMode) -> Result, ConnectionError> where A: Into, { grab_keyboard(self, owner_events, grab_window, time, pointer_mode, keyboard_mode) } fn ungrab_keyboard(&self, time: A) -> Result, ConnectionError> where A: Into, { ungrab_keyboard(self, time) } /// Grab keyboard key(s). /// /// Establishes a passive grab on the keyboard. In the future, the keyboard is /// actively grabbed (as for `GrabKeyboard`), the last-keyboard-grab time is set to /// the time at which the key was pressed (as transmitted in the KeyPress event), /// and the KeyPress event is reported if all of the following conditions are true: /// /// The keyboard is not grabbed and the specified key (which can itself be a /// modifier key) is logically pressed when the specified modifier keys are /// logically down, and no other modifier keys are logically down. /// /// Either the grab_window is an ancestor of (or is) the focus window, or the /// grab_window is a descendant of the focus window and contains the pointer. /// /// A passive grab on the same key combination does not exist on any ancestor of /// grab_window. /// /// The interpretation of the remaining arguments is as for XGrabKeyboard. The active grab is terminated /// automatically when the logical state of the keyboard has the specified key released (independent of the /// logical state of the modifier keys), at which point a KeyRelease event is reported to the grabbing window. /// /// Note that the logical state of a device (as seen by client applications) may lag the physical state if /// device event processing is frozen. /// /// A modifiers argument of AnyModifier is equivalent to issuing the request for all possible modifier combinations (including the combination of no modifiers). It is not required that all modifiers specified /// have currently assigned KeyCodes. A keycode argument of AnyKey is equivalent to issuing the request for /// all possible KeyCodes. Otherwise, the specified keycode must be in the range specified by min_keycode /// and max_keycode in the connection setup, or a BadValue error results. /// /// If some other client has issued a XGrabKey with the same key combination on the same window, a BadAccess /// error results. When using AnyModifier or AnyKey, the request fails completely, and a BadAccess error /// results (no grabs are established) if there is a conflicting grab for any combination. /// /// # Fields /// /// * `owner_events` - If 1, the `grab_window` will still get the pointer events. If 0, events are not /// reported to the `grab_window`. /// * `grab_window` - Specifies the window on which the pointer should be grabbed. /// * `key` - The keycode of the key to grab. /// /// The special value `XCB_GRAB_ANY` means grab any key. /// * `cursor` - Specifies the cursor that should be displayed or `XCB_NONE` to not change the /// cursor. /// * `modifiers` - The modifiers to grab. /// /// Using the special value `XCB_MOD_MASK_ANY` means grab the pointer with all /// possible modifier combinations. /// * `pointer_mode` - /// * `keyboard_mode` - /// /// # Errors /// /// * `Access` - Another client has already issued a GrabKey with the same button/key /// combination on the same window. /// * `Value` - TODO: reasons? /// * `Window` - The specified `window` does not exist. /// /// # See /// /// * `GrabKeyboard`: request fn grab_key(&self, owner_events: bool, grab_window: Window, modifiers: A, key: B, pointer_mode: GrabMode, keyboard_mode: GrabMode) -> Result, ConnectionError> where A: Into, B: Into, { grab_key(self, owner_events, grab_window, modifiers, key, pointer_mode, keyboard_mode) } /// release a key combination. /// /// Releases the key combination on `grab_window` if you grabbed it using /// `xcb_grab_key` before. /// /// # Fields /// /// * `key` - The keycode of the specified key combination. /// /// Using the special value `XCB_GRAB_ANY` means releasing all possible key codes. /// * `grab_window` - The window on which the grabbed key combination will be released. /// * `modifiers` - The modifiers of the specified key combination. /// /// Using the special value `XCB_MOD_MASK_ANY` means releasing the key combination /// with every possible modifier combination. /// /// # Errors /// /// * `Window` - The specified `grab_window` does not exist. /// * `Value` - TODO: reasons? /// /// # See /// /// * `GrabKey`: request /// * `xev`: program fn ungrab_key(&self, key: A, grab_window: Window, modifiers: B) -> Result, ConnectionError> where A: Into, B: Into, { ungrab_key(self, key, grab_window, modifiers) } /// release queued events. /// /// Releases queued events if the client has caused a device (pointer/keyboard) to /// freeze due to grabbing it actively. This request has no effect if `time` is /// earlier than the last-grab time of the most recent active grab for this client /// or if `time` is later than the current X server time. /// /// # Fields /// /// * `mode` - /// * `time` - Timestamp to avoid race conditions when running X over the network. /// /// The special value `XCB_CURRENT_TIME` will be replaced with the current server /// time. /// /// # Errors /// /// * `Value` - You specified an invalid `mode`. fn allow_events(&self, mode: Allow, time: A) -> Result, ConnectionError> where A: Into, { allow_events(self, mode, time) } fn grab_server(&self) -> Result, ConnectionError> { grab_server(self) } fn ungrab_server(&self) -> Result, ConnectionError> { ungrab_server(self) } /// get pointer coordinates. /// /// Gets the root window the pointer is logically on and the pointer coordinates /// relative to the root window's origin. /// /// # Fields /// /// * `window` - A window to check if the pointer is on the same screen as `window` (see the /// `same_screen` field in the reply). /// /// # Errors /// /// * `Window` - The specified `window` does not exist. fn query_pointer(&self, window: Window) -> Result, ConnectionError> { query_pointer(self, window) } fn get_motion_events(&self, window: Window, start: A, stop: B) -> Result, ConnectionError> where A: Into, B: Into, { get_motion_events(self, window, start, stop) } fn translate_coordinates(&self, src_window: Window, dst_window: Window, src_x: i16, src_y: i16) -> Result, ConnectionError> { translate_coordinates(self, src_window, dst_window, src_x, src_y) } /// move mouse pointer. /// /// Moves the mouse pointer to the specified position. /// /// If `src_window` is not `XCB_NONE` (TODO), the move will only take place if the /// pointer is inside `src_window` and within the rectangle specified by (`src_x`, /// `src_y`, `src_width`, `src_height`). The rectangle coordinates are relative to /// `src_window`. /// /// If `dst_window` is not `XCB_NONE` (TODO), the pointer will be moved to the /// offsets (`dst_x`, `dst_y`) relative to `dst_window`. If `dst_window` is /// `XCB_NONE` (TODO), the pointer will be moved by the offsets (`dst_x`, `dst_y`) /// relative to the current position of the pointer. /// /// # Fields /// /// * `src_window` - If `src_window` is not `XCB_NONE` (TODO), the move will only take place if the /// pointer is inside `src_window` and within the rectangle specified by (`src_x`, /// `src_y`, `src_width`, `src_height`). The rectangle coordinates are relative to /// `src_window`. /// * `dst_window` - If `dst_window` is not `XCB_NONE` (TODO), the pointer will be moved to the /// offsets (`dst_x`, `dst_y`) relative to `dst_window`. If `dst_window` is /// `XCB_NONE` (TODO), the pointer will be moved by the offsets (`dst_x`, `dst_y`) /// relative to the current position of the pointer. /// /// # Errors /// /// * `Window` - TODO: reasons? /// /// # See /// /// * `SetInputFocus`: request fn warp_pointer(&self, src_window: A, dst_window: B, src_x: i16, src_y: i16, src_width: u16, src_height: u16, dst_x: i16, dst_y: i16) -> Result, ConnectionError> where A: Into, B: Into, { warp_pointer(self, src_window, dst_window, src_x, src_y, src_width, src_height, dst_x, dst_y) } /// Sets input focus. /// /// Changes the input focus and the last-focus-change time. If the specified `time` /// is earlier than the current last-focus-change time, the request is ignored (to /// avoid race conditions when running X over the network). /// /// A FocusIn and FocusOut event is generated when focus is changed. /// /// # Fields /// /// * `focus` - The window to focus. All keyboard events will be reported to this window. The /// window must be viewable (TODO), or a `xcb_match_error_t` occurs (TODO). /// /// If `focus` is `XCB_NONE` (TODO), all keyboard events are /// discarded until a new focus window is set. /// /// If `focus` is `XCB_POINTER_ROOT` (TODO), focus is on the root window of the /// screen on which the pointer is on currently. /// * `time` - Timestamp to avoid race conditions when running X over the network. /// /// The special value `XCB_CURRENT_TIME` will be replaced with the current server /// time. /// * `revert_to` - Specifies what happens when the `focus` window becomes unviewable (if `focus` /// is neither `XCB_NONE` nor `XCB_POINTER_ROOT`). /// /// # Errors /// /// * `Window` - The specified `focus` window does not exist. /// * `Match` - The specified `focus` window is not viewable. /// * `Value` - TODO: Reasons? /// /// # See /// /// * `FocusIn`: event /// * `FocusOut`: event fn set_input_focus(&self, revert_to: InputFocus, focus: A, time: B) -> Result, ConnectionError> where A: Into, B: Into, { set_input_focus(self, revert_to, focus, time) } fn get_input_focus(&self) -> Result, ConnectionError> { get_input_focus(self) } fn query_keymap(&self) -> Result, ConnectionError> { query_keymap(self) } /// opens a font. /// /// Opens any X core font matching the given `name` (for example "-misc-fixed-*"). /// /// Note that X core fonts are deprecated (but still supported) in favor of /// client-side rendering using Xft. /// /// # Fields /// /// * `fid` - The ID with which you will refer to the font, created by `xcb_generate_id`. /// * `name_len` - Length (in bytes) of `name`. /// * `name` - A pattern describing an X core font. /// /// # Errors /// /// * `Name` - No font matches the given `name`. /// /// # See /// /// * `xcb_generate_id`: function fn open_font<'c, 'input>(&'c self, fid: Font, name: &'input [u8]) -> Result, ConnectionError> { open_font(self, fid, name) } fn close_font(&self, font: Font) -> Result, ConnectionError> { close_font(self, font) } /// query font metrics. /// /// Queries information associated with the font. /// /// # Fields /// /// * `font` - The fontable (Font or Graphics Context) to query. fn query_font(&self, font: Fontable) -> Result, ConnectionError> { query_font(self, font) } /// get text extents. /// /// Query text extents from the X11 server. This request returns the bounding box /// of the specified 16-bit character string in the specified `font` or the font /// contained in the specified graphics context. /// /// `font_ascent` is set to the maximum of the ascent metrics of all characters in /// the string. `font_descent` is set to the maximum of the descent metrics. /// `overall_width` is set to the sum of the character-width metrics of all /// characters in the string. For each character in the string, let W be the sum of /// the character-width metrics of all characters preceding it in the string. Let L /// be the left-side-bearing metric of the character plus W. Let R be the /// right-side-bearing metric of the character plus W. The lbearing member is set /// to the minimum L of all characters in the string. The rbearing member is set to /// the maximum R. /// /// For fonts defined with linear indexing rather than 2-byte matrix indexing, each /// `xcb_char2b_t` structure is interpreted as a 16-bit number with byte1 as the /// most significant byte. If the font has no defined default character, undefined /// characters in the string are taken to have all zero metrics. /// /// Characters with all zero metrics are ignored. If the font has no defined /// default_char, the undefined characters in the string are also ignored. /// /// # Fields /// /// * `font` - The `font` to calculate text extents in. You can also pass a graphics context. /// * `string_len` - The number of characters in `string`. /// * `string` - The text to get text extents for. /// /// # Errors /// /// * `GContext` - The specified graphics context does not exist. /// * `Font` - The specified `font` does not exist. fn query_text_extents<'c, 'input>(&'c self, font: Fontable, string: &'input [Char2b]) -> Result, ConnectionError> { query_text_extents(self, font, string) } /// get matching font names. /// /// Gets a list of available font names which match the given `pattern`. /// /// # Fields /// /// * `pattern_len` - The length (in bytes) of `pattern`. /// * `pattern` - A font pattern, for example "-misc-fixed-*". /// /// The asterisk (*) is a wildcard for any number of characters. The question mark /// (?) is a wildcard for a single character. Use of uppercase or lowercase does /// not matter. /// * `max_names` - The maximum number of fonts to be returned. fn list_fonts<'c, 'input>(&'c self, max_names: u16, pattern: &'input [u8]) -> Result, ConnectionError> { list_fonts(self, max_names, pattern) } /// get matching font names and information. /// /// Gets a list of available font names which match the given `pattern`. /// /// # Fields /// /// * `pattern_len` - The length (in bytes) of `pattern`. /// * `pattern` - A font pattern, for example "-misc-fixed-*". /// /// The asterisk (*) is a wildcard for any number of characters. The question mark /// (?) is a wildcard for a single character. Use of uppercase or lowercase does /// not matter. /// * `max_names` - The maximum number of fonts to be returned. fn list_fonts_with_info<'c, 'input>(&'c self, max_names: u16, pattern: &'input [u8]) -> Result, ConnectionError> { list_fonts_with_info(self, max_names, pattern) } fn set_font_path<'c, 'input>(&'c self, font: &'input [Str]) -> Result, ConnectionError> { set_font_path(self, font) } fn get_font_path(&self) -> Result, ConnectionError> { get_font_path(self) } /// Creates a pixmap. /// /// Creates a pixmap. The pixmap can only be used on the same screen as `drawable` /// is on and only with drawables of the same `depth`. /// /// # Fields /// /// * `depth` - TODO /// * `pid` - The ID with which you will refer to the new pixmap, created by /// `xcb_generate_id`. /// * `drawable` - Drawable to get the screen from. /// * `width` - The width of the new pixmap. /// * `height` - The height of the new pixmap. /// /// # Errors /// /// * `Value` - TODO: reasons? /// * `Drawable` - The specified `drawable` (Window or Pixmap) does not exist. /// * `Alloc` - The X server could not allocate the requested resources (no memory?). /// /// # See /// /// * `xcb_generate_id`: function fn create_pixmap(&self, depth: u8, pid: Pixmap, drawable: Drawable, width: u16, height: u16) -> Result, ConnectionError> { create_pixmap(self, depth, pid, drawable, width, height) } /// Destroys a pixmap. /// /// Deletes the association between the pixmap ID and the pixmap. The pixmap /// storage will be freed when there are no more references to it. /// /// # Fields /// /// * `pixmap` - The pixmap to destroy. /// /// # Errors /// /// * `Pixmap` - The specified pixmap does not exist. fn free_pixmap(&self, pixmap: Pixmap) -> Result, ConnectionError> { free_pixmap(self, pixmap) } /// Creates a graphics context. /// /// Creates a graphics context. The graphics context can be used with any drawable /// that has the same root and depth as the specified drawable. /// /// # Fields /// /// * `cid` - The ID with which you will refer to the graphics context, created by /// `xcb_generate_id`. /// * `drawable` - Drawable to get the root/depth from. /// /// # Errors /// /// * `Drawable` - The specified `drawable` (Window or Pixmap) does not exist. /// * `Match` - TODO: reasons? /// * `Font` - TODO: reasons? /// * `Pixmap` - TODO: reasons? /// * `Value` - TODO: reasons? /// * `Alloc` - The X server could not allocate the requested resources (no memory?). /// /// # See /// /// * `xcb_generate_id`: function fn create_gc<'c, 'input>(&'c self, cid: Gcontext, drawable: Drawable, value_list: &'input CreateGCAux) -> Result, ConnectionError> { create_gc(self, cid, drawable, value_list) } /// change graphics context components. /// /// Changes the components specified by `value_mask` for the specified graphics context. /// /// # Fields /// /// * `gc` - The graphics context to change. /// * `value_mask` - /// * `value_list` - Values for each of the components specified in the bitmask `value_mask`. The /// order has to correspond to the order of possible `value_mask` bits. See the /// example. /// /// # Errors /// /// * `Font` - TODO: reasons? /// * `GContext` - TODO: reasons? /// * `Match` - TODO: reasons? /// * `Pixmap` - TODO: reasons? /// * `Value` - TODO: reasons? /// * `Alloc` - The X server could not allocate the requested resources (no memory?). /// /// # Example /// /// ```text /// /* /// * Changes the foreground color component of the specified graphics context. /// * /// */ /// void my_example(xcb_connection_t *conn, xcb_gcontext_t gc, uint32_t fg, uint32_t bg) { /// /* C99 allows us to use a compact way of changing a single component: */ /// xcb_change_gc(conn, gc, XCB_GC_FOREGROUND, (uint32_t[]){ fg }); /// /// /* The more explicit way. Beware that the order of values is important! */ /// uint32_t mask = 0; /// mask |= XCB_GC_FOREGROUND; /// mask |= XCB_GC_BACKGROUND; /// /// uint32_t values[] = { /// fg, /// bg /// }; /// xcb_change_gc(conn, gc, mask, values); /// xcb_flush(conn); /// } /// ``` fn change_gc<'c, 'input>(&'c self, gc: Gcontext, value_list: &'input ChangeGCAux) -> Result, ConnectionError> { change_gc(self, gc, value_list) } fn copy_gc(&self, src_gc: Gcontext, dst_gc: Gcontext, value_mask: A) -> Result, ConnectionError> where A: Into, { copy_gc(self, src_gc, dst_gc, value_mask) } fn set_dashes<'c, 'input>(&'c self, gc: Gcontext, dash_offset: u16, dashes: &'input [u8]) -> Result, ConnectionError> { set_dashes(self, gc, dash_offset, dashes) } fn set_clip_rectangles<'c, 'input>(&'c self, ordering: ClipOrdering, gc: Gcontext, clip_x_origin: i16, clip_y_origin: i16, rectangles: &'input [Rectangle]) -> Result, ConnectionError> { set_clip_rectangles(self, ordering, gc, clip_x_origin, clip_y_origin, rectangles) } /// Destroys a graphics context. /// /// Destroys the specified `gc` and all associated storage. /// /// # Fields /// /// * `gc` - The graphics context to destroy. /// /// # Errors /// /// * `GContext` - The specified graphics context does not exist. fn free_gc(&self, gc: Gcontext) -> Result, ConnectionError> { free_gc(self, gc) } fn clear_area(&self, exposures: bool, window: Window, x: i16, y: i16, width: u16, height: u16) -> Result, ConnectionError> { clear_area(self, exposures, window, x, y, width, height) } /// copy areas. /// /// Copies the specified rectangle from `src_drawable` to `dst_drawable`. /// /// # Fields /// /// * `dst_drawable` - The destination drawable (Window or Pixmap). /// * `src_drawable` - The source drawable (Window or Pixmap). /// * `gc` - The graphics context to use. /// * `src_x` - The source X coordinate. /// * `src_y` - The source Y coordinate. /// * `dst_x` - The destination X coordinate. /// * `dst_y` - The destination Y coordinate. /// * `width` - The width of the area to copy (in pixels). /// * `height` - The height of the area to copy (in pixels). /// /// # Errors /// /// * `Drawable` - The specified `drawable` (Window or Pixmap) does not exist. /// * `GContext` - The specified graphics context does not exist. /// * `Match` - `src_drawable` has a different root or depth than `dst_drawable`. fn copy_area(&self, src_drawable: Drawable, dst_drawable: Drawable, gc: Gcontext, src_x: i16, src_y: i16, dst_x: i16, dst_y: i16, width: u16, height: u16) -> Result, ConnectionError> { copy_area(self, src_drawable, dst_drawable, gc, src_x, src_y, dst_x, dst_y, width, height) } fn copy_plane(&self, src_drawable: Drawable, dst_drawable: Drawable, gc: Gcontext, src_x: i16, src_y: i16, dst_x: i16, dst_y: i16, width: u16, height: u16, bit_plane: u32) -> Result, ConnectionError> { copy_plane(self, src_drawable, dst_drawable, gc, src_x, src_y, dst_x, dst_y, width, height, bit_plane) } fn poly_point<'c, 'input>(&'c self, coordinate_mode: CoordMode, drawable: Drawable, gc: Gcontext, points: &'input [Point]) -> Result, ConnectionError> { poly_point(self, coordinate_mode, drawable, gc, points) } /// draw lines. /// /// Draws `points_len`-1 lines between each pair of points (point[i], point[i+1]) /// in the `points` array. The lines are drawn in the order listed in the array. /// They join correctly at all intermediate points, and if the first and last /// points coincide, the first and last lines also join correctly. For any given /// line, a pixel is not drawn more than once. If thin (zero line-width) lines /// intersect, the intersecting pixels are drawn multiple times. If wide lines /// intersect, the intersecting pixels are drawn only once, as though the entire /// request were a single, filled shape. /// /// # Fields /// /// * `drawable` - The drawable to draw the line(s) on. /// * `gc` - The graphics context to use. /// * `points_len` - The number of `xcb_point_t` structures in `points`. /// * `points` - An array of points. /// * `coordinate_mode` - /// /// # Errors /// /// * `Drawable` - TODO: reasons? /// * `GContext` - TODO: reasons? /// * `Match` - TODO: reasons? /// * `Value` - TODO: reasons? /// /// # Example /// /// ```text /// /* /// * Draw a straight line. /// * /// */ /// void my_example(xcb_connection_t *conn, xcb_drawable_t drawable, xcb_gcontext_t gc) { /// xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, drawable, gc, 2, /// (xcb_point_t[]) { {10, 10}, {100, 10} }); /// xcb_flush(conn); /// } /// ``` fn poly_line<'c, 'input>(&'c self, coordinate_mode: CoordMode, drawable: Drawable, gc: Gcontext, points: &'input [Point]) -> Result, ConnectionError> { poly_line(self, coordinate_mode, drawable, gc, points) } /// draw lines. /// /// Draws multiple, unconnected lines. For each segment, a line is drawn between /// (x1, y1) and (x2, y2). The lines are drawn in the order listed in the array of /// `xcb_segment_t` structures and does not perform joining at coincident /// endpoints. For any given line, a pixel is not drawn more than once. If lines /// intersect, the intersecting pixels are drawn multiple times. /// /// TODO: include the xcb_segment_t data structure /// /// TODO: an example /// /// # Fields /// /// * `drawable` - A drawable (Window or Pixmap) to draw on. /// * `gc` - The graphics context to use. /// /// TODO: document which attributes of a gc are used /// * `segments_len` - The number of `xcb_segment_t` structures in `segments`. /// * `segments` - An array of `xcb_segment_t` structures. /// /// # Errors /// /// * `Drawable` - The specified `drawable` does not exist. /// * `GContext` - The specified `gc` does not exist. /// * `Match` - TODO: reasons? fn poly_segment<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, segments: &'input [Segment]) -> Result, ConnectionError> { poly_segment(self, drawable, gc, segments) } fn poly_rectangle<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, rectangles: &'input [Rectangle]) -> Result, ConnectionError> { poly_rectangle(self, drawable, gc, rectangles) } fn poly_arc<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, arcs: &'input [Arc]) -> Result, ConnectionError> { poly_arc(self, drawable, gc, arcs) } fn fill_poly<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, shape: PolyShape, coordinate_mode: CoordMode, points: &'input [Point]) -> Result, ConnectionError> { fill_poly(self, drawable, gc, shape, coordinate_mode, points) } /// Fills rectangles. /// /// Fills the specified rectangle(s) in the order listed in the array. For any /// given rectangle, each pixel is not drawn more than once. If rectangles /// intersect, the intersecting pixels are drawn multiple times. /// /// # Fields /// /// * `drawable` - The drawable (Window or Pixmap) to draw on. /// * `gc` - The graphics context to use. /// /// The following graphics context components are used: function, plane-mask, /// fill-style, subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask. /// /// The following graphics context mode-dependent components are used: /// foreground, background, tile, stipple, tile-stipple-x-origin, and /// tile-stipple-y-origin. /// * `rectangles_len` - The number of `xcb_rectangle_t` structures in `rectangles`. /// * `rectangles` - The rectangles to fill. /// /// # Errors /// /// * `Drawable` - The specified `drawable` (Window or Pixmap) does not exist. /// * `GContext` - The specified graphics context does not exist. /// * `Match` - TODO: reasons? fn poly_fill_rectangle<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, rectangles: &'input [Rectangle]) -> Result, ConnectionError> { poly_fill_rectangle(self, drawable, gc, rectangles) } fn poly_fill_arc<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, arcs: &'input [Arc]) -> Result, ConnectionError> { poly_fill_arc(self, drawable, gc, arcs) } fn put_image<'c, 'input>(&'c self, format: ImageFormat, drawable: Drawable, gc: Gcontext, width: u16, height: u16, dst_x: i16, dst_y: i16, left_pad: u8, depth: u8, data: &'input [u8]) -> Result, ConnectionError> { put_image(self, format, drawable, gc, width, height, dst_x, dst_y, left_pad, depth, data) } fn get_image(&self, format: ImageFormat, drawable: Drawable, x: i16, y: i16, width: u16, height: u16, plane_mask: u32) -> Result, ConnectionError> { get_image(self, format, drawable, x, y, width, height, plane_mask) } fn poly_text8<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, x: i16, y: i16, items: &'input [u8]) -> Result, ConnectionError> { poly_text8(self, drawable, gc, x, y, items) } fn poly_text16<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, x: i16, y: i16, items: &'input [u8]) -> Result, ConnectionError> { poly_text16(self, drawable, gc, x, y, items) } /// Draws text. /// /// Fills the destination rectangle with the background pixel from `gc`, then /// paints the text with the foreground pixel from `gc`. The upper-left corner of /// the filled rectangle is at [x, y - font-ascent]. The width is overall-width, /// the height is font-ascent + font-descent. The overall-width, font-ascent and /// font-descent are as returned by `xcb_query_text_extents` (TODO). /// /// Note that using X core fonts is deprecated (but still supported) in favor of /// client-side rendering using Xft. /// /// # Fields /// /// * `drawable` - The drawable (Window or Pixmap) to draw text on. /// * `string_len` - The length of the `string`. Note that this parameter limited by 255 due to /// using 8 bits! /// * `string` - The string to draw. Only the first 255 characters are relevant due to the data /// type of `string_len`. /// * `x` - The x coordinate of the first character, relative to the origin of `drawable`. /// * `y` - The y coordinate of the first character, relative to the origin of `drawable`. /// * `gc` - The graphics context to use. /// /// The following graphics context components are used: plane-mask, foreground, /// background, font, subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask. /// /// # Errors /// /// * `Drawable` - The specified `drawable` (Window or Pixmap) does not exist. /// * `GContext` - The specified graphics context does not exist. /// * `Match` - TODO: reasons? /// /// # See /// /// * `ImageText16`: request fn image_text8<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, x: i16, y: i16, string: &'input [u8]) -> Result, ConnectionError> { image_text8(self, drawable, gc, x, y, string) } /// Draws text. /// /// Fills the destination rectangle with the background pixel from `gc`, then /// paints the text with the foreground pixel from `gc`. The upper-left corner of /// the filled rectangle is at [x, y - font-ascent]. The width is overall-width, /// the height is font-ascent + font-descent. The overall-width, font-ascent and /// font-descent are as returned by `xcb_query_text_extents` (TODO). /// /// Note that using X core fonts is deprecated (but still supported) in favor of /// client-side rendering using Xft. /// /// # Fields /// /// * `drawable` - The drawable (Window or Pixmap) to draw text on. /// * `string_len` - The length of the `string` in characters. Note that this parameter limited by /// 255 due to using 8 bits! /// * `string` - The string to draw. Only the first 255 characters are relevant due to the data /// type of `string_len`. Every character uses 2 bytes (hence the 16 in this /// request's name). /// * `x` - The x coordinate of the first character, relative to the origin of `drawable`. /// * `y` - The y coordinate of the first character, relative to the origin of `drawable`. /// * `gc` - The graphics context to use. /// /// The following graphics context components are used: plane-mask, foreground, /// background, font, subwindow-mode, clip-x-origin, clip-y-origin, and clip-mask. /// /// # Errors /// /// * `Drawable` - The specified `drawable` (Window or Pixmap) does not exist. /// * `GContext` - The specified graphics context does not exist. /// * `Match` - TODO: reasons? /// /// # See /// /// * `ImageText8`: request fn image_text16<'c, 'input>(&'c self, drawable: Drawable, gc: Gcontext, x: i16, y: i16, string: &'input [Char2b]) -> Result, ConnectionError> { image_text16(self, drawable, gc, x, y, string) } fn create_colormap(&self, alloc: ColormapAlloc, mid: Colormap, window: Window, visual: Visualid) -> Result, ConnectionError> { create_colormap(self, alloc, mid, window, visual) } fn free_colormap(&self, cmap: Colormap) -> Result, ConnectionError> { free_colormap(self, cmap) } fn copy_colormap_and_free(&self, mid: Colormap, src_cmap: Colormap) -> Result, ConnectionError> { copy_colormap_and_free(self, mid, src_cmap) } fn install_colormap(&self, cmap: Colormap) -> Result, ConnectionError> { install_colormap(self, cmap) } fn uninstall_colormap(&self, cmap: Colormap) -> Result, ConnectionError> { uninstall_colormap(self, cmap) } fn list_installed_colormaps(&self, window: Window) -> Result, ConnectionError> { list_installed_colormaps(self, window) } /// Allocate a color. /// /// Allocates a read-only colormap entry corresponding to the closest RGB value /// supported by the hardware. If you are using TrueColor, you can take a shortcut /// and directly calculate the color pixel value to avoid the round trip. But, for /// example, on 16-bit color setups (VNC), you can easily get the closest supported /// RGB value to the RGB value you are specifying. /// /// # Fields /// /// * `cmap` - TODO /// * `red` - The red value of your color. /// * `green` - The green value of your color. /// * `blue` - The blue value of your color. /// /// # Errors /// /// * `Colormap` - The specified colormap `cmap` does not exist. fn alloc_color(&self, cmap: Colormap, red: u16, green: u16, blue: u16) -> Result, ConnectionError> { alloc_color(self, cmap, red, green, blue) } fn alloc_named_color<'c, 'input>(&'c self, cmap: Colormap, name: &'input [u8]) -> Result, ConnectionError> { alloc_named_color(self, cmap, name) } fn alloc_color_cells(&self, contiguous: bool, cmap: Colormap, colors: u16, planes: u16) -> Result, ConnectionError> { alloc_color_cells(self, contiguous, cmap, colors, planes) } fn alloc_color_planes(&self, contiguous: bool, cmap: Colormap, colors: u16, reds: u16, greens: u16, blues: u16) -> Result, ConnectionError> { alloc_color_planes(self, contiguous, cmap, colors, reds, greens, blues) } fn free_colors<'c, 'input>(&'c self, cmap: Colormap, plane_mask: u32, pixels: &'input [u32]) -> Result, ConnectionError> { free_colors(self, cmap, plane_mask, pixels) } fn store_colors<'c, 'input>(&'c self, cmap: Colormap, items: &'input [Coloritem]) -> Result, ConnectionError> { store_colors(self, cmap, items) } fn store_named_color<'c, 'input, A>(&'c self, flags: A, cmap: Colormap, pixel: u32, name: &'input [u8]) -> Result, ConnectionError> where A: Into, { store_named_color(self, flags, cmap, pixel, name) } fn query_colors<'c, 'input>(&'c self, cmap: Colormap, pixels: &'input [u32]) -> Result, ConnectionError> { query_colors(self, cmap, pixels) } fn lookup_color<'c, 'input>(&'c self, cmap: Colormap, name: &'input [u8]) -> Result, ConnectionError> { lookup_color(self, cmap, name) } fn create_cursor(&self, cid: Cursor, source: Pixmap, mask: A, fore_red: u16, fore_green: u16, fore_blue: u16, back_red: u16, back_green: u16, back_blue: u16, x: u16, y: u16) -> Result, ConnectionError> where A: Into, { create_cursor(self, cid, source, mask, fore_red, fore_green, fore_blue, back_red, back_green, back_blue, x, y) } /// create cursor. /// /// Creates a cursor from a font glyph. X provides a set of standard cursor shapes /// in a special font named cursor. Applications are encouraged to use this /// interface for their cursors because the font can be customized for the /// individual display type. /// /// All pixels which are set to 1 in the source will use the foreground color (as /// specified by `fore_red`, `fore_green` and `fore_blue`). All pixels set to 0 /// will use the background color (as specified by `back_red`, `back_green` and /// `back_blue`). /// /// # Fields /// /// * `cid` - The ID with which you will refer to the cursor, created by `xcb_generate_id`. /// * `source_font` - In which font to look for the cursor glyph. /// * `mask_font` - In which font to look for the mask glyph. /// * `source_char` - The glyph of `source_font` to use. /// * `mask_char` - The glyph of `mask_font` to use as a mask: Pixels which are set to 1 define /// which source pixels are displayed. All pixels which are set to 0 are not /// displayed. /// * `fore_red` - The red value of the foreground color. /// * `fore_green` - The green value of the foreground color. /// * `fore_blue` - The blue value of the foreground color. /// * `back_red` - The red value of the background color. /// * `back_green` - The green value of the background color. /// * `back_blue` - The blue value of the background color. /// /// # Errors /// /// * `Alloc` - The X server could not allocate the requested resources (no memory?). /// * `Font` - The specified `source_font` or `mask_font` does not exist. /// * `Value` - Either `source_char` or `mask_char` are not defined in `source_font` or `mask_font`, respectively. fn create_glyph_cursor(&self, cid: Cursor, source_font: Font, mask_font: A, source_char: u16, mask_char: u16, fore_red: u16, fore_green: u16, fore_blue: u16, back_red: u16, back_green: u16, back_blue: u16) -> Result, ConnectionError> where A: Into, { create_glyph_cursor(self, cid, source_font, mask_font, source_char, mask_char, fore_red, fore_green, fore_blue, back_red, back_green, back_blue) } /// Deletes a cursor. /// /// Deletes the association between the cursor resource ID and the specified /// cursor. The cursor is freed when no other resource references it. /// /// # Fields /// /// * `cursor` - The cursor to destroy. /// /// # Errors /// /// * `Cursor` - The specified cursor does not exist. fn free_cursor(&self, cursor: Cursor) -> Result, ConnectionError> { free_cursor(self, cursor) } fn recolor_cursor(&self, cursor: Cursor, fore_red: u16, fore_green: u16, fore_blue: u16, back_red: u16, back_green: u16, back_blue: u16) -> Result, ConnectionError> { recolor_cursor(self, cursor, fore_red, fore_green, fore_blue, back_red, back_green, back_blue) } fn query_best_size(&self, class: QueryShapeOf, drawable: Drawable, width: u16, height: u16) -> Result, ConnectionError> { query_best_size(self, class, drawable, width, height) } /// check if extension is present. /// /// Determines if the specified extension is present on this X11 server. /// /// Every extension has a unique `major_opcode` to identify requests, the minor /// opcodes and request formats are extension-specific. If the extension provides /// events and errors, the `first_event` and `first_error` fields in the reply are /// set accordingly. /// /// There should rarely be a need to use this request directly, XCB provides the /// `xcb_get_extension_data` function instead. /// /// # Fields /// /// * `name_len` - The length of `name` in bytes. /// * `name` - The name of the extension to query, for example "RANDR". This is case /// sensitive! /// /// # See /// /// * `xdpyinfo`: program /// * `xcb_get_extension_data`: function fn query_extension<'c, 'input>(&'c self, name: &'input [u8]) -> Result, ConnectionError> { query_extension(self, name) } fn list_extensions(&self) -> Result, ConnectionError> { list_extensions(self) } fn change_keyboard_mapping<'c, 'input>(&'c self, keycode_count: u8, first_keycode: Keycode, keysyms_per_keycode: u8, keysyms: &'input [Keysym]) -> Result, ConnectionError> { change_keyboard_mapping(self, keycode_count, first_keycode, keysyms_per_keycode, keysyms) } fn get_keyboard_mapping(&self, first_keycode: Keycode, count: u8) -> Result, ConnectionError> { get_keyboard_mapping(self, first_keycode, count) } fn change_keyboard_control<'c, 'input>(&'c self, value_list: &'input ChangeKeyboardControlAux) -> Result, ConnectionError> { change_keyboard_control(self, value_list) } fn get_keyboard_control(&self) -> Result, ConnectionError> { get_keyboard_control(self) } fn bell(&self, percent: i8) -> Result, ConnectionError> { bell(self, percent) } fn change_pointer_control(&self, acceleration_numerator: i16, acceleration_denominator: i16, threshold: i16, do_acceleration: bool, do_threshold: bool) -> Result, ConnectionError> { change_pointer_control(self, acceleration_numerator, acceleration_denominator, threshold, do_acceleration, do_threshold) } fn get_pointer_control(&self) -> Result, ConnectionError> { get_pointer_control(self) } fn set_screen_saver(&self, timeout: i16, interval: i16, prefer_blanking: Blanking, allow_exposures: Exposures) -> Result, ConnectionError> { set_screen_saver(self, timeout, interval, prefer_blanking, allow_exposures) } fn get_screen_saver(&self) -> Result, ConnectionError> { get_screen_saver(self) } fn change_hosts<'c, 'input>(&'c self, mode: HostMode, family: Family, address: &'input [u8]) -> Result, ConnectionError> { change_hosts(self, mode, family, address) } fn list_hosts(&self) -> Result, ConnectionError> { list_hosts(self) } fn set_access_control(&self, mode: AccessControl) -> Result, ConnectionError> { set_access_control(self, mode) } fn set_close_down_mode(&self, mode: CloseDown) -> Result, ConnectionError> { set_close_down_mode(self, mode) } /// kills a client. /// /// Forces a close down of the client that created the specified `resource`. /// /// # Fields /// /// * `resource` - Any resource belonging to the client (for example a Window), used to identify /// the client connection. /// /// The special value of `XCB_KILL_ALL_TEMPORARY`, the resources of all clients /// that have terminated in `RetainTemporary` (TODO) are destroyed. /// /// # Errors /// /// * `Value` - The specified `resource` does not exist. /// /// # See /// /// * `xkill`: program fn kill_client(&self, resource: A) -> Result, ConnectionError> where A: Into, { kill_client(self, resource) } fn rotate_properties<'c, 'input>(&'c self, window: Window, delta: i16, atoms: &'input [Atom]) -> Result, ConnectionError> { rotate_properties(self, window, delta, atoms) } fn force_screen_saver(&self, mode: ScreenSaver) -> Result, ConnectionError> { force_screen_saver(self, mode) } fn set_pointer_mapping<'c, 'input>(&'c self, map: &'input [u8]) -> Result, ConnectionError> { set_pointer_mapping(self, map) } fn get_pointer_mapping(&self) -> Result, ConnectionError> { get_pointer_mapping(self) } fn set_modifier_mapping<'c, 'input>(&'c self, keycodes: &'input [Keycode]) -> Result, ConnectionError> { set_modifier_mapping(self, keycodes) } fn get_modifier_mapping(&self) -> Result, ConnectionError> { get_modifier_mapping(self) } fn no_operation(&self) -> Result, ConnectionError> { no_operation(self) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xselinux.rs010064400017500001750000003021011402220031600154760ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `SELinux` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "SELinux"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 0); /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest { pub client_major: u8, pub client_minor: u8, } impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let client_major_bytes = self.client_major.serialize(); let client_minor_bytes = self.client_minor.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, client_major_bytes[0], client_minor_bytes[0], 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (client_major, remaining) = u8::try_parse(value)?; let (client_minor, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(QueryVersionRequest { client_major, client_minor, }) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn, client_major: u8, client_minor: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest { client_major, client_minor, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub server_major: u16, pub server_minor: u16, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (server_major, remaining) = u16::try_parse(remaining)?; let (server_minor, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, server_major, server_minor }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetDeviceCreateContext request pub const SET_DEVICE_CREATE_CONTEXT_REQUEST: u8 = 1; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetDeviceCreateContextRequest<'input> { pub context: Cow<'input, [u8]>, } impl<'input> SetDeviceCreateContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_len = u32::try_from(self.context.len()).expect("`context` has too many elements"); let context_len_bytes = context_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_CREATE_CONTEXT_REQUEST, 0, 0, context_len_bytes[0], context_len_bytes[1], context_len_bytes[2], context_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.context.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.context, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_DEVICE_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_len, remaining) = u32::try_parse(value)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let _ = remaining; Ok(SetDeviceCreateContextRequest { context: Cow::Borrowed(context), }) } /// Clone all borrowed data in this SetDeviceCreateContextRequest. pub fn into_owned(self) -> SetDeviceCreateContextRequest<'static> { SetDeviceCreateContextRequest { context: Cow::Owned(self.context.into_owned()), } } } impl<'input> Request for SetDeviceCreateContextRequest<'input> { type Reply = (); } pub fn set_device_create_context<'c, 'input, Conn>(conn: &'c Conn, context: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetDeviceCreateContextRequest { context: Cow::Borrowed(context), }; request0.send(conn) } /// Opcode for the GetDeviceCreateContext request pub const GET_DEVICE_CREATE_CONTEXT_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceCreateContextRequest; impl GetDeviceCreateContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_CREATE_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetDeviceCreateContextRequest ) } } impl Request for GetDeviceCreateContextRequest { type Reply = GetDeviceCreateContextReply; } pub fn get_device_create_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceCreateContextRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceCreateContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetDeviceCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceCreateContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceCreateContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the SetDeviceContext request pub const SET_DEVICE_CONTEXT_REQUEST: u8 = 3; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetDeviceContextRequest<'input> { pub device: u32, pub context: Cow<'input, [u8]>, } impl<'input> SetDeviceContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_bytes = self.device.serialize(); let context_len = u32::try_from(self.context.len()).expect("`context` has too many elements"); let context_len_bytes = context_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_DEVICE_CONTEXT_REQUEST, 0, 0, device_bytes[0], device_bytes[1], device_bytes[2], device_bytes[3], context_len_bytes[0], context_len_bytes[1], context_len_bytes[2], context_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.context.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.context, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_DEVICE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (device, remaining) = u32::try_parse(value)?; let (context_len, remaining) = u32::try_parse(remaining)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let _ = remaining; Ok(SetDeviceContextRequest { device, context: Cow::Borrowed(context), }) } /// Clone all borrowed data in this SetDeviceContextRequest. pub fn into_owned(self) -> SetDeviceContextRequest<'static> { SetDeviceContextRequest { device: self.device, context: Cow::Owned(self.context.into_owned()), } } } impl<'input> Request for SetDeviceContextRequest<'input> { type Reply = (); } pub fn set_device_context<'c, 'input, Conn>(conn: &'c Conn, device: u32, context: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetDeviceContextRequest { device, context: Cow::Borrowed(context), }; request0.send(conn) } /// Opcode for the GetDeviceContext request pub const GET_DEVICE_CONTEXT_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetDeviceContextRequest { pub device: u32, } impl GetDeviceContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let device_bytes = self.device.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_DEVICE_CONTEXT_REQUEST, 0, 0, device_bytes[0], device_bytes[1], device_bytes[2], device_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_DEVICE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (device, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetDeviceContextRequest { device, }) } } impl Request for GetDeviceContextRequest { type Reply = GetDeviceContextReply; } pub fn get_device_context(conn: &Conn, device: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetDeviceContextRequest { device, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetDeviceContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetDeviceContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetDeviceContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the SetWindowCreateContext request pub const SET_WINDOW_CREATE_CONTEXT_REQUEST: u8 = 5; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetWindowCreateContextRequest<'input> { pub context: Cow<'input, [u8]>, } impl<'input> SetWindowCreateContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_len = u32::try_from(self.context.len()).expect("`context` has too many elements"); let context_len_bytes = context_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_WINDOW_CREATE_CONTEXT_REQUEST, 0, 0, context_len_bytes[0], context_len_bytes[1], context_len_bytes[2], context_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.context.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.context, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_WINDOW_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_len, remaining) = u32::try_parse(value)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let _ = remaining; Ok(SetWindowCreateContextRequest { context: Cow::Borrowed(context), }) } /// Clone all borrowed data in this SetWindowCreateContextRequest. pub fn into_owned(self) -> SetWindowCreateContextRequest<'static> { SetWindowCreateContextRequest { context: Cow::Owned(self.context.into_owned()), } } } impl<'input> Request for SetWindowCreateContextRequest<'input> { type Reply = (); } pub fn set_window_create_context<'c, 'input, Conn>(conn: &'c Conn, context: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetWindowCreateContextRequest { context: Cow::Borrowed(context), }; request0.send(conn) } /// Opcode for the GetWindowCreateContext request pub const GET_WINDOW_CREATE_CONTEXT_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetWindowCreateContextRequest; impl GetWindowCreateContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_WINDOW_CREATE_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_WINDOW_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetWindowCreateContextRequest ) } } impl Request for GetWindowCreateContextRequest { type Reply = GetWindowCreateContextReply; } pub fn get_window_create_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetWindowCreateContextRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetWindowCreateContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetWindowCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetWindowCreateContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetWindowCreateContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the GetWindowContext request pub const GET_WINDOW_CONTEXT_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetWindowContextRequest { pub window: xproto::Window, } impl GetWindowContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_WINDOW_CONTEXT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_WINDOW_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(GetWindowContextRequest { window, }) } } impl Request for GetWindowContextRequest { type Reply = GetWindowContextReply; } pub fn get_window_context(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetWindowContextRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetWindowContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetWindowContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetWindowContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetWindowContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListItem { pub name: xproto::Atom, pub object_context: Vec, pub data_context: Vec, } impl TryParse for ListItem { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (object_context_len, remaining) = u32::try_parse(remaining)?; let (data_context_len, remaining) = u32::try_parse(remaining)?; let (object_context, remaining) = crate::x11_utils::parse_u8_list(remaining, object_context_len.try_to_usize()?)?; let object_context = object_context.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (data_context, remaining) = crate::x11_utils::parse_u8_list(remaining, data_context_len.try_to_usize()?)?; let data_context = data_context.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = ListItem { name, object_context, data_context }; Ok((result, remaining)) } } impl Serialize for ListItem { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.name.serialize_into(bytes); let object_context_len = u32::try_from(self.object_context.len()).expect("`object_context` has too many elements"); object_context_len.serialize_into(bytes); let data_context_len = u32::try_from(self.data_context.len()).expect("`data_context` has too many elements"); data_context_len.serialize_into(bytes); bytes.extend_from_slice(&self.object_context); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); bytes.extend_from_slice(&self.data_context); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl ListItem { /// Get the value of the `object_context_len` field. /// /// The `object_context_len` field is used as the length field of the `object_context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn object_context_len(&self) -> u32 { self.object_context.len() .try_into().unwrap() } /// Get the value of the `data_context_len` field. /// /// The `data_context_len` field is used as the length field of the `data_context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn data_context_len(&self) -> u32 { self.data_context.len() .try_into().unwrap() } } /// Opcode for the SetPropertyCreateContext request pub const SET_PROPERTY_CREATE_CONTEXT_REQUEST: u8 = 8; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetPropertyCreateContextRequest<'input> { pub context: Cow<'input, [u8]>, } impl<'input> SetPropertyCreateContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_len = u32::try_from(self.context.len()).expect("`context` has too many elements"); let context_len_bytes = context_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PROPERTY_CREATE_CONTEXT_REQUEST, 0, 0, context_len_bytes[0], context_len_bytes[1], context_len_bytes[2], context_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.context.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.context, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_PROPERTY_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_len, remaining) = u32::try_parse(value)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let _ = remaining; Ok(SetPropertyCreateContextRequest { context: Cow::Borrowed(context), }) } /// Clone all borrowed data in this SetPropertyCreateContextRequest. pub fn into_owned(self) -> SetPropertyCreateContextRequest<'static> { SetPropertyCreateContextRequest { context: Cow::Owned(self.context.into_owned()), } } } impl<'input> Request for SetPropertyCreateContextRequest<'input> { type Reply = (); } pub fn set_property_create_context<'c, 'input, Conn>(conn: &'c Conn, context: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPropertyCreateContextRequest { context: Cow::Borrowed(context), }; request0.send(conn) } /// Opcode for the GetPropertyCreateContext request pub const GET_PROPERTY_CREATE_CONTEXT_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPropertyCreateContextRequest; impl GetPropertyCreateContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_PROPERTY_CREATE_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PROPERTY_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetPropertyCreateContextRequest ) } } impl Request for GetPropertyCreateContextRequest { type Reply = GetPropertyCreateContextReply; } pub fn get_property_create_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPropertyCreateContextRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetPropertyCreateContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetPropertyCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPropertyCreateContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPropertyCreateContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the SetPropertyUseContext request pub const SET_PROPERTY_USE_CONTEXT_REQUEST: u8 = 10; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetPropertyUseContextRequest<'input> { pub context: Cow<'input, [u8]>, } impl<'input> SetPropertyUseContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_len = u32::try_from(self.context.len()).expect("`context` has too many elements"); let context_len_bytes = context_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PROPERTY_USE_CONTEXT_REQUEST, 0, 0, context_len_bytes[0], context_len_bytes[1], context_len_bytes[2], context_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.context.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.context, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_PROPERTY_USE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_len, remaining) = u32::try_parse(value)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let _ = remaining; Ok(SetPropertyUseContextRequest { context: Cow::Borrowed(context), }) } /// Clone all borrowed data in this SetPropertyUseContextRequest. pub fn into_owned(self) -> SetPropertyUseContextRequest<'static> { SetPropertyUseContextRequest { context: Cow::Owned(self.context.into_owned()), } } } impl<'input> Request for SetPropertyUseContextRequest<'input> { type Reply = (); } pub fn set_property_use_context<'c, 'input, Conn>(conn: &'c Conn, context: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPropertyUseContextRequest { context: Cow::Borrowed(context), }; request0.send(conn) } /// Opcode for the GetPropertyUseContext request pub const GET_PROPERTY_USE_CONTEXT_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPropertyUseContextRequest; impl GetPropertyUseContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_PROPERTY_USE_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PROPERTY_USE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetPropertyUseContextRequest ) } } impl Request for GetPropertyUseContextRequest { type Reply = GetPropertyUseContextReply; } pub fn get_property_use_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPropertyUseContextRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetPropertyUseContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetPropertyUseContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPropertyUseContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPropertyUseContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the GetPropertyContext request pub const GET_PROPERTY_CONTEXT_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPropertyContextRequest { pub window: xproto::Window, pub property: xproto::Atom, } impl GetPropertyContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let property_bytes = self.property.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PROPERTY_CONTEXT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PROPERTY_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(GetPropertyContextRequest { window, property, }) } } impl Request for GetPropertyContextRequest { type Reply = GetPropertyContextReply; } pub fn get_property_context(conn: &Conn, window: xproto::Window, property: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPropertyContextRequest { window, property, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetPropertyContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetPropertyContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPropertyContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPropertyContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the GetPropertyDataContext request pub const GET_PROPERTY_DATA_CONTEXT_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPropertyDataContextRequest { pub window: xproto::Window, pub property: xproto::Atom, } impl GetPropertyDataContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let property_bytes = self.property.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PROPERTY_DATA_CONTEXT_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], property_bytes[0], property_bytes[1], property_bytes[2], property_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PROPERTY_DATA_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (property, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(GetPropertyDataContextRequest { window, property, }) } } impl Request for GetPropertyDataContextRequest { type Reply = GetPropertyDataContextReply; } pub fn get_property_data_context(conn: &Conn, window: xproto::Window, property: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPropertyDataContextRequest { window, property, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetPropertyDataContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetPropertyDataContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPropertyDataContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetPropertyDataContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the ListProperties request pub const LIST_PROPERTIES_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListPropertiesRequest { pub window: xproto::Window, } impl ListPropertiesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_PROPERTIES_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_PROPERTIES_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(ListPropertiesRequest { window, }) } } impl Request for ListPropertiesRequest { type Reply = ListPropertiesReply; } pub fn list_properties(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListPropertiesRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListPropertiesReply { pub sequence: u16, pub length: u32, pub properties: Vec, } impl TryParse for ListPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (properties_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (properties, remaining) = crate::x11_utils::parse_list::(remaining, properties_len.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListPropertiesReply { sequence, length, properties }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListPropertiesReply { /// Get the value of the `properties_len` field. /// /// The `properties_len` field is used as the length field of the `properties` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn properties_len(&self) -> u32 { self.properties.len() .try_into().unwrap() } } /// Opcode for the SetSelectionCreateContext request pub const SET_SELECTION_CREATE_CONTEXT_REQUEST: u8 = 15; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetSelectionCreateContextRequest<'input> { pub context: Cow<'input, [u8]>, } impl<'input> SetSelectionCreateContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_len = u32::try_from(self.context.len()).expect("`context` has too many elements"); let context_len_bytes = context_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_SELECTION_CREATE_CONTEXT_REQUEST, 0, 0, context_len_bytes[0], context_len_bytes[1], context_len_bytes[2], context_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.context.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.context, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_SELECTION_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_len, remaining) = u32::try_parse(value)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let _ = remaining; Ok(SetSelectionCreateContextRequest { context: Cow::Borrowed(context), }) } /// Clone all borrowed data in this SetSelectionCreateContextRequest. pub fn into_owned(self) -> SetSelectionCreateContextRequest<'static> { SetSelectionCreateContextRequest { context: Cow::Owned(self.context.into_owned()), } } } impl<'input> Request for SetSelectionCreateContextRequest<'input> { type Reply = (); } pub fn set_selection_create_context<'c, 'input, Conn>(conn: &'c Conn, context: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetSelectionCreateContextRequest { context: Cow::Borrowed(context), }; request0.send(conn) } /// Opcode for the GetSelectionCreateContext request pub const GET_SELECTION_CREATE_CONTEXT_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetSelectionCreateContextRequest; impl GetSelectionCreateContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_SELECTION_CREATE_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SELECTION_CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetSelectionCreateContextRequest ) } } impl Request for GetSelectionCreateContextRequest { type Reply = GetSelectionCreateContextReply; } pub fn get_selection_create_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetSelectionCreateContextRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetSelectionCreateContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetSelectionCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetSelectionCreateContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetSelectionCreateContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the SetSelectionUseContext request pub const SET_SELECTION_USE_CONTEXT_REQUEST: u8 = 17; #[derive(Debug, Clone, PartialEq, Eq)] pub struct SetSelectionUseContextRequest<'input> { pub context: Cow<'input, [u8]>, } impl<'input> SetSelectionUseContextRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_len = u32::try_from(self.context.len()).expect("`context` has too many elements"); let context_len_bytes = context_len.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_SELECTION_USE_CONTEXT_REQUEST, 0, 0, context_len_bytes[0], context_len_bytes[1], context_len_bytes[2], context_len_bytes[3], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.context.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.context, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != SET_SELECTION_USE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_len, remaining) = u32::try_parse(value)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let _ = remaining; Ok(SetSelectionUseContextRequest { context: Cow::Borrowed(context), }) } /// Clone all borrowed data in this SetSelectionUseContextRequest. pub fn into_owned(self) -> SetSelectionUseContextRequest<'static> { SetSelectionUseContextRequest { context: Cow::Owned(self.context.into_owned()), } } } impl<'input> Request for SetSelectionUseContextRequest<'input> { type Reply = (); } pub fn set_selection_use_context<'c, 'input, Conn>(conn: &'c Conn, context: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetSelectionUseContextRequest { context: Cow::Borrowed(context), }; request0.send(conn) } /// Opcode for the GetSelectionUseContext request pub const GET_SELECTION_USE_CONTEXT_REQUEST: u8 = 18; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetSelectionUseContextRequest; impl GetSelectionUseContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, GET_SELECTION_USE_CONTEXT_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SELECTION_USE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(GetSelectionUseContextRequest ) } } impl Request for GetSelectionUseContextRequest { type Reply = GetSelectionUseContextReply; } pub fn get_selection_use_context(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetSelectionUseContextRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetSelectionUseContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetSelectionUseContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetSelectionUseContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetSelectionUseContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the GetSelectionContext request pub const GET_SELECTION_CONTEXT_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetSelectionContextRequest { pub selection: xproto::Atom, } impl GetSelectionContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let selection_bytes = self.selection.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SELECTION_CONTEXT_REQUEST, 0, 0, selection_bytes[0], selection_bytes[1], selection_bytes[2], selection_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SELECTION_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (selection, remaining) = xproto::Atom::try_parse(value)?; let _ = remaining; Ok(GetSelectionContextRequest { selection, }) } } impl Request for GetSelectionContextRequest { type Reply = GetSelectionContextReply; } pub fn get_selection_context(conn: &Conn, selection: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetSelectionContextRequest { selection, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetSelectionContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetSelectionContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetSelectionContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetSelectionContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the GetSelectionDataContext request pub const GET_SELECTION_DATA_CONTEXT_REQUEST: u8 = 20; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetSelectionDataContextRequest { pub selection: xproto::Atom, } impl GetSelectionDataContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let selection_bytes = self.selection.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_SELECTION_DATA_CONTEXT_REQUEST, 0, 0, selection_bytes[0], selection_bytes[1], selection_bytes[2], selection_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_SELECTION_DATA_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (selection, remaining) = xproto::Atom::try_parse(value)?; let _ = remaining; Ok(GetSelectionDataContextRequest { selection, }) } } impl Request for GetSelectionDataContextRequest { type Reply = GetSelectionDataContextReply; } pub fn get_selection_data_context(conn: &Conn, selection: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetSelectionDataContextRequest { selection, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetSelectionDataContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetSelectionDataContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetSelectionDataContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetSelectionDataContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Opcode for the ListSelections request pub const LIST_SELECTIONS_REQUEST: u8 = 21; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListSelectionsRequest; impl ListSelectionsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, LIST_SELECTIONS_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_SELECTIONS_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(ListSelectionsRequest ) } } impl Request for ListSelectionsRequest { type Reply = ListSelectionsReply; } pub fn list_selections(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListSelectionsRequest; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListSelectionsReply { pub sequence: u16, pub length: u32, pub selections: Vec, } impl TryParse for ListSelectionsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (selections_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (selections, remaining) = crate::x11_utils::parse_list::(remaining, selections_len.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListSelectionsReply { sequence, length, selections }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListSelectionsReply { /// Get the value of the `selections_len` field. /// /// The `selections_len` field is used as the length field of the `selections` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn selections_len(&self) -> u32 { self.selections.len() .try_into().unwrap() } } /// Opcode for the GetClientContext request pub const GET_CLIENT_CONTEXT_REQUEST: u8 = 22; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetClientContextRequest { pub resource: u32, } impl GetClientContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let resource_bytes = self.resource.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_CLIENT_CONTEXT_REQUEST, 0, 0, resource_bytes[0], resource_bytes[1], resource_bytes[2], resource_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_CLIENT_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (resource, remaining) = u32::try_parse(value)?; let _ = remaining; Ok(GetClientContextRequest { resource, }) } } impl Request for GetClientContextRequest { type Reply = GetClientContextReply; } pub fn get_client_context(conn: &Conn, resource: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetClientContextRequest { resource, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetClientContextReply { pub sequence: u16, pub length: u32, pub context: Vec, } impl TryParse for GetClientContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (context_len, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (context, remaining) = crate::x11_utils::parse_u8_list(remaining, context_len.try_to_usize()?)?; let context = context.to_vec(); if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetClientContextReply { sequence, length, context }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl GetClientContextReply { /// Get the value of the `context_len` field. /// /// The `context_len` field is used as the length field of the `context` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn context_len(&self) -> u32 { self.context.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xselinux_query_version(&self, client_major: u8, client_minor: u8) -> Result, ConnectionError> { query_version(self, client_major, client_minor) } fn xselinux_set_device_create_context<'c, 'input>(&'c self, context: &'input [u8]) -> Result, ConnectionError> { set_device_create_context(self, context) } fn xselinux_get_device_create_context(&self) -> Result, ConnectionError> { get_device_create_context(self) } fn xselinux_set_device_context<'c, 'input>(&'c self, device: u32, context: &'input [u8]) -> Result, ConnectionError> { set_device_context(self, device, context) } fn xselinux_get_device_context(&self, device: u32) -> Result, ConnectionError> { get_device_context(self, device) } fn xselinux_set_window_create_context<'c, 'input>(&'c self, context: &'input [u8]) -> Result, ConnectionError> { set_window_create_context(self, context) } fn xselinux_get_window_create_context(&self) -> Result, ConnectionError> { get_window_create_context(self) } fn xselinux_get_window_context(&self, window: xproto::Window) -> Result, ConnectionError> { get_window_context(self, window) } fn xselinux_set_property_create_context<'c, 'input>(&'c self, context: &'input [u8]) -> Result, ConnectionError> { set_property_create_context(self, context) } fn xselinux_get_property_create_context(&self) -> Result, ConnectionError> { get_property_create_context(self) } fn xselinux_set_property_use_context<'c, 'input>(&'c self, context: &'input [u8]) -> Result, ConnectionError> { set_property_use_context(self, context) } fn xselinux_get_property_use_context(&self) -> Result, ConnectionError> { get_property_use_context(self) } fn xselinux_get_property_context(&self, window: xproto::Window, property: xproto::Atom) -> Result, ConnectionError> { get_property_context(self, window, property) } fn xselinux_get_property_data_context(&self, window: xproto::Window, property: xproto::Atom) -> Result, ConnectionError> { get_property_data_context(self, window, property) } fn xselinux_list_properties(&self, window: xproto::Window) -> Result, ConnectionError> { list_properties(self, window) } fn xselinux_set_selection_create_context<'c, 'input>(&'c self, context: &'input [u8]) -> Result, ConnectionError> { set_selection_create_context(self, context) } fn xselinux_get_selection_create_context(&self) -> Result, ConnectionError> { get_selection_create_context(self) } fn xselinux_set_selection_use_context<'c, 'input>(&'c self, context: &'input [u8]) -> Result, ConnectionError> { set_selection_use_context(self, context) } fn xselinux_get_selection_use_context(&self) -> Result, ConnectionError> { get_selection_use_context(self) } fn xselinux_get_selection_context(&self, selection: xproto::Atom) -> Result, ConnectionError> { get_selection_context(self, selection) } fn xselinux_get_selection_data_context(&self, selection: xproto::Atom) -> Result, ConnectionError> { get_selection_data_context(self, selection) } fn xselinux_list_selections(&self) -> Result, ConnectionError> { list_selections(self) } fn xselinux_get_client_context(&self, resource: u32) -> Result, ConnectionError> { get_client_context(self, resource) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xtest.rs010064400017500001750000000426531402220031600150030ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Test` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XTEST"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (2, 2); /// Opcode for the GetVersion request pub const GET_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVersionRequest { pub major_version: u8, pub minor_version: u16, } impl GetVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let major_version_bytes = self.major_version.serialize(); let minor_version_bytes = self.minor_version.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_VERSION_REQUEST, 0, 0, major_version_bytes[0], 0, minor_version_bytes[0], minor_version_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let (major_version, remaining) = u8::try_parse(value)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (minor_version, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(GetVersionRequest { major_version, minor_version, }) } } impl Request for GetVersionRequest { type Reply = GetVersionReply; } pub fn get_version(conn: &Conn, major_version: u8, minor_version: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetVersionRequest { major_version, minor_version, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVersionReply { pub major_version: u8, pub sequence: u16, pub length: u32, pub minor_version: u16, } impl TryParse for GetVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (major_version, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (minor_version, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetVersionReply { major_version, sequence, length, minor_version }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct Cursor(bool); impl Cursor { pub const NONE: Self = Self(false); pub const CURRENT: Self = Self(true); } impl From for bool { #[inline] fn from(input: Cursor) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Cursor) -> Self { Some(input.0) } } impl From for u8 { #[inline] fn from(input: Cursor) -> Self { u8::from(input.0) } } impl From for Option { #[inline] fn from(input: Cursor) -> Self { Some(u8::from(input.0)) } } impl From for u16 { #[inline] fn from(input: Cursor) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Cursor) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Cursor) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Cursor) -> Self { Some(u32::from(input.0)) } } impl From for Cursor { #[inline] fn from(value: bool) -> Self { Self(value) } } impl std::fmt::Debug for Cursor { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::NONE.0.into(), "NONE", "None"), (Self::CURRENT.0.into(), "CURRENT", "Current"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } /// Opcode for the CompareCursor request pub const COMPARE_CURSOR_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CompareCursorRequest { pub window: xproto::Window, pub cursor: xproto::Cursor, } impl CompareCursorRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let cursor_bytes = self.cursor.serialize(); let mut request0 = vec![ extension_information.major_opcode, COMPARE_CURSOR_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], cursor_bytes[0], cursor_bytes[1], cursor_bytes[2], cursor_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != COMPARE_CURSOR_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?; let _ = remaining; Ok(CompareCursorRequest { window, cursor, }) } } impl Request for CompareCursorRequest { type Reply = CompareCursorReply; } pub fn compare_cursor(conn: &Conn, window: xproto::Window, cursor: xproto::Cursor) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CompareCursorRequest { window, cursor, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CompareCursorReply { pub same: bool, pub sequence: u16, pub length: u32, } impl TryParse for CompareCursorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (same, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CompareCursorReply { same, sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the FakeInput request pub const FAKE_INPUT_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FakeInputRequest { pub type_: u8, pub detail: u8, pub time: u32, pub root: xproto::Window, pub root_x: i16, pub root_y: i16, pub deviceid: u8, } impl FakeInputRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let type_bytes = self.type_.serialize(); let detail_bytes = self.detail.serialize(); let time_bytes = self.time.serialize(); let root_bytes = self.root.serialize(); let root_x_bytes = self.root_x.serialize(); let root_y_bytes = self.root_y.serialize(); let deviceid_bytes = self.deviceid.serialize(); let mut request0 = vec![ extension_information.major_opcode, FAKE_INPUT_REQUEST, 0, 0, type_bytes[0], detail_bytes[0], 0, 0, time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], root_bytes[0], root_bytes[1], root_bytes[2], root_bytes[3], 0, 0, 0, 0, 0, 0, 0, 0, root_x_bytes[0], root_x_bytes[1], root_y_bytes[0], root_y_bytes[1], 0, 0, 0, 0, 0, 0, 0, deviceid_bytes[0], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != FAKE_INPUT_REQUEST { return Err(ParseError::InvalidValue); } let (type_, remaining) = u8::try_parse(value)?; let (detail, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (time, remaining) = u32::try_parse(remaining)?; let (root, remaining) = xproto::Window::try_parse(remaining)?; let remaining = remaining.get(8..).ok_or(ParseError::InsufficientData)?; let (root_x, remaining) = i16::try_parse(remaining)?; let (root_y, remaining) = i16::try_parse(remaining)?; let remaining = remaining.get(7..).ok_or(ParseError::InsufficientData)?; let (deviceid, remaining) = u8::try_parse(remaining)?; let _ = remaining; Ok(FakeInputRequest { type_, detail, time, root, root_x, root_y, deviceid, }) } } impl Request for FakeInputRequest { type Reply = (); } pub fn fake_input(conn: &Conn, type_: u8, detail: u8, time: u32, root: xproto::Window, root_x: i16, root_y: i16, deviceid: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = FakeInputRequest { type_, detail, time, root, root_x, root_y, deviceid, }; request0.send(conn) } /// Opcode for the GrabControl request pub const GRAB_CONTROL_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GrabControlRequest { pub impervious: bool, } impl GrabControlRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let impervious_bytes = self.impervious.serialize(); let mut request0 = vec![ extension_information.major_opcode, GRAB_CONTROL_REQUEST, 0, 0, impervious_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GRAB_CONTROL_REQUEST { return Err(ParseError::InvalidValue); } let (impervious, remaining) = bool::try_parse(value)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(GrabControlRequest { impervious, }) } } impl Request for GrabControlRequest { type Reply = (); } pub fn grab_control(conn: &Conn, impervious: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GrabControlRequest { impervious, }; request0.send(conn) } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xtest_get_version(&self, major_version: u8, minor_version: u16) -> Result, ConnectionError> { get_version(self, major_version, minor_version) } fn xtest_compare_cursor(&self, window: xproto::Window, cursor: xproto::Cursor) -> Result, ConnectionError> { compare_cursor(self, window, cursor) } fn xtest_fake_input(&self, type_: u8, detail: u8, time: u32, root: xproto::Window, root_x: i16, root_y: i16, deviceid: u8) -> Result, ConnectionError> { fake_input(self, type_, detail, time, root, root_x, root_y, deviceid) } fn xtest_grab_control(&self, impervious: bool) -> Result, ConnectionError> { grab_control(self, impervious) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xv.rs010064400017500001750000003756761402220031600143070ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `Xv` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::shm; use super::xproto; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XVideo"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (2, 2); pub type Port = u32; pub type Encoding = u32; #[derive(Clone, Copy, PartialEq, Eq)] pub struct Type(u8); impl Type { pub const INPUT_MASK: Self = Self(1 << 0); pub const OUTPUT_MASK: Self = Self(1 << 1); pub const VIDEO_MASK: Self = Self(1 << 2); pub const STILL_MASK: Self = Self(1 << 3); pub const IMAGE_MASK: Self = Self(1 << 4); } impl From for u8 { #[inline] fn from(input: Type) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: Type) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: Type) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: Type) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: Type) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: Type) -> Self { Some(u32::from(input.0)) } } impl From for Type { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for Type { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::INPUT_MASK.0.into(), "INPUT_MASK", "InputMask"), (Self::OUTPUT_MASK.0.into(), "OUTPUT_MASK", "OutputMask"), (Self::VIDEO_MASK.0.into(), "VIDEO_MASK", "VideoMask"), (Self::STILL_MASK.0.into(), "STILL_MASK", "StillMask"), (Self::IMAGE_MASK.0.into(), "IMAGE_MASK", "ImageMask"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(Type, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct ImageFormatInfoType(u8); impl ImageFormatInfoType { pub const RGB: Self = Self(0); pub const YUV: Self = Self(1); } impl From for u8 { #[inline] fn from(input: ImageFormatInfoType) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ImageFormatInfoType) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ImageFormatInfoType) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ImageFormatInfoType) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ImageFormatInfoType) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ImageFormatInfoType) -> Self { Some(u32::from(input.0)) } } impl From for ImageFormatInfoType { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ImageFormatInfoType { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::RGB.0.into(), "RGB", "RGB"), (Self::YUV.0.into(), "YUV", "YUV"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ImageFormatInfoFormat(u8); impl ImageFormatInfoFormat { pub const PACKED: Self = Self(0); pub const PLANAR: Self = Self(1); } impl From for u8 { #[inline] fn from(input: ImageFormatInfoFormat) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ImageFormatInfoFormat) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ImageFormatInfoFormat) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ImageFormatInfoFormat) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ImageFormatInfoFormat) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ImageFormatInfoFormat) -> Self { Some(u32::from(input.0)) } } impl From for ImageFormatInfoFormat { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ImageFormatInfoFormat { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::PACKED.0.into(), "PACKED", "Packed"), (Self::PLANAR.0.into(), "PLANAR", "Planar"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct AttributeFlag(u8); impl AttributeFlag { pub const GETTABLE: Self = Self(1 << 0); pub const SETTABLE: Self = Self(1 << 1); } impl From for u8 { #[inline] fn from(input: AttributeFlag) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: AttributeFlag) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: AttributeFlag) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: AttributeFlag) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: AttributeFlag) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: AttributeFlag) -> Self { Some(u32::from(input.0)) } } impl From for AttributeFlag { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for AttributeFlag { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::GETTABLE.0.into(), "GETTABLE", "Gettable"), (Self::SETTABLE.0.into(), "SETTABLE", "Settable"), ]; pretty_print_bitmask(fmt, self.0.into(), &variants) } } bitmask_binop!(AttributeFlag, u8); #[derive(Clone, Copy, PartialEq, Eq)] pub struct VideoNotifyReason(u8); impl VideoNotifyReason { pub const STARTED: Self = Self(0); pub const STOPPED: Self = Self(1); pub const BUSY: Self = Self(2); pub const PREEMPTED: Self = Self(3); pub const HARD_ERROR: Self = Self(4); } impl From for u8 { #[inline] fn from(input: VideoNotifyReason) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: VideoNotifyReason) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: VideoNotifyReason) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: VideoNotifyReason) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: VideoNotifyReason) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: VideoNotifyReason) -> Self { Some(u32::from(input.0)) } } impl From for VideoNotifyReason { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for VideoNotifyReason { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::STARTED.0.into(), "STARTED", "Started"), (Self::STOPPED.0.into(), "STOPPED", "Stopped"), (Self::BUSY.0.into(), "BUSY", "Busy"), (Self::PREEMPTED.0.into(), "PREEMPTED", "Preempted"), (Self::HARD_ERROR.0.into(), "HARD_ERROR", "HardError"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ScanlineOrder(u8); impl ScanlineOrder { pub const TOP_TO_BOTTOM: Self = Self(0); pub const BOTTOM_TO_TOP: Self = Self(1); } impl From for u8 { #[inline] fn from(input: ScanlineOrder) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: ScanlineOrder) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: ScanlineOrder) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: ScanlineOrder) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: ScanlineOrder) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: ScanlineOrder) -> Self { Some(u32::from(input.0)) } } impl From for ScanlineOrder { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for ScanlineOrder { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::TOP_TO_BOTTOM.0.into(), "TOP_TO_BOTTOM", "TopToBottom"), (Self::BOTTOM_TO_TOP.0.into(), "BOTTOM_TO_TOP", "BottomToTop"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct GrabPortStatus(u8); impl GrabPortStatus { pub const SUCCESS: Self = Self(0); pub const BAD_EXTENSION: Self = Self(1); pub const ALREADY_GRABBED: Self = Self(2); pub const INVALID_TIME: Self = Self(3); pub const BAD_REPLY: Self = Self(4); pub const BAD_ALLOC: Self = Self(5); } impl From for u8 { #[inline] fn from(input: GrabPortStatus) -> Self { input.0 } } impl From for Option { #[inline] fn from(input: GrabPortStatus) -> Self { Some(input.0) } } impl From for u16 { #[inline] fn from(input: GrabPortStatus) -> Self { u16::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabPortStatus) -> Self { Some(u16::from(input.0)) } } impl From for u32 { #[inline] fn from(input: GrabPortStatus) -> Self { u32::from(input.0) } } impl From for Option { #[inline] fn from(input: GrabPortStatus) -> Self { Some(u32::from(input.0)) } } impl From for GrabPortStatus { #[inline] fn from(value: u8) -> Self { Self(value) } } impl std::fmt::Debug for GrabPortStatus { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let variants = [ (Self::SUCCESS.0.into(), "SUCCESS", "Success"), (Self::BAD_EXTENSION.0.into(), "BAD_EXTENSION", "BadExtension"), (Self::ALREADY_GRABBED.0.into(), "ALREADY_GRABBED", "AlreadyGrabbed"), (Self::INVALID_TIME.0.into(), "INVALID_TIME", "InvalidTime"), (Self::BAD_REPLY.0.into(), "BAD_REPLY", "BadReply"), (Self::BAD_ALLOC.0.into(), "BAD_ALLOC", "BadAlloc"), ]; pretty_print_enum(fmt, self.0.into(), &variants) } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Rational { pub numerator: i32, pub denominator: i32, } impl TryParse for Rational { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (numerator, remaining) = i32::try_parse(remaining)?; let (denominator, remaining) = i32::try_parse(remaining)?; let result = Rational { numerator, denominator }; Ok((result, remaining)) } } impl Serialize for Rational { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let numerator_bytes = self.numerator.serialize(); let denominator_bytes = self.denominator.serialize(); [ numerator_bytes[0], numerator_bytes[1], numerator_bytes[2], numerator_bytes[3], denominator_bytes[0], denominator_bytes[1], denominator_bytes[2], denominator_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.numerator.serialize_into(bytes); self.denominator.serialize_into(bytes); } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Format { pub visual: xproto::Visualid, pub depth: u8, } impl TryParse for Format { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let result = Format { visual, depth }; Ok((result, remaining)) } } impl Serialize for Format { type Bytes = [u8; 8]; fn serialize(&self) -> [u8; 8] { let visual_bytes = self.visual.serialize(); let depth_bytes = self.depth.serialize(); [ visual_bytes[0], visual_bytes[1], visual_bytes[2], visual_bytes[3], depth_bytes[0], 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(8); self.visual.serialize_into(bytes); self.depth.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct AdaptorInfo { pub base_id: Port, pub num_ports: u16, pub type_: u8, pub name: Vec, pub formats: Vec, } impl TryParse for AdaptorInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (base_id, remaining) = Port::try_parse(remaining)?; let (name_size, remaining) = u16::try_parse(remaining)?; let (num_ports, remaining) = u16::try_parse(remaining)?; let (num_formats, remaining) = u16::try_parse(remaining)?; let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_size.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let (formats, remaining) = crate::x11_utils::parse_list::(remaining, num_formats.try_to_usize()?)?; let result = AdaptorInfo { base_id, num_ports, type_, name, formats }; Ok((result, remaining)) } } impl Serialize for AdaptorInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(12); self.base_id.serialize_into(bytes); let name_size = u16::try_from(self.name.len()).expect("`name` has too many elements"); name_size.serialize_into(bytes); self.num_ports.serialize_into(bytes); let num_formats = u16::try_from(self.formats.len()).expect("`formats` has too many elements"); num_formats.serialize_into(bytes); self.type_.serialize_into(bytes); bytes.extend_from_slice(&[0; 1]); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); self.formats.serialize_into(bytes); } } impl AdaptorInfo { /// Get the value of the `name_size` field. /// /// The `name_size` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_size(&self) -> u16 { self.name.len() .try_into().unwrap() } /// Get the value of the `num_formats` field. /// /// The `num_formats` field is used as the length field of the `formats` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_formats(&self) -> u16 { self.formats.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct EncodingInfo { pub encoding: Encoding, pub width: u16, pub height: u16, pub rate: Rational, pub name: Vec, } impl TryParse for EncodingInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (encoding, remaining) = Encoding::try_parse(remaining)?; let (name_size, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (rate, remaining) = Rational::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_size.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = EncodingInfo { encoding, width, height, rate, name }; Ok((result, remaining)) } } impl Serialize for EncodingInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(20); self.encoding.serialize_into(bytes); let name_size = u16::try_from(self.name.len()).expect("`name` has too many elements"); name_size.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.rate.serialize_into(bytes); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl EncodingInfo { /// Get the value of the `name_size` field. /// /// The `name_size` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn name_size(&self) -> u16 { self.name.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Image { pub id: u32, pub width: u16, pub height: u16, pub pitches: Vec, pub offsets: Vec, pub data: Vec, } impl TryParse for Image { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (id, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (data_size, remaining) = u32::try_parse(remaining)?; let (num_planes, remaining) = u32::try_parse(remaining)?; let (pitches, remaining) = crate::x11_utils::parse_list::(remaining, num_planes.try_to_usize()?)?; let (offsets, remaining) = crate::x11_utils::parse_list::(remaining, num_planes.try_to_usize()?)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, data_size.try_to_usize()?)?; let data = data.to_vec(); let result = Image { id, width, height, pitches, offsets, data }; Ok((result, remaining)) } } impl Serialize for Image { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); self.id.serialize_into(bytes); self.width.serialize_into(bytes); self.height.serialize_into(bytes); let data_size = u32::try_from(self.data.len()).expect("`data` has too many elements"); data_size.serialize_into(bytes); let num_planes = u32::try_from(self.pitches.len()).expect("`pitches` has too many elements"); num_planes.serialize_into(bytes); self.pitches.serialize_into(bytes); assert_eq!(self.offsets.len(), usize::try_from(num_planes).unwrap(), "`offsets` has an incorrect length"); self.offsets.serialize_into(bytes); bytes.extend_from_slice(&self.data); } } impl Image { /// Get the value of the `data_size` field. /// /// The `data_size` field is used as the length field of the `data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn data_size(&self) -> u32 { self.data.len() .try_into().unwrap() } /// Get the value of the `num_planes` field. /// /// The `num_planes` field is used as the length field of the `pitches` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_planes(&self) -> u32 { self.pitches.len() .try_into().unwrap() } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct AttributeInfo { pub flags: u32, pub min: i32, pub max: i32, pub name: Vec, } impl TryParse for AttributeInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let value = remaining; let (flags, remaining) = u32::try_parse(remaining)?; let (min, remaining) = i32::try_parse(remaining)?; let (max, remaining) = i32::try_parse(remaining)?; let (size, remaining) = u32::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, size.try_to_usize()?)?; let name = name.to_vec(); // Align offset to multiple of 4 let offset = remaining.as_ptr() as usize - value.as_ptr() as usize; let misalignment = (4 - (offset % 4)) % 4; let remaining = remaining.get(misalignment..).ok_or(ParseError::InsufficientData)?; let result = AttributeInfo { flags, min, max, name }; Ok((result, remaining)) } } impl Serialize for AttributeInfo { type Bytes = Vec; fn serialize(&self) -> Vec { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(16); self.flags.serialize_into(bytes); self.min.serialize_into(bytes); self.max.serialize_into(bytes); let size = u32::try_from(self.name.len()).expect("`name` has too many elements"); size.serialize_into(bytes); bytes.extend_from_slice(&self.name); bytes.extend_from_slice(&[0; 3][..(4 - (bytes.len() % 4)) % 4]); } } impl AttributeInfo { /// Get the value of the `size` field. /// /// The `size` field is used as the length field of the `name` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn size(&self) -> u32 { self.name.len() .try_into().unwrap() } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ImageFormatInfo { pub id: u32, pub type_: ImageFormatInfoType, pub byte_order: xproto::ImageOrder, pub guid: [u8; 16], pub bpp: u8, pub num_planes: u8, pub depth: u8, pub red_mask: u32, pub green_mask: u32, pub blue_mask: u32, pub format: ImageFormatInfoFormat, pub y_sample_bits: u32, pub u_sample_bits: u32, pub v_sample_bits: u32, pub vhorz_y_period: u32, pub vhorz_u_period: u32, pub vhorz_v_period: u32, pub vvert_y_period: u32, pub vvert_u_period: u32, pub vvert_v_period: u32, pub vcomp_order: [u8; 32], pub vscanline_order: ScanlineOrder, } impl TryParse for ImageFormatInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (id, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u8::try_parse(remaining)?; let (byte_order, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (guid, remaining) = crate::x11_utils::parse_u8_list(remaining, 16)?; let guid = <[u8; 16]>::try_from(guid).unwrap(); let (bpp, remaining) = u8::try_parse(remaining)?; let (num_planes, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::InsufficientData)?; let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (red_mask, remaining) = u32::try_parse(remaining)?; let (green_mask, remaining) = u32::try_parse(remaining)?; let (blue_mask, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let (y_sample_bits, remaining) = u32::try_parse(remaining)?; let (u_sample_bits, remaining) = u32::try_parse(remaining)?; let (v_sample_bits, remaining) = u32::try_parse(remaining)?; let (vhorz_y_period, remaining) = u32::try_parse(remaining)?; let (vhorz_u_period, remaining) = u32::try_parse(remaining)?; let (vhorz_v_period, remaining) = u32::try_parse(remaining)?; let (vvert_y_period, remaining) = u32::try_parse(remaining)?; let (vvert_u_period, remaining) = u32::try_parse(remaining)?; let (vvert_v_period, remaining) = u32::try_parse(remaining)?; let (vcomp_order, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; let vcomp_order = <[u8; 32]>::try_from(vcomp_order).unwrap(); let (vscanline_order, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(11..).ok_or(ParseError::InsufficientData)?; let type_ = type_.into(); let byte_order = byte_order.into(); let format = format.into(); let vscanline_order = vscanline_order.into(); let result = ImageFormatInfo { id, type_, byte_order, guid, bpp, num_planes, depth, red_mask, green_mask, blue_mask, format, y_sample_bits, u_sample_bits, v_sample_bits, vhorz_y_period, vhorz_u_period, vhorz_v_period, vvert_y_period, vvert_u_period, vvert_v_period, vcomp_order, vscanline_order }; Ok((result, remaining)) } } impl Serialize for ImageFormatInfo { type Bytes = [u8; 128]; fn serialize(&self) -> [u8; 128] { let id_bytes = self.id.serialize(); let type_bytes = u8::from(self.type_).serialize(); let byte_order_bytes = u8::from(self.byte_order).serialize(); let bpp_bytes = self.bpp.serialize(); let num_planes_bytes = self.num_planes.serialize(); let depth_bytes = self.depth.serialize(); let red_mask_bytes = self.red_mask.serialize(); let green_mask_bytes = self.green_mask.serialize(); let blue_mask_bytes = self.blue_mask.serialize(); let format_bytes = u8::from(self.format).serialize(); let y_sample_bits_bytes = self.y_sample_bits.serialize(); let u_sample_bits_bytes = self.u_sample_bits.serialize(); let v_sample_bits_bytes = self.v_sample_bits.serialize(); let vhorz_y_period_bytes = self.vhorz_y_period.serialize(); let vhorz_u_period_bytes = self.vhorz_u_period.serialize(); let vhorz_v_period_bytes = self.vhorz_v_period.serialize(); let vvert_y_period_bytes = self.vvert_y_period.serialize(); let vvert_u_period_bytes = self.vvert_u_period.serialize(); let vvert_v_period_bytes = self.vvert_v_period.serialize(); let vscanline_order_bytes = u8::from(self.vscanline_order).serialize(); [ id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], type_bytes[0], byte_order_bytes[0], 0, 0, self.guid[0], self.guid[1], self.guid[2], self.guid[3], self.guid[4], self.guid[5], self.guid[6], self.guid[7], self.guid[8], self.guid[9], self.guid[10], self.guid[11], self.guid[12], self.guid[13], self.guid[14], self.guid[15], bpp_bytes[0], num_planes_bytes[0], 0, 0, depth_bytes[0], 0, 0, 0, red_mask_bytes[0], red_mask_bytes[1], red_mask_bytes[2], red_mask_bytes[3], green_mask_bytes[0], green_mask_bytes[1], green_mask_bytes[2], green_mask_bytes[3], blue_mask_bytes[0], blue_mask_bytes[1], blue_mask_bytes[2], blue_mask_bytes[3], format_bytes[0], 0, 0, 0, y_sample_bits_bytes[0], y_sample_bits_bytes[1], y_sample_bits_bytes[2], y_sample_bits_bytes[3], u_sample_bits_bytes[0], u_sample_bits_bytes[1], u_sample_bits_bytes[2], u_sample_bits_bytes[3], v_sample_bits_bytes[0], v_sample_bits_bytes[1], v_sample_bits_bytes[2], v_sample_bits_bytes[3], vhorz_y_period_bytes[0], vhorz_y_period_bytes[1], vhorz_y_period_bytes[2], vhorz_y_period_bytes[3], vhorz_u_period_bytes[0], vhorz_u_period_bytes[1], vhorz_u_period_bytes[2], vhorz_u_period_bytes[3], vhorz_v_period_bytes[0], vhorz_v_period_bytes[1], vhorz_v_period_bytes[2], vhorz_v_period_bytes[3], vvert_y_period_bytes[0], vvert_y_period_bytes[1], vvert_y_period_bytes[2], vvert_y_period_bytes[3], vvert_u_period_bytes[0], vvert_u_period_bytes[1], vvert_u_period_bytes[2], vvert_u_period_bytes[3], vvert_v_period_bytes[0], vvert_v_period_bytes[1], vvert_v_period_bytes[2], vvert_v_period_bytes[3], self.vcomp_order[0], self.vcomp_order[1], self.vcomp_order[2], self.vcomp_order[3], self.vcomp_order[4], self.vcomp_order[5], self.vcomp_order[6], self.vcomp_order[7], self.vcomp_order[8], self.vcomp_order[9], self.vcomp_order[10], self.vcomp_order[11], self.vcomp_order[12], self.vcomp_order[13], self.vcomp_order[14], self.vcomp_order[15], self.vcomp_order[16], self.vcomp_order[17], self.vcomp_order[18], self.vcomp_order[19], self.vcomp_order[20], self.vcomp_order[21], self.vcomp_order[22], self.vcomp_order[23], self.vcomp_order[24], self.vcomp_order[25], self.vcomp_order[26], self.vcomp_order[27], self.vcomp_order[28], self.vcomp_order[29], self.vcomp_order[30], self.vcomp_order[31], vscanline_order_bytes[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(128); self.id.serialize_into(bytes); u8::from(self.type_).serialize_into(bytes); u8::from(self.byte_order).serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); bytes.extend_from_slice(&self.guid); self.bpp.serialize_into(bytes); self.num_planes.serialize_into(bytes); bytes.extend_from_slice(&[0; 2]); self.depth.serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.red_mask.serialize_into(bytes); self.green_mask.serialize_into(bytes); self.blue_mask.serialize_into(bytes); u8::from(self.format).serialize_into(bytes); bytes.extend_from_slice(&[0; 3]); self.y_sample_bits.serialize_into(bytes); self.u_sample_bits.serialize_into(bytes); self.v_sample_bits.serialize_into(bytes); self.vhorz_y_period.serialize_into(bytes); self.vhorz_u_period.serialize_into(bytes); self.vhorz_v_period.serialize_into(bytes); self.vvert_y_period.serialize_into(bytes); self.vvert_u_period.serialize_into(bytes); self.vvert_v_period.serialize_into(bytes); bytes.extend_from_slice(&self.vcomp_order); u8::from(self.vscanline_order).serialize_into(bytes); bytes.extend_from_slice(&[0; 11]); } } /// Opcode for the BadPort error pub const BAD_PORT_ERROR: u8 = 0; /// Opcode for the BadEncoding error pub const BAD_ENCODING_ERROR: u8 = 1; /// Opcode for the BadControl error pub const BAD_CONTROL_ERROR: u8 = 2; /// Opcode for the VideoNotify event pub const VIDEO_NOTIFY_EVENT: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct VideoNotifyEvent { pub response_type: u8, pub reason: VideoNotifyReason, pub sequence: u16, pub time: xproto::Timestamp, pub drawable: xproto::Drawable, pub port: Port, } impl TryParse for VideoNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (reason, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (port, remaining) = Port::try_parse(remaining)?; let reason = reason.into(); let result = VideoNotifyEvent { response_type, reason, sequence, time, drawable, port }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&VideoNotifyEvent> for [u8; 32] { fn from(input: &VideoNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let reason_bytes = u8::from(input.reason).serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let drawable_bytes = input.drawable.serialize(); let port_bytes = input.port.serialize(); [ response_type_bytes[0], reason_bytes[0], sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: VideoNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the PortNotify event pub const PORT_NOTIFY_EVENT: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PortNotifyEvent { pub response_type: u8, pub sequence: u16, pub time: xproto::Timestamp, pub port: Port, pub attribute: xproto::Atom, pub value: i32, } impl TryParse for PortNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (port, remaining) = Port::try_parse(remaining)?; let (attribute, remaining) = xproto::Atom::try_parse(remaining)?; let (value, remaining) = i32::try_parse(remaining)?; let result = PortNotifyEvent { response_type, sequence, time, port, attribute, value }; let _ = remaining; let remaining = initial_value.get(32..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl From<&PortNotifyEvent> for [u8; 32] { fn from(input: &PortNotifyEvent) -> Self { let response_type_bytes = input.response_type.serialize(); let sequence_bytes = input.sequence.serialize(); let time_bytes = input.time.serialize(); let port_bytes = input.port.serialize(); let attribute_bytes = input.attribute.serialize(); let value_bytes = input.value.serialize(); [ response_type_bytes[0], 0, sequence_bytes[0], sequence_bytes[1], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], attribute_bytes[0], attribute_bytes[1], attribute_bytes[2], attribute_bytes[3], value_bytes[0], value_bytes[1], value_bytes[2], value_bytes[3], // trailing padding 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: PortNotifyEvent) -> Self { Self::from(&input) } } /// Opcode for the QueryExtension request pub const QUERY_EXTENSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryExtensionRequest; impl QueryExtensionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_EXTENSION_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_EXTENSION_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryExtensionRequest ) } } impl Request for QueryExtensionRequest { type Reply = QueryExtensionReply; } pub fn query_extension(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryExtensionRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryExtensionReply { pub sequence: u16, pub length: u32, pub major: u16, pub minor: u16, } impl TryParse for QueryExtensionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major, remaining) = u16::try_parse(remaining)?; let (minor, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryExtensionReply { sequence, length, major, minor }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryAdaptors request pub const QUERY_ADAPTORS_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryAdaptorsRequest { pub window: xproto::Window, } impl QueryAdaptorsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let window_bytes = self.window.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_ADAPTORS_REQUEST, 0, 0, window_bytes[0], window_bytes[1], window_bytes[2], window_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_ADAPTORS_REQUEST { return Err(ParseError::InvalidValue); } let (window, remaining) = xproto::Window::try_parse(value)?; let _ = remaining; Ok(QueryAdaptorsRequest { window, }) } } impl Request for QueryAdaptorsRequest { type Reply = QueryAdaptorsReply; } pub fn query_adaptors(conn: &Conn, window: xproto::Window) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryAdaptorsRequest { window, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryAdaptorsReply { pub sequence: u16, pub length: u32, pub info: Vec, } impl TryParse for QueryAdaptorsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_adaptors, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (info, remaining) = crate::x11_utils::parse_list::(remaining, num_adaptors.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryAdaptorsReply { sequence, length, info }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryAdaptorsReply { /// Get the value of the `num_adaptors` field. /// /// The `num_adaptors` field is used as the length field of the `info` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_adaptors(&self) -> u16 { self.info.len() .try_into().unwrap() } } /// Opcode for the QueryEncodings request pub const QUERY_ENCODINGS_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryEncodingsRequest { pub port: Port, } impl QueryEncodingsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_ENCODINGS_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_ENCODINGS_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let _ = remaining; Ok(QueryEncodingsRequest { port, }) } } impl Request for QueryEncodingsRequest { type Reply = QueryEncodingsReply; } pub fn query_encodings(conn: &Conn, port: Port) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryEncodingsRequest { port, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryEncodingsReply { pub sequence: u16, pub length: u32, pub info: Vec, } impl TryParse for QueryEncodingsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_encodings, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(22..).ok_or(ParseError::InsufficientData)?; let (info, remaining) = crate::x11_utils::parse_list::(remaining, num_encodings.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryEncodingsReply { sequence, length, info }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryEncodingsReply { /// Get the value of the `num_encodings` field. /// /// The `num_encodings` field is used as the length field of the `info` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_encodings(&self) -> u16 { self.info.len() .try_into().unwrap() } } /// Opcode for the GrabPort request pub const GRAB_PORT_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GrabPortRequest { pub port: Port, pub time: xproto::Timestamp, } impl GrabPortRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let time_bytes = self.time.serialize(); let mut request0 = vec![ extension_information.major_opcode, GRAB_PORT_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GRAB_PORT_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let _ = remaining; Ok(GrabPortRequest { port, time, }) } } impl Request for GrabPortRequest { type Reply = GrabPortReply; } pub fn grab_port(conn: &Conn, port: Port, time: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let time: xproto::Timestamp = time.into(); let request0 = GrabPortRequest { port, time, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GrabPortReply { pub result: GrabPortStatus, pub sequence: u16, pub length: u32, } impl TryParse for GrabPortReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let (result, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = result.into(); let result = GrabPortReply { result, sequence, length }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the UngrabPort request pub const UNGRAB_PORT_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UngrabPortRequest { pub port: Port, pub time: xproto::Timestamp, } impl UngrabPortRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let time_bytes = self.time.serialize(); let mut request0 = vec![ extension_information.major_opcode, UNGRAB_PORT_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], time_bytes[0], time_bytes[1], time_bytes[2], time_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != UNGRAB_PORT_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let _ = remaining; Ok(UngrabPortRequest { port, time, }) } } impl Request for UngrabPortRequest { type Reply = (); } pub fn ungrab_port(conn: &Conn, port: Port, time: A) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, A: Into, { let time: xproto::Timestamp = time.into(); let request0 = UngrabPortRequest { port, time, }; request0.send(conn) } /// Opcode for the PutVideo request pub const PUT_VIDEO_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PutVideoRequest { pub port: Port, pub drawable: xproto::Drawable, pub gc: xproto::Gcontext, pub vid_x: i16, pub vid_y: i16, pub vid_w: u16, pub vid_h: u16, pub drw_x: i16, pub drw_y: i16, pub drw_w: u16, pub drw_h: u16, } impl PutVideoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let drawable_bytes = self.drawable.serialize(); let gc_bytes = self.gc.serialize(); let vid_x_bytes = self.vid_x.serialize(); let vid_y_bytes = self.vid_y.serialize(); let vid_w_bytes = self.vid_w.serialize(); let vid_h_bytes = self.vid_h.serialize(); let drw_x_bytes = self.drw_x.serialize(); let drw_y_bytes = self.drw_y.serialize(); let drw_w_bytes = self.drw_w.serialize(); let drw_h_bytes = self.drw_h.serialize(); let mut request0 = vec![ extension_information.major_opcode, PUT_VIDEO_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], vid_x_bytes[0], vid_x_bytes[1], vid_y_bytes[0], vid_y_bytes[1], vid_w_bytes[0], vid_w_bytes[1], vid_h_bytes[0], vid_h_bytes[1], drw_x_bytes[0], drw_x_bytes[1], drw_y_bytes[0], drw_y_bytes[1], drw_w_bytes[0], drw_w_bytes[1], drw_h_bytes[0], drw_h_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PUT_VIDEO_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let (vid_x, remaining) = i16::try_parse(remaining)?; let (vid_y, remaining) = i16::try_parse(remaining)?; let (vid_w, remaining) = u16::try_parse(remaining)?; let (vid_h, remaining) = u16::try_parse(remaining)?; let (drw_x, remaining) = i16::try_parse(remaining)?; let (drw_y, remaining) = i16::try_parse(remaining)?; let (drw_w, remaining) = u16::try_parse(remaining)?; let (drw_h, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(PutVideoRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }) } } impl Request for PutVideoRequest { type Reply = (); } pub fn put_video(conn: &Conn, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PutVideoRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }; request0.send(conn) } /// Opcode for the PutStill request pub const PUT_STILL_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PutStillRequest { pub port: Port, pub drawable: xproto::Drawable, pub gc: xproto::Gcontext, pub vid_x: i16, pub vid_y: i16, pub vid_w: u16, pub vid_h: u16, pub drw_x: i16, pub drw_y: i16, pub drw_w: u16, pub drw_h: u16, } impl PutStillRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let drawable_bytes = self.drawable.serialize(); let gc_bytes = self.gc.serialize(); let vid_x_bytes = self.vid_x.serialize(); let vid_y_bytes = self.vid_y.serialize(); let vid_w_bytes = self.vid_w.serialize(); let vid_h_bytes = self.vid_h.serialize(); let drw_x_bytes = self.drw_x.serialize(); let drw_y_bytes = self.drw_y.serialize(); let drw_w_bytes = self.drw_w.serialize(); let drw_h_bytes = self.drw_h.serialize(); let mut request0 = vec![ extension_information.major_opcode, PUT_STILL_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], vid_x_bytes[0], vid_x_bytes[1], vid_y_bytes[0], vid_y_bytes[1], vid_w_bytes[0], vid_w_bytes[1], vid_h_bytes[0], vid_h_bytes[1], drw_x_bytes[0], drw_x_bytes[1], drw_y_bytes[0], drw_y_bytes[1], drw_w_bytes[0], drw_w_bytes[1], drw_h_bytes[0], drw_h_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != PUT_STILL_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let (vid_x, remaining) = i16::try_parse(remaining)?; let (vid_y, remaining) = i16::try_parse(remaining)?; let (vid_w, remaining) = u16::try_parse(remaining)?; let (vid_h, remaining) = u16::try_parse(remaining)?; let (drw_x, remaining) = i16::try_parse(remaining)?; let (drw_y, remaining) = i16::try_parse(remaining)?; let (drw_w, remaining) = u16::try_parse(remaining)?; let (drw_h, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(PutStillRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }) } } impl Request for PutStillRequest { type Reply = (); } pub fn put_still(conn: &Conn, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PutStillRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }; request0.send(conn) } /// Opcode for the GetVideo request pub const GET_VIDEO_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetVideoRequest { pub port: Port, pub drawable: xproto::Drawable, pub gc: xproto::Gcontext, pub vid_x: i16, pub vid_y: i16, pub vid_w: u16, pub vid_h: u16, pub drw_x: i16, pub drw_y: i16, pub drw_w: u16, pub drw_h: u16, } impl GetVideoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let drawable_bytes = self.drawable.serialize(); let gc_bytes = self.gc.serialize(); let vid_x_bytes = self.vid_x.serialize(); let vid_y_bytes = self.vid_y.serialize(); let vid_w_bytes = self.vid_w.serialize(); let vid_h_bytes = self.vid_h.serialize(); let drw_x_bytes = self.drw_x.serialize(); let drw_y_bytes = self.drw_y.serialize(); let drw_w_bytes = self.drw_w.serialize(); let drw_h_bytes = self.drw_h.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_VIDEO_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], vid_x_bytes[0], vid_x_bytes[1], vid_y_bytes[0], vid_y_bytes[1], vid_w_bytes[0], vid_w_bytes[1], vid_h_bytes[0], vid_h_bytes[1], drw_x_bytes[0], drw_x_bytes[1], drw_y_bytes[0], drw_y_bytes[1], drw_w_bytes[0], drw_w_bytes[1], drw_h_bytes[0], drw_h_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_VIDEO_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let (vid_x, remaining) = i16::try_parse(remaining)?; let (vid_y, remaining) = i16::try_parse(remaining)?; let (vid_w, remaining) = u16::try_parse(remaining)?; let (vid_h, remaining) = u16::try_parse(remaining)?; let (drw_x, remaining) = i16::try_parse(remaining)?; let (drw_y, remaining) = i16::try_parse(remaining)?; let (drw_w, remaining) = u16::try_parse(remaining)?; let (drw_h, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(GetVideoRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }) } } impl Request for GetVideoRequest { type Reply = (); } pub fn get_video(conn: &Conn, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetVideoRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }; request0.send(conn) } /// Opcode for the GetStill request pub const GET_STILL_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetStillRequest { pub port: Port, pub drawable: xproto::Drawable, pub gc: xproto::Gcontext, pub vid_x: i16, pub vid_y: i16, pub vid_w: u16, pub vid_h: u16, pub drw_x: i16, pub drw_y: i16, pub drw_w: u16, pub drw_h: u16, } impl GetStillRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let drawable_bytes = self.drawable.serialize(); let gc_bytes = self.gc.serialize(); let vid_x_bytes = self.vid_x.serialize(); let vid_y_bytes = self.vid_y.serialize(); let vid_w_bytes = self.vid_w.serialize(); let vid_h_bytes = self.vid_h.serialize(); let drw_x_bytes = self.drw_x.serialize(); let drw_y_bytes = self.drw_y.serialize(); let drw_w_bytes = self.drw_w.serialize(); let drw_h_bytes = self.drw_h.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_STILL_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], vid_x_bytes[0], vid_x_bytes[1], vid_y_bytes[0], vid_y_bytes[1], vid_w_bytes[0], vid_w_bytes[1], vid_h_bytes[0], vid_h_bytes[1], drw_x_bytes[0], drw_x_bytes[1], drw_y_bytes[0], drw_y_bytes[1], drw_w_bytes[0], drw_w_bytes[1], drw_h_bytes[0], drw_h_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_STILL_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let (vid_x, remaining) = i16::try_parse(remaining)?; let (vid_y, remaining) = i16::try_parse(remaining)?; let (vid_w, remaining) = u16::try_parse(remaining)?; let (vid_h, remaining) = u16::try_parse(remaining)?; let (drw_x, remaining) = i16::try_parse(remaining)?; let (drw_y, remaining) = i16::try_parse(remaining)?; let (drw_w, remaining) = u16::try_parse(remaining)?; let (drw_h, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(GetStillRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }) } } impl Request for GetStillRequest { type Reply = (); } pub fn get_still(conn: &Conn, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetStillRequest { port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h, }; request0.send(conn) } /// Opcode for the StopVideo request pub const STOP_VIDEO_REQUEST: u8 = 9; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct StopVideoRequest { pub port: Port, pub drawable: xproto::Drawable, } impl StopVideoRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let drawable_bytes = self.drawable.serialize(); let mut request0 = vec![ extension_information.major_opcode, STOP_VIDEO_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != STOP_VIDEO_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let _ = remaining; Ok(StopVideoRequest { port, drawable, }) } } impl Request for StopVideoRequest { type Reply = (); } pub fn stop_video(conn: &Conn, port: Port, drawable: xproto::Drawable) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = StopVideoRequest { port, drawable, }; request0.send(conn) } /// Opcode for the SelectVideoNotify request pub const SELECT_VIDEO_NOTIFY_REQUEST: u8 = 10; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectVideoNotifyRequest { pub drawable: xproto::Drawable, pub onoff: bool, } impl SelectVideoNotifyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let drawable_bytes = self.drawable.serialize(); let onoff_bytes = self.onoff.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_VIDEO_NOTIFY_REQUEST, 0, 0, drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], onoff_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_VIDEO_NOTIFY_REQUEST { return Err(ParseError::InvalidValue); } let (drawable, remaining) = xproto::Drawable::try_parse(value)?; let (onoff, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SelectVideoNotifyRequest { drawable, onoff, }) } } impl Request for SelectVideoNotifyRequest { type Reply = (); } pub fn select_video_notify(conn: &Conn, drawable: xproto::Drawable, onoff: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SelectVideoNotifyRequest { drawable, onoff, }; request0.send(conn) } /// Opcode for the SelectPortNotify request pub const SELECT_PORT_NOTIFY_REQUEST: u8 = 11; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SelectPortNotifyRequest { pub port: Port, pub onoff: bool, } impl SelectPortNotifyRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let onoff_bytes = self.onoff.serialize(); let mut request0 = vec![ extension_information.major_opcode, SELECT_PORT_NOTIFY_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], onoff_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SELECT_PORT_NOTIFY_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (onoff, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(SelectPortNotifyRequest { port, onoff, }) } } impl Request for SelectPortNotifyRequest { type Reply = (); } pub fn select_port_notify(conn: &Conn, port: Port, onoff: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SelectPortNotifyRequest { port, onoff, }; request0.send(conn) } /// Opcode for the QueryBestSize request pub const QUERY_BEST_SIZE_REQUEST: u8 = 12; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryBestSizeRequest { pub port: Port, pub vid_w: u16, pub vid_h: u16, pub drw_w: u16, pub drw_h: u16, pub motion: bool, } impl QueryBestSizeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let vid_w_bytes = self.vid_w.serialize(); let vid_h_bytes = self.vid_h.serialize(); let drw_w_bytes = self.drw_w.serialize(); let drw_h_bytes = self.drw_h.serialize(); let motion_bytes = self.motion.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_BEST_SIZE_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], vid_w_bytes[0], vid_w_bytes[1], vid_h_bytes[0], vid_h_bytes[1], drw_w_bytes[0], drw_w_bytes[1], drw_h_bytes[0], drw_h_bytes[1], motion_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_BEST_SIZE_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (vid_w, remaining) = u16::try_parse(remaining)?; let (vid_h, remaining) = u16::try_parse(remaining)?; let (drw_w, remaining) = u16::try_parse(remaining)?; let (drw_h, remaining) = u16::try_parse(remaining)?; let (motion, remaining) = bool::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(QueryBestSizeRequest { port, vid_w, vid_h, drw_w, drw_h, motion, }) } } impl Request for QueryBestSizeRequest { type Reply = QueryBestSizeReply; } pub fn query_best_size(conn: &Conn, port: Port, vid_w: u16, vid_h: u16, drw_w: u16, drw_h: u16, motion: bool) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryBestSizeRequest { port, vid_w, vid_h, drw_w, drw_h, motion, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryBestSizeReply { pub sequence: u16, pub length: u32, pub actual_width: u16, pub actual_height: u16, } impl TryParse for QueryBestSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (actual_width, remaining) = u16::try_parse(remaining)?; let (actual_height, remaining) = u16::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryBestSizeReply { sequence, length, actual_width, actual_height }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the SetPortAttribute request pub const SET_PORT_ATTRIBUTE_REQUEST: u8 = 13; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SetPortAttributeRequest { pub port: Port, pub attribute: xproto::Atom, pub value: i32, } impl SetPortAttributeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let attribute_bytes = self.attribute.serialize(); let value_bytes = self.value.serialize(); let mut request0 = vec![ extension_information.major_opcode, SET_PORT_ATTRIBUTE_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], attribute_bytes[0], attribute_bytes[1], attribute_bytes[2], attribute_bytes[3], value_bytes[0], value_bytes[1], value_bytes[2], value_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SET_PORT_ATTRIBUTE_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (attribute, remaining) = xproto::Atom::try_parse(remaining)?; let (value, remaining) = i32::try_parse(remaining)?; let _ = remaining; Ok(SetPortAttributeRequest { port, attribute, value, }) } } impl Request for SetPortAttributeRequest { type Reply = (); } pub fn set_port_attribute(conn: &Conn, port: Port, attribute: xproto::Atom, value: i32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = SetPortAttributeRequest { port, attribute, value, }; request0.send(conn) } /// Opcode for the GetPortAttribute request pub const GET_PORT_ATTRIBUTE_REQUEST: u8 = 14; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPortAttributeRequest { pub port: Port, pub attribute: xproto::Atom, } impl GetPortAttributeRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let attribute_bytes = self.attribute.serialize(); let mut request0 = vec![ extension_information.major_opcode, GET_PORT_ATTRIBUTE_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], attribute_bytes[0], attribute_bytes[1], attribute_bytes[2], attribute_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != GET_PORT_ATTRIBUTE_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (attribute, remaining) = xproto::Atom::try_parse(remaining)?; let _ = remaining; Ok(GetPortAttributeRequest { port, attribute, }) } } impl Request for GetPortAttributeRequest { type Reply = GetPortAttributeReply; } pub fn get_port_attribute(conn: &Conn, port: Port, attribute: xproto::Atom) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = GetPortAttributeRequest { port, attribute, }; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct GetPortAttributeReply { pub sequence: u16, pub length: u32, pub value: i32, } impl TryParse for GetPortAttributeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (value, remaining) = i32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = GetPortAttributeReply { sequence, length, value }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the QueryPortAttributes request pub const QUERY_PORT_ATTRIBUTES_REQUEST: u8 = 15; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryPortAttributesRequest { pub port: Port, } impl QueryPortAttributesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_PORT_ATTRIBUTES_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_PORT_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let _ = remaining; Ok(QueryPortAttributesRequest { port, }) } } impl Request for QueryPortAttributesRequest { type Reply = QueryPortAttributesReply; } pub fn query_port_attributes(conn: &Conn, port: Port) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryPortAttributesRequest { port, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryPortAttributesReply { pub sequence: u16, pub length: u32, pub text_size: u32, pub attributes: Vec, } impl TryParse for QueryPortAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_attributes, remaining) = u32::try_parse(remaining)?; let (text_size, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(16..).ok_or(ParseError::InsufficientData)?; let (attributes, remaining) = crate::x11_utils::parse_list::(remaining, num_attributes.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryPortAttributesReply { sequence, length, text_size, attributes }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryPortAttributesReply { /// Get the value of the `num_attributes` field. /// /// The `num_attributes` field is used as the length field of the `attributes` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_attributes(&self) -> u32 { self.attributes.len() .try_into().unwrap() } } /// Opcode for the ListImageFormats request pub const LIST_IMAGE_FORMATS_REQUEST: u8 = 16; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListImageFormatsRequest { pub port: Port, } impl ListImageFormatsRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_IMAGE_FORMATS_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_IMAGE_FORMATS_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let _ = remaining; Ok(ListImageFormatsRequest { port, }) } } impl Request for ListImageFormatsRequest { type Reply = ListImageFormatsReply; } pub fn list_image_formats(conn: &Conn, port: Port) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListImageFormatsRequest { port, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListImageFormatsReply { pub sequence: u16, pub length: u32, pub format: Vec, } impl TryParse for ListImageFormatsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_formats, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (format, remaining) = crate::x11_utils::parse_list::(remaining, num_formats.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListImageFormatsReply { sequence, length, format }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListImageFormatsReply { /// Get the value of the `num_formats` field. /// /// The `num_formats` field is used as the length field of the `format` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_formats(&self) -> u32 { self.format.len() .try_into().unwrap() } } /// Opcode for the QueryImageAttributes request pub const QUERY_IMAGE_ATTRIBUTES_REQUEST: u8 = 17; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryImageAttributesRequest { pub port: Port, pub id: u32, pub width: u16, pub height: u16, } impl QueryImageAttributesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let id_bytes = self.id.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let mut request0 = vec![ extension_information.major_opcode, QUERY_IMAGE_ATTRIBUTES_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_IMAGE_ATTRIBUTES_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (id, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(QueryImageAttributesRequest { port, id, width, height, }) } } impl Request for QueryImageAttributesRequest { type Reply = QueryImageAttributesReply; } pub fn query_image_attributes(conn: &Conn, port: Port, id: u32, width: u16, height: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryImageAttributesRequest { port, id, width, height, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct QueryImageAttributesReply { pub sequence: u16, pub length: u32, pub data_size: u32, pub width: u16, pub height: u16, pub pitches: Vec, pub offsets: Vec, } impl TryParse for QueryImageAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num_planes, remaining) = u32::try_parse(remaining)?; let (data_size, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (pitches, remaining) = crate::x11_utils::parse_list::(remaining, num_planes.try_to_usize()?)?; let (offsets, remaining) = crate::x11_utils::parse_list::(remaining, num_planes.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryImageAttributesReply { sequence, length, data_size, width, height, pitches, offsets }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl QueryImageAttributesReply { /// Get the value of the `num_planes` field. /// /// The `num_planes` field is used as the length field of the `pitches` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num_planes(&self) -> u32 { self.pitches.len() .try_into().unwrap() } } /// Opcode for the PutImage request pub const PUT_IMAGE_REQUEST: u8 = 18; #[derive(Debug, Clone, PartialEq, Eq)] pub struct PutImageRequest<'input> { pub port: Port, pub drawable: xproto::Drawable, pub gc: xproto::Gcontext, pub id: u32, pub src_x: i16, pub src_y: i16, pub src_w: u16, pub src_h: u16, pub drw_x: i16, pub drw_y: i16, pub drw_w: u16, pub drw_h: u16, pub width: u16, pub height: u16, pub data: Cow<'input, [u8]>, } impl<'input> PutImageRequest<'input> { /// Serialize this request into bytes for the provided connection fn serialize(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let drawable_bytes = self.drawable.serialize(); let gc_bytes = self.gc.serialize(); let id_bytes = self.id.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let src_w_bytes = self.src_w.serialize(); let src_h_bytes = self.src_h.serialize(); let drw_x_bytes = self.drw_x.serialize(); let drw_y_bytes = self.drw_y.serialize(); let drw_w_bytes = self.drw_w.serialize(); let drw_h_bytes = self.drw_h.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let mut request0 = vec![ extension_information.major_opcode, PUT_IMAGE_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], src_w_bytes[0], src_w_bytes[1], src_h_bytes[0], src_h_bytes[1], drw_x_bytes[0], drw_x_bytes[1], drw_y_bytes[0], drw_y_bytes[1], drw_w_bytes[0], drw_w_bytes[1], drw_h_bytes[0], drw_h_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], ]; let length_so_far = length_so_far + request0.len(); let length_so_far = length_so_far + self.data.len(); let padding0 = &[0; 3][..(4 - (length_so_far % 4)) % 4]; let length_so_far = length_so_far + padding0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into(), self.data, padding0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &'input [u8]) -> Result { if header.minor_opcode != PUT_IMAGE_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let (id, remaining) = u32::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let (src_w, remaining) = u16::try_parse(remaining)?; let (src_h, remaining) = u16::try_parse(remaining)?; let (drw_x, remaining) = i16::try_parse(remaining)?; let (drw_y, remaining) = i16::try_parse(remaining)?; let (drw_w, remaining) = u16::try_parse(remaining)?; let (drw_h, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (data, remaining) = remaining.split_at(remaining.len()); let _ = remaining; Ok(PutImageRequest { port, drawable, gc, id, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height, data: Cow::Borrowed(data), }) } /// Clone all borrowed data in this PutImageRequest. pub fn into_owned(self) -> PutImageRequest<'static> { PutImageRequest { port: self.port, drawable: self.drawable, gc: self.gc, id: self.id, src_x: self.src_x, src_y: self.src_y, src_w: self.src_w, src_h: self.src_h, drw_x: self.drw_x, drw_y: self.drw_y, drw_w: self.drw_w, drw_h: self.drw_h, width: self.width, height: self.height, data: Cow::Owned(self.data.into_owned()), } } } impl<'input> Request for PutImageRequest<'input> { type Reply = (); } pub fn put_image<'c, 'input, Conn>(conn: &'c Conn, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, id: u32, src_x: i16, src_y: i16, src_w: u16, src_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16, width: u16, height: u16, data: &'input [u8]) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = PutImageRequest { port, drawable, gc, id, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height, data: Cow::Borrowed(data), }; request0.send(conn) } /// Opcode for the ShmPutImage request pub const SHM_PUT_IMAGE_REQUEST: u8 = 19; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ShmPutImageRequest { pub port: Port, pub drawable: xproto::Drawable, pub gc: xproto::Gcontext, pub shmseg: shm::Seg, pub id: u32, pub offset: u32, pub src_x: i16, pub src_y: i16, pub src_w: u16, pub src_h: u16, pub drw_x: i16, pub drw_y: i16, pub drw_w: u16, pub drw_h: u16, pub width: u16, pub height: u16, pub send_event: u8, } impl ShmPutImageRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_bytes = self.port.serialize(); let drawable_bytes = self.drawable.serialize(); let gc_bytes = self.gc.serialize(); let shmseg_bytes = self.shmseg.serialize(); let id_bytes = self.id.serialize(); let offset_bytes = self.offset.serialize(); let src_x_bytes = self.src_x.serialize(); let src_y_bytes = self.src_y.serialize(); let src_w_bytes = self.src_w.serialize(); let src_h_bytes = self.src_h.serialize(); let drw_x_bytes = self.drw_x.serialize(); let drw_y_bytes = self.drw_y.serialize(); let drw_w_bytes = self.drw_w.serialize(); let drw_h_bytes = self.drw_h.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let send_event_bytes = self.send_event.serialize(); let mut request0 = vec![ extension_information.major_opcode, SHM_PUT_IMAGE_REQUEST, 0, 0, port_bytes[0], port_bytes[1], port_bytes[2], port_bytes[3], drawable_bytes[0], drawable_bytes[1], drawable_bytes[2], drawable_bytes[3], gc_bytes[0], gc_bytes[1], gc_bytes[2], gc_bytes[3], shmseg_bytes[0], shmseg_bytes[1], shmseg_bytes[2], shmseg_bytes[3], id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], offset_bytes[0], offset_bytes[1], offset_bytes[2], offset_bytes[3], src_x_bytes[0], src_x_bytes[1], src_y_bytes[0], src_y_bytes[1], src_w_bytes[0], src_w_bytes[1], src_h_bytes[0], src_h_bytes[1], drw_x_bytes[0], drw_x_bytes[1], drw_y_bytes[0], drw_y_bytes[1], drw_w_bytes[0], drw_w_bytes[1], drw_h_bytes[0], drw_h_bytes[1], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], send_event_bytes[0], 0, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != SHM_PUT_IMAGE_REQUEST { return Err(ParseError::InvalidValue); } let (port, remaining) = Port::try_parse(value)?; let (drawable, remaining) = xproto::Drawable::try_parse(remaining)?; let (gc, remaining) = xproto::Gcontext::try_parse(remaining)?; let (shmseg, remaining) = shm::Seg::try_parse(remaining)?; let (id, remaining) = u32::try_parse(remaining)?; let (offset, remaining) = u32::try_parse(remaining)?; let (src_x, remaining) = i16::try_parse(remaining)?; let (src_y, remaining) = i16::try_parse(remaining)?; let (src_w, remaining) = u16::try_parse(remaining)?; let (src_h, remaining) = u16::try_parse(remaining)?; let (drw_x, remaining) = i16::try_parse(remaining)?; let (drw_y, remaining) = i16::try_parse(remaining)?; let (drw_w, remaining) = u16::try_parse(remaining)?; let (drw_h, remaining) = u16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (send_event, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::InsufficientData)?; let _ = remaining; Ok(ShmPutImageRequest { port, drawable, gc, shmseg, id, offset, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height, send_event, }) } } impl Request for ShmPutImageRequest { type Reply = (); } pub fn shm_put_image(conn: &Conn, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, shmseg: shm::Seg, id: u32, offset: u32, src_x: i16, src_y: i16, src_w: u16, src_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16, width: u16, height: u16, send_event: u8) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ShmPutImageRequest { port, drawable, gc, shmseg, id, offset, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height, send_event, }; request0.send(conn) } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xv_query_extension(&self) -> Result, ConnectionError> { query_extension(self) } fn xv_query_adaptors(&self, window: xproto::Window) -> Result, ConnectionError> { query_adaptors(self, window) } fn xv_query_encodings(&self, port: Port) -> Result, ConnectionError> { query_encodings(self, port) } fn xv_grab_port(&self, port: Port, time: A) -> Result, ConnectionError> where A: Into, { grab_port(self, port, time) } fn xv_ungrab_port(&self, port: Port, time: A) -> Result, ConnectionError> where A: Into, { ungrab_port(self, port, time) } fn xv_put_video(&self, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> { put_video(self, port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h) } fn xv_put_still(&self, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> { put_still(self, port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h) } fn xv_get_video(&self, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> { get_video(self, port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h) } fn xv_get_still(&self, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, vid_x: i16, vid_y: i16, vid_w: u16, vid_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16) -> Result, ConnectionError> { get_still(self, port, drawable, gc, vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h) } fn xv_stop_video(&self, port: Port, drawable: xproto::Drawable) -> Result, ConnectionError> { stop_video(self, port, drawable) } fn xv_select_video_notify(&self, drawable: xproto::Drawable, onoff: bool) -> Result, ConnectionError> { select_video_notify(self, drawable, onoff) } fn xv_select_port_notify(&self, port: Port, onoff: bool) -> Result, ConnectionError> { select_port_notify(self, port, onoff) } fn xv_query_best_size(&self, port: Port, vid_w: u16, vid_h: u16, drw_w: u16, drw_h: u16, motion: bool) -> Result, ConnectionError> { query_best_size(self, port, vid_w, vid_h, drw_w, drw_h, motion) } fn xv_set_port_attribute(&self, port: Port, attribute: xproto::Atom, value: i32) -> Result, ConnectionError> { set_port_attribute(self, port, attribute, value) } fn xv_get_port_attribute(&self, port: Port, attribute: xproto::Atom) -> Result, ConnectionError> { get_port_attribute(self, port, attribute) } fn xv_query_port_attributes(&self, port: Port) -> Result, ConnectionError> { query_port_attributes(self, port) } fn xv_list_image_formats(&self, port: Port) -> Result, ConnectionError> { list_image_formats(self, port) } fn xv_query_image_attributes(&self, port: Port, id: u32, width: u16, height: u16) -> Result, ConnectionError> { query_image_attributes(self, port, id, width, height) } fn xv_put_image<'c, 'input>(&'c self, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, id: u32, src_x: i16, src_y: i16, src_w: u16, src_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16, width: u16, height: u16, data: &'input [u8]) -> Result, ConnectionError> { put_image(self, port, drawable, gc, id, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height, data) } fn xv_shm_put_image(&self, port: Port, drawable: xproto::Drawable, gc: xproto::Gcontext, shmseg: shm::Seg, id: u32, offset: u32, src_x: i16, src_y: i16, src_w: u16, src_h: u16, drw_x: i16, drw_y: i16, drw_w: u16, drw_h: u16, width: u16, height: u16, send_event: u8) -> Result, ConnectionError> { shm_put_image(self, port, drawable, gc, shmseg, id, offset, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height, send_event) } } impl ConnectionExt for C {} x11rb-0.8.1/src/protocol/xvmc.rs010064400017500001750000001220071402220031600146010ustar 00000000000000// This file contains generated code. Do not edit directly. // To regenerate this, run 'make'. //! Bindings to the `XvMC` X11 extension. #![allow(clippy::too_many_arguments)] #[allow(unused_imports)] use std::borrow::Cow; use std::convert::TryFrom; #[allow(unused_imports)] use std::convert::TryInto; use std::io::IoSlice; #[allow(unused_imports)] use crate::utils::{RawFdContainer, pretty_print_bitmask, pretty_print_enum}; #[allow(unused_imports)] use crate::x11_utils::{Request, RequestHeader, Serialize, TryParse, TryParseFd, TryIntoUSize}; use crate::connection::{BufWithFds, PiecewiseBuf, RequestConnection}; #[allow(unused_imports)] use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; use crate::errors::{ConnectionError, ParseError}; use super::xv; /// The X11 name of the extension for QueryExtension pub const X11_EXTENSION_NAME: &str = "XVideo-MotionCompensation"; /// The version number of this extension that this client library supports. /// /// This constant contains the version number of this extension that is supported /// by this build of x11rb. For most things, it does not make sense to use this /// information. If you need to send a `QueryVersion`, it is recommended to instead /// send the maximum version of the extension that you need. pub const X11_XML_VERSION: (u32, u32) = (1, 1); pub type Context = u32; pub type Surface = u32; pub type Subpicture = u32; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SurfaceInfo { pub id: Surface, pub chroma_format: u16, pub pad0: u16, pub max_width: u16, pub max_height: u16, pub subpicture_max_width: u16, pub subpicture_max_height: u16, pub mc_type: u32, pub flags: u32, } impl TryParse for SurfaceInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (id, remaining) = Surface::try_parse(remaining)?; let (chroma_format, remaining) = u16::try_parse(remaining)?; let (pad0, remaining) = u16::try_parse(remaining)?; let (max_width, remaining) = u16::try_parse(remaining)?; let (max_height, remaining) = u16::try_parse(remaining)?; let (subpicture_max_width, remaining) = u16::try_parse(remaining)?; let (subpicture_max_height, remaining) = u16::try_parse(remaining)?; let (mc_type, remaining) = u32::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let result = SurfaceInfo { id, chroma_format, pad0, max_width, max_height, subpicture_max_width, subpicture_max_height, mc_type, flags }; Ok((result, remaining)) } } impl Serialize for SurfaceInfo { type Bytes = [u8; 24]; fn serialize(&self) -> [u8; 24] { let id_bytes = self.id.serialize(); let chroma_format_bytes = self.chroma_format.serialize(); let pad0_bytes = self.pad0.serialize(); let max_width_bytes = self.max_width.serialize(); let max_height_bytes = self.max_height.serialize(); let subpicture_max_width_bytes = self.subpicture_max_width.serialize(); let subpicture_max_height_bytes = self.subpicture_max_height.serialize(); let mc_type_bytes = self.mc_type.serialize(); let flags_bytes = self.flags.serialize(); [ id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3], chroma_format_bytes[0], chroma_format_bytes[1], pad0_bytes[0], pad0_bytes[1], max_width_bytes[0], max_width_bytes[1], max_height_bytes[0], max_height_bytes[1], subpicture_max_width_bytes[0], subpicture_max_width_bytes[1], subpicture_max_height_bytes[0], subpicture_max_height_bytes[1], mc_type_bytes[0], mc_type_bytes[1], mc_type_bytes[2], mc_type_bytes[3], flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], ] } fn serialize_into(&self, bytes: &mut Vec) { bytes.reserve(24); self.id.serialize_into(bytes); self.chroma_format.serialize_into(bytes); self.pad0.serialize_into(bytes); self.max_width.serialize_into(bytes); self.max_height.serialize_into(bytes); self.subpicture_max_width.serialize_into(bytes); self.subpicture_max_height.serialize_into(bytes); self.mc_type.serialize_into(bytes); self.flags.serialize_into(bytes); } } /// Opcode for the QueryVersion request pub const QUERY_VERSION_REQUEST: u8 = 0; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionRequest; impl QueryVersionRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let mut request0 = vec![ extension_information.major_opcode, QUERY_VERSION_REQUEST, 0, 0, ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != QUERY_VERSION_REQUEST { return Err(ParseError::InvalidValue); } let _ = value; Ok(QueryVersionRequest ) } } impl Request for QueryVersionRequest { type Reply = QueryVersionReply; } pub fn query_version(conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = QueryVersionRequest; request0.send(conn) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct QueryVersionReply { pub sequence: u16, pub length: u32, pub major: u32, pub minor: u32, } impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (major, remaining) = u32::try_parse(remaining)?; let (minor, remaining) = u32::try_parse(remaining)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = QueryVersionReply { sequence, length, major, minor }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } /// Opcode for the ListSurfaceTypes request pub const LIST_SURFACE_TYPES_REQUEST: u8 = 1; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListSurfaceTypesRequest { pub port_id: xv::Port, } impl ListSurfaceTypesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_id_bytes = self.port_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_SURFACE_TYPES_REQUEST, 0, 0, port_id_bytes[0], port_id_bytes[1], port_id_bytes[2], port_id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_SURFACE_TYPES_REQUEST { return Err(ParseError::InvalidValue); } let (port_id, remaining) = xv::Port::try_parse(value)?; let _ = remaining; Ok(ListSurfaceTypesRequest { port_id, }) } } impl Request for ListSurfaceTypesRequest { type Reply = ListSurfaceTypesReply; } pub fn list_surface_types(conn: &Conn, port_id: xv::Port) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListSurfaceTypesRequest { port_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListSurfaceTypesReply { pub sequence: u16, pub length: u32, pub surfaces: Vec, } impl TryParse for ListSurfaceTypesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (surfaces, remaining) = crate::x11_utils::parse_list::(remaining, num.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListSurfaceTypesReply { sequence, length, surfaces }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListSurfaceTypesReply { /// Get the value of the `num` field. /// /// The `num` field is used as the length field of the `surfaces` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num(&self) -> u32 { self.surfaces.len() .try_into().unwrap() } } /// Opcode for the CreateContext request pub const CREATE_CONTEXT_REQUEST: u8 = 2; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateContextRequest { pub context_id: Context, pub port_id: xv::Port, pub surface_id: Surface, pub width: u16, pub height: u16, pub flags: u32, } impl CreateContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_id_bytes = self.context_id.serialize(); let port_id_bytes = self.port_id.serialize(); let surface_id_bytes = self.surface_id.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let flags_bytes = self.flags.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_CONTEXT_REQUEST, 0, 0, context_id_bytes[0], context_id_bytes[1], context_id_bytes[2], context_id_bytes[3], port_id_bytes[0], port_id_bytes[1], port_id_bytes[2], port_id_bytes[3], surface_id_bytes[0], surface_id_bytes[1], surface_id_bytes[2], surface_id_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], flags_bytes[0], flags_bytes[1], flags_bytes[2], flags_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_id, remaining) = Context::try_parse(value)?; let (port_id, remaining) = xv::Port::try_parse(remaining)?; let (surface_id, remaining) = Surface::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (flags, remaining) = u32::try_parse(remaining)?; let _ = remaining; Ok(CreateContextRequest { context_id, port_id, surface_id, width, height, flags, }) } } impl Request for CreateContextRequest { type Reply = CreateContextReply; } pub fn create_context(conn: &Conn, context_id: Context, port_id: xv::Port, surface_id: Surface, width: u16, height: u16, flags: u32) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateContextRequest { context_id, port_id, surface_id, width, height, flags, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateContextReply { pub sequence: u16, pub width_actual: u16, pub height_actual: u16, pub flags_return: u32, pub priv_data: Vec, } impl TryParse for CreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (width_actual, remaining) = u16::try_parse(remaining)?; let (height_actual, remaining) = u16::try_parse(remaining)?; let (flags_return, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (priv_data, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateContextReply { sequence, width_actual, height_actual, flags_return, priv_data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl CreateContextReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `priv_data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.priv_data.len() .try_into().unwrap() } } /// Opcode for the DestroyContext request pub const DESTROY_CONTEXT_REQUEST: u8 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroyContextRequest { pub context_id: Context, } impl DestroyContextRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let context_id_bytes = self.context_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_CONTEXT_REQUEST, 0, 0, context_id_bytes[0], context_id_bytes[1], context_id_bytes[2], context_id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_CONTEXT_REQUEST { return Err(ParseError::InvalidValue); } let (context_id, remaining) = Context::try_parse(value)?; let _ = remaining; Ok(DestroyContextRequest { context_id, }) } } impl Request for DestroyContextRequest { type Reply = (); } pub fn destroy_context(conn: &Conn, context_id: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroyContextRequest { context_id, }; request0.send(conn) } /// Opcode for the CreateSurface request pub const CREATE_SURFACE_REQUEST: u8 = 4; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateSurfaceRequest { pub surface_id: Surface, pub context_id: Context, } impl CreateSurfaceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let surface_id_bytes = self.surface_id.serialize(); let context_id_bytes = self.context_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_SURFACE_REQUEST, 0, 0, surface_id_bytes[0], surface_id_bytes[1], surface_id_bytes[2], surface_id_bytes[3], context_id_bytes[0], context_id_bytes[1], context_id_bytes[2], context_id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_SURFACE_REQUEST { return Err(ParseError::InvalidValue); } let (surface_id, remaining) = Surface::try_parse(value)?; let (context_id, remaining) = Context::try_parse(remaining)?; let _ = remaining; Ok(CreateSurfaceRequest { surface_id, context_id, }) } } impl Request for CreateSurfaceRequest { type Reply = CreateSurfaceReply; } pub fn create_surface(conn: &Conn, surface_id: Surface, context_id: Context) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateSurfaceRequest { surface_id, context_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateSurfaceReply { pub sequence: u16, pub priv_data: Vec, } impl TryParse for CreateSurfaceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(24..).ok_or(ParseError::InsufficientData)?; let (priv_data, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateSurfaceReply { sequence, priv_data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl CreateSurfaceReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `priv_data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.priv_data.len() .try_into().unwrap() } } /// Opcode for the DestroySurface request pub const DESTROY_SURFACE_REQUEST: u8 = 5; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroySurfaceRequest { pub surface_id: Surface, } impl DestroySurfaceRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let surface_id_bytes = self.surface_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_SURFACE_REQUEST, 0, 0, surface_id_bytes[0], surface_id_bytes[1], surface_id_bytes[2], surface_id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_SURFACE_REQUEST { return Err(ParseError::InvalidValue); } let (surface_id, remaining) = Surface::try_parse(value)?; let _ = remaining; Ok(DestroySurfaceRequest { surface_id, }) } } impl Request for DestroySurfaceRequest { type Reply = (); } pub fn destroy_surface(conn: &Conn, surface_id: Surface) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroySurfaceRequest { surface_id, }; request0.send(conn) } /// Opcode for the CreateSubpicture request pub const CREATE_SUBPICTURE_REQUEST: u8 = 6; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CreateSubpictureRequest { pub subpicture_id: Subpicture, pub context: Context, pub xvimage_id: u32, pub width: u16, pub height: u16, } impl CreateSubpictureRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let subpicture_id_bytes = self.subpicture_id.serialize(); let context_bytes = self.context.serialize(); let xvimage_id_bytes = self.xvimage_id.serialize(); let width_bytes = self.width.serialize(); let height_bytes = self.height.serialize(); let mut request0 = vec![ extension_information.major_opcode, CREATE_SUBPICTURE_REQUEST, 0, 0, subpicture_id_bytes[0], subpicture_id_bytes[1], subpicture_id_bytes[2], subpicture_id_bytes[3], context_bytes[0], context_bytes[1], context_bytes[2], context_bytes[3], xvimage_id_bytes[0], xvimage_id_bytes[1], xvimage_id_bytes[2], xvimage_id_bytes[3], width_bytes[0], width_bytes[1], height_bytes[0], height_bytes[1], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != CREATE_SUBPICTURE_REQUEST { return Err(ParseError::InvalidValue); } let (subpicture_id, remaining) = Subpicture::try_parse(value)?; let (context, remaining) = Context::try_parse(remaining)?; let (xvimage_id, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let _ = remaining; Ok(CreateSubpictureRequest { subpicture_id, context, xvimage_id, width, height, }) } } impl Request for CreateSubpictureRequest { type Reply = CreateSubpictureReply; } pub fn create_subpicture(conn: &Conn, subpicture_id: Subpicture, context: Context, xvimage_id: u32, width: u16, height: u16) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = CreateSubpictureRequest { subpicture_id, context, xvimage_id, width, height, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct CreateSubpictureReply { pub sequence: u16, pub width_actual: u16, pub height_actual: u16, pub num_palette_entries: u16, pub entry_bytes: u16, pub component_order: [u8; 4], pub priv_data: Vec, } impl TryParse for CreateSubpictureReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (width_actual, remaining) = u16::try_parse(remaining)?; let (height_actual, remaining) = u16::try_parse(remaining)?; let (num_palette_entries, remaining) = u16::try_parse(remaining)?; let (entry_bytes, remaining) = u16::try_parse(remaining)?; let (component_order, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let component_order = <[u8; 4]>::try_from(component_order).unwrap(); let remaining = remaining.get(12..).ok_or(ParseError::InsufficientData)?; let (priv_data, remaining) = crate::x11_utils::parse_list::(remaining, length.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = CreateSubpictureReply { sequence, width_actual, height_actual, num_palette_entries, entry_bytes, component_order, priv_data }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl CreateSubpictureReply { /// Get the value of the `length` field. /// /// The `length` field is used as the length field of the `priv_data` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn length(&self) -> u32 { self.priv_data.len() .try_into().unwrap() } } /// Opcode for the DestroySubpicture request pub const DESTROY_SUBPICTURE_REQUEST: u8 = 7; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct DestroySubpictureRequest { pub subpicture_id: Subpicture, } impl DestroySubpictureRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let subpicture_id_bytes = self.subpicture_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, DESTROY_SUBPICTURE_REQUEST, 0, 0, subpicture_id_bytes[0], subpicture_id_bytes[1], subpicture_id_bytes[2], subpicture_id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_without_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != DESTROY_SUBPICTURE_REQUEST { return Err(ParseError::InvalidValue); } let (subpicture_id, remaining) = Subpicture::try_parse(value)?; let _ = remaining; Ok(DestroySubpictureRequest { subpicture_id, }) } } impl Request for DestroySubpictureRequest { type Reply = (); } pub fn destroy_subpicture(conn: &Conn, subpicture_id: Subpicture) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = DestroySubpictureRequest { subpicture_id, }; request0.send(conn) } /// Opcode for the ListSubpictureTypes request pub const LIST_SUBPICTURE_TYPES_REQUEST: u8 = 8; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ListSubpictureTypesRequest { pub port_id: xv::Port, pub surface_id: Surface, } impl ListSubpictureTypesRequest { /// Serialize this request into bytes for the provided connection fn serialize<'input, Conn>(self, conn: &Conn) -> Result>, ConnectionError> where Conn: RequestConnection + ?Sized, { let extension_information = conn.extension_information(X11_EXTENSION_NAME)? .ok_or(ConnectionError::UnsupportedExtension)?; let length_so_far = 0; let port_id_bytes = self.port_id.serialize(); let surface_id_bytes = self.surface_id.serialize(); let mut request0 = vec![ extension_information.major_opcode, LIST_SUBPICTURE_TYPES_REQUEST, 0, 0, port_id_bytes[0], port_id_bytes[1], port_id_bytes[2], port_id_bytes[3], surface_id_bytes[0], surface_id_bytes[1], surface_id_bytes[2], surface_id_bytes[3], ]; let length_so_far = length_so_far + request0.len(); assert_eq!(length_so_far % 4, 0); let length = u16::try_from(length_so_far / 4).unwrap_or(0); request0[2..4].copy_from_slice(&length.to_ne_bytes()); Ok((vec![request0.into()], vec![])) } pub fn send(self, conn: &Conn) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let (bytes, fds) = self.serialize(conn)?; let slices = bytes.iter().map(|b| IoSlice::new(&*b)).collect::>(); conn.send_request_with_reply(&slices, fds) } /// Parse this request given its header, its body, and any fds that go along with it pub fn try_parse_request(header: RequestHeader, value: &[u8]) -> Result { if header.minor_opcode != LIST_SUBPICTURE_TYPES_REQUEST { return Err(ParseError::InvalidValue); } let (port_id, remaining) = xv::Port::try_parse(value)?; let (surface_id, remaining) = Surface::try_parse(remaining)?; let _ = remaining; Ok(ListSubpictureTypesRequest { port_id, surface_id, }) } } impl Request for ListSubpictureTypesRequest { type Reply = ListSubpictureTypesReply; } pub fn list_subpicture_types(conn: &Conn, port_id: xv::Port, surface_id: Surface) -> Result, ConnectionError> where Conn: RequestConnection + ?Sized, { let request0 = ListSubpictureTypesRequest { port_id, surface_id, }; request0.send(conn) } #[derive(Debug, Clone, PartialEq, Eq)] pub struct ListSubpictureTypesReply { pub sequence: u16, pub length: u32, pub types: Vec, } impl TryParse for ListSubpictureTypesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::InsufficientData)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (num, remaining) = u32::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::InsufficientData)?; let (types, remaining) = crate::x11_utils::parse_list::(remaining, num.try_to_usize()?)?; if response_type != 1 { return Err(ParseError::InvalidValue); } let result = ListSubpictureTypesReply { sequence, length, types }; let _ = remaining; let remaining = initial_value.get(32 + length as usize * 4..) .ok_or(ParseError::InsufficientData)?; Ok((result, remaining)) } } impl ListSubpictureTypesReply { /// Get the value of the `num` field. /// /// The `num` field is used as the length field of the `types` field. /// This function computes the field's value again based on the length of the list. /// /// # Panics /// /// Panics if the value cannot be represented in the target type. This /// cannot happen with values of the struct received from the X11 server. pub fn num(&self) -> u32 { self.types.len() .try_into().unwrap() } } /// Extension trait defining the requests of this extension. pub trait ConnectionExt: RequestConnection { fn xvmc_query_version(&self) -> Result, ConnectionError> { query_version(self) } fn xvmc_list_surface_types(&self, port_id: xv::Port) -> Result, ConnectionError> { list_surface_types(self, port_id) } fn xvmc_create_context(&self, context_id: Context, port_id: xv::Port, surface_id: Surface, width: u16, height: u16, flags: u32) -> Result, ConnectionError> { create_context(self, context_id, port_id, surface_id, width, height, flags) } fn xvmc_destroy_context(&self, context_id: Context) -> Result, ConnectionError> { destroy_context(self, context_id) } fn xvmc_create_surface(&self, surface_id: Surface, context_id: Context) -> Result, ConnectionError> { create_surface(self, surface_id, context_id) } fn xvmc_destroy_surface(&self, surface_id: Surface) -> Result, ConnectionError> { destroy_surface(self, surface_id) } fn xvmc_create_subpicture(&self, subpicture_id: Subpicture, context: Context, xvimage_id: u32, width: u16, height: u16) -> Result, ConnectionError> { create_subpicture(self, subpicture_id, context, xvimage_id, width, height) } fn xvmc_destroy_subpicture(&self, subpicture_id: Subpicture) -> Result, ConnectionError> { destroy_subpicture(self, subpicture_id) } fn xvmc_list_subpicture_types(&self, port_id: xv::Port, surface_id: Surface) -> Result, ConnectionError> { list_subpicture_types(self, port_id, surface_id) } } impl ConnectionExt for C {} x11rb-0.8.1/src/resource_manager/matcher.rs010064400017500001750000000504511402220031600167320ustar 00000000000000//! Match Xrm entries against a query. use std::cmp::Ordering; use super::parser::parse_query; use super::{Binding, Component, Entry}; mod zip_longest { /// Given two slices, produce an iterator that zips the two slices. /// /// Compared to std::iter::Iterator::zip(), this iterator does not stop at the end of the /// shorter of the two slices, but instead continues to the end of the longer slice. To make /// this possible, the individual items are wrapped in `Option`. /// /// See tests below to make this clearer. pub(super) fn zip_longest<'a, T>( a: &'a [T], b: &'a [T], ) -> impl Iterator, Option<&'a T>)> + 'a { ZipLongest { a: a.iter(), b: b.iter(), } } #[derive(Debug)] struct ZipLongest { a: A, b: B, } impl Iterator for ZipLongest where A: Iterator, B: Iterator, { type Item = (Option, Option); fn next(&mut self) -> Option { match (self.a.next(), self.b.next()) { (None, None) => None, (a, b) => Some((a, b)), } } } #[cfg(test)] mod test_zip_longest { use super::zip_longest; #[test] fn empty() { let (a, b): ([u8; 0], [u8; 0]) = ([], []); let res = zip_longest(&a, &b).collect::>(); assert_eq!(res, []); } #[test] fn same_length() { let a = [0, 1, 2]; let b = [4, 5, 6]; let expected = [ (Some(&0), Some(&4)), (Some(&1), Some(&5)), (Some(&2), Some(&6)), ]; let res = zip_longest(&a, &b).collect::>(); assert_eq!(res, expected); } #[test] fn first_shorter() { let a = [0, 1]; let b = [4, 5, 6, 7]; let expected = [ (Some(&0), Some(&4)), (Some(&1), Some(&5)), (None, Some(&6)), (None, Some(&7)), ]; let res = zip_longest(&a, &b).collect::>(); assert_eq!(res, expected); } #[test] fn second_shorter() { let a = [0, 1, 2, 3]; let b = [4, 5]; let expected = [ (Some(&0), Some(&4)), (Some(&1), Some(&5)), (Some(&2), None), (Some(&3), None), ]; let res = zip_longest(&a, &b).collect::>(); assert_eq!(res, expected); } } } /// Info how a specific component was matched. /// /// This information is used to decide which of two matches is "better" in `compare_matches()`. #[derive(Debug, Copy, Clone)] enum HowMatched { /// The component matched the instance of the query Instance, /// The component matched the class of the query Class, /// The component is a wildcard and thus matched by default Wildcard, } /// Info on how an (unskipped) component of the query was matched /// /// This information is used to decide which of two matches is "better" in `compare_matches()`. #[derive(Debug, Copy, Clone)] struct MatchComponent { preceding_binding: Binding, how_matched: HowMatched, } /// Info how a (possibly skipped) component of the query was matched /// /// This information is used to decide which of two matches is "better" in `compare_matches()`. #[derive(Debug, Copy, Clone)] enum MatchKind { /// The component was skipped via a loose binding ("*") SkippedViaLooseBinding, /// The component was matched against the entry. Matched(MatchComponent), } impl MatchKind { /// Create a new `MatchKind::Match` with the given entries. fn new_match(preceding_binding: Binding, how_matched: HowMatched) -> Self { Self::Matched(MatchComponent { preceding_binding, how_matched, }) } } fn check_match(entry: &Entry, resource: &[String], class: &[String]) -> Vec> { /// Current state of the matching machinery #[derive(Debug, Default)] struct MatchState { /// Index into the entry on where we have to continue matching index: usize, /// How did we get to this state? history: Vec, } impl MatchState { /// Record that a component was skipped via a loose binding (`*`). fn skip_loose(&self) -> Self { let mut history = self.history.clone(); history.push(MatchKind::SkippedViaLooseBinding); Self { index: self.index, history, } } /// Record that a component was matched in the given way. fn step(mut self, kind: MatchKind) -> Self { self.history.push(kind); self.index += 1; self } } // The idea is to check if a nondeterministic finite automaton accepts a given // word. We have a set of current states. This describes where in the // entry we are while trying to match. When we match a component, we go to the next // component in the entry (index + 1, `MatchState::step()`). When we have a loose binding, we // can accept the current component by staying in the same state (index, // `MatchState::skip_loose()`). let mut states = vec![MatchState::default()]; // Go through the components and match them against the query for (resource, class) in zip_longest::zip_longest(resource, class) { let mut next_states = Vec::new(); for state in states.into_iter() { if state.index == entry.components.len() { // We are at the end of the entry and thus cannot continue this match. // We drop this match state. continue; } let binding = entry.components[state.index].0; match binding { // We have to match here, no way around that. Binding::Tight => {} // We could "eat" this with the loose binding by staying in the state Binding::Loose => next_states.push(state.skip_loose()), } // Does the component match? let kind = match entry.components[state.index].1 { Component::Wildcard => Some(MatchKind::new_match(binding, HowMatched::Wildcard)), Component::Normal(ref s) => { if Some(s) == resource { Some(MatchKind::new_match(binding, HowMatched::Instance)) } else if Some(s) == class { Some(MatchKind::new_match(binding, HowMatched::Class)) } else { None } } }; if let Some(kind) = kind { // Yes, the component matches and we go to the next state next_states.push(state.step(kind)); } } states = next_states; } // We have a match if we reached the end of the components states .into_iter() .filter(|s| s.index == entry.components.len()) .map(|s| s.history) .collect() } /// Compare two matches and decide which one of the two is better (`Ordering::Greater`) fn compare_matches(match1: &[MatchKind], match2: &[MatchKind]) -> Ordering { use Binding::*; use HowMatched::*; use MatchKind::*; fn rule1(match1: &MatchKind, match2: &MatchKind) -> Ordering { // Precedence rule #1: Matching components (including wildcard '?') outweighs loose bindings ('*') if let Matched(_) = match1 { if let SkippedViaLooseBinding = match2 { return Ordering::Greater; } } Ordering::Equal } fn rule2(match1: &MatchKind, match2: &MatchKind) -> Ordering { // Precedence rule #2a: Matching instance outweighs both matching class and wildcard if let Matched(MatchComponent { how_matched: Instance, preceding_binding: _, }) = match1 { if let Matched(MatchComponent { how_matched: Class, preceding_binding: _, }) = match2 { return Ordering::Greater; } if let Matched(MatchComponent { how_matched: Wildcard, .. }) = match2 { return Ordering::Greater; } } // Precedence rule #2b: Matching class outweighs wildcard if let Matched(MatchComponent { how_matched: Class, .. }) = match1 { if let Matched(MatchComponent { how_matched: Wildcard, .. }) = match2 { return Ordering::Greater; } } Ordering::Equal } fn rule3(match1: &MatchKind, match2: &MatchKind) -> Ordering { // Precedence rule #3: A preceding exact match outweights a preceding '*' if let Matched(MatchComponent { preceding_binding: Tight, .. }) = match1 { if let Matched(MatchComponent { preceding_binding: Loose, .. }) = match2 { return Ordering::Greater; } } Ordering::Equal } assert_eq!( match1.len(), match2.len(), "Both matches should have the same length (which is guaranteed by the current \ implementation of check_match())" ); for (m1, m2) in match1.iter().zip(match2.iter()) { let ordering = rule1(m1, m2) .then_with(|| rule1(m2, m1).reverse()) .then_with(|| rule2(m1, m2)) .then_with(|| rule2(m2, m1).reverse()) .then_with(|| rule3(m1, m2)) .then_with(|| rule3(m2, m1).reverse()); if ordering != Ordering::Equal { return ordering; } } Ordering::Equal } /// Find the best match for the given query in the database, returning `None` when nothing matches. pub(crate) fn match_entry<'a>( database: &'a [Entry], resource: &str, class: &str, ) -> Option<&'a [u8]> { let resource = parse_query(resource.as_bytes())?; let class = parse_query(class.as_bytes())?; database .iter() // Filter for entries that match the query (and record some info on how they match) .flat_map(|entry| { let matches = check_match(entry, &resource, &class); let best_match = matches .into_iter() .max_by(|match1, match2| compare_matches(match1, match2)); best_match.map(|m| (entry, m)) }) .max_by(|(_, match1), (_, match2)| compare_matches(match1, match2)) .map(|(entry, _)| &entry.value[..]) } #[cfg(test)] mod test { use super::super::parser::parse_database; use super::match_entry; // Most tests in here are based on [1], which is: Copyright © 2016 Ingo Bürk // [1]: https://github.com/Airblader/xcb-util-xrm/blob/master/tests/tests_match.c #[test] fn test_matches() { let tests = [ // Non-matches / Errors (&b""[..], "", "", None), // Xlib returns the match here, despite the query violating the specs (different number // of components in the query) ( b"First.second: 1", "First.second", "First.second.third", None, ), (b"", "First.second", "", None), (b"First.second: 1", "First.third", "", None), (b"First.second: 1", "First", "", None), (b"First: 1", "First.second", "", None), (b"First.?.fourth: 1", "First.second.third.fourth", "", None), (b"First*?.third: 1", "First.third", "", None), (b"First: 1", "first", "", None), (b"First: 1", "", "first", None), // Duplicate entries ( b"First: 1\nFirst: 2\nFirst: 3\n", "First", "", Some(&b"3"[..]), ), ( b"First: 1\nSecond: 2\nSecond: 3\nThird: 4\n", "Second", "", Some(b"3"), ), // Basic matching (b"First: 1", "First", "", Some(b"1")), (b"First.second: 1", "First.second", "", Some(b"1")), (b"?.second: 1", "First.second", "", Some(b"1")), (b"First.?.third: 1", "First.second.third", "", Some(b"1")), ( b"First.?.?.fourth: 1", "First.second.third.fourth", "", Some(b"1"), ), (b"*second: 1", "First.second", "", Some(b"1")), (b".second: 1", "First.second", "", None), (b"*third: 1", "First.second.third", "", Some(b"1")), (b"First*second: 1", "First.second", "", Some(b"1")), (b"First*third: 1", "First.second.third", "", Some(b"1")), ( b"First*fourth: 1", "First.second.third.fourth", "", Some(b"1"), ), (b"First*?.third: 1", "First.second.third", "", Some(b"1")), (b"First: 1", "Second", "First", Some(b"1")), ( b"First.second: 1", "First.third", "first.second", Some(b"1"), ), ( b"First.second.third: 1", "First.third.third", "first.second.fourth", Some(b"1"), ), ( b"First*third*fifth: 1", "First.second.third.fourth.third.fifth", "", Some(b"1"), ), (b"First: x\\\ny", "First", "", Some(b"xy")), (b"! First: x", "First", "", None), (b"# First: x", "First", "", None), (b"First:", "First", "", Some(b"")), (b"First: ", "First", "", Some(b"")), (b"First: \t ", "First", "", Some(b"")), // Consecutive bindings (b"*.bar: 1", "foo.foo.bar", "", Some(b"1")), (b"...bar: 1", "foo.bar", "", None), (b"...bar: 1", "foo.foo.foo.bar", "", None), (b"***bar: 1", "foo.bar", "", Some(b"1")), (b".*.bar: 1", "foo.bar", "", Some(b"1")), (b".*.bar: 1", "foo.foo.bar", "", Some(b"1")), (b"..*bar: 1", "foo.foo.foo.foo.bar", "", Some(b"1")), (b"a.*.z: 1", "a.b.c.d.e.f.z", "", Some(b"1")), (b"a...z: 1", "a.z", "", Some(b"1")), (b"a...z: 1", "a.b.z", "", None), // Matching among multiple entries (b"First: 1\nSecond: 2\n", "First", "", Some(b"1")), (b"First: 1\nSecond: 2\n", "Second", "", Some(b"2")), // Greediness (b"a*c.e: 1", "a.b.c.d.c.e", "", Some(b"1")), (b"a*c.e: 1", "a.b.c.c.e", "", Some(b"1")), (b"a*?.e: 1", "a.b.c.e", "", Some(b"1")), (b"a*c*e: 1", "a.b.c.d.c.d.e.d.e", "", Some(b"1")), // Precedence rules // Rule 1 ( b"First.second.third: 1\nFirst*third: 2\n", "First.second.third", "", Some(b"1"), ), ( b"First*third: 2\nFirst.second.third: 1\n", "First.second.third", "", Some(b"1"), ), ( b"First.second.third: 1\nFirst*third: 2\n", "x.x.x", "First.second.third", Some(b"1"), ), ( b"First*third: 2\nFirst.second.third: 1\n", "x.x.x", "First.second.third", Some(b"1"), ), // Rule 2 ( b"First.second: 1\nFirst.third: 2\n", "First.second", "First.third", Some(b"1"), ), ( b"First.third: 2\nFirst.second: 1\n", "First.second", "First.third", Some(b"1"), ), ( b"First.second.third: 1\nFirst.?.third: 2\n", "First.second.third", "", Some(b"1"), ), ( b"First.?.third: 2\nFirst.second.third: 1\n", "First.second.third", "", Some(b"1"), ), ( b"First.second.third: 1\nFirst.?.third: 2\n", "x.x.x", "First.second.third", Some(b"1"), ), ( b"First.?.third: 2\nFirst.second.third: 1\n", "x.x.x", "First.second.third", Some(b"1"), ), // Rule 3 ( b"First.second: 1\nFirst*second: 2\n", "First.second", "", Some(b"1"), ), ( b"First*second: 2\nFirst.second: 1\n", "First.second", "", Some(b"1"), ), // Some real world examples. May contain duplicates to the above tests. // From the specification: // https://tronche.com/gui/x/xlib/resource-manager/matching-rules.html ( b"xmh*Paned*activeForeground: red\n\ *incorporate.Foreground: blue\n\ xmh.toc*Command*activeForeground: green\n\ xmh.toc*?.Foreground: white\n\ xmh.toc*Command.activeForeground: black", "xmh.toc.messagefunctions.incorporate.activeForeground", "Xmh.Paned.Box.Command.Foreground", Some(b"black"), ), ( b"urxvt*background: [95]#000", "urxvt.background", "", Some(b"[95]#000"), ), ( b"urxvt*scrollBar_right:true", "urxvt.scrollBar_right", "", Some(b"true"), ), ( b"urxvt*cutchars: '\"'()*<>[]{|}", "urxvt.cutchars", "", Some(b"'\"'()*<>[]{|}"), ), ( b"urxvt.keysym.Control-Shift-Up: perl:font:increment", "urxvt.keysym.Control-Shift-Up", "", Some(b"perl:font:increment"), ), ( b"rofi.normal: #000000, #000000, #000000, #000000", "rofi.normal", "", Some(b"#000000, #000000, #000000, #000000"), ), // Own tests (b"*foo.bar: 1", "bar", "", None), ( b"First.Second.Third: 1\nFirst.Second: 2", "First.Second.Third", "First.Second", Some(b"1"), ), ( b"First.Second.Third: 1\nFirst.Second: 2", "First.Second", "First.Second.Third", Some(b"1"), ), ]; let mut failures = 0; for &(data, resource, class, expected) in tests.iter() { let mut entries = Vec::new(); parse_database(data, &mut entries, |_, _| unreachable!()); let result = match_entry(&entries, resource, class); if result != expected { eprintln!( "While testing resource '{}' and class '{}' with the following input:", resource, class ); eprintln!("{}", print_string(data)); eprintln!("Expected: {:?}", expected.map(print_string)); eprintln!("Got: {:?}", result.map(print_string)); eprintln!(); failures += 1; } } if failures != 0 { panic!("Had {} failures", failures) } } fn print_string(data: &[u8]) -> String { std::str::from_utf8(data) .map(|s| s.to_string()) .unwrap_or_else(|_| format!("{:?}", data)) } } x11rb-0.8.1/src/resource_manager/mod.rs010064400017500001750000000361111402220031600160630ustar 00000000000000//! X11 resource manager library. //! //! Usage example (please cache the database in real applications instead of re-opening it whenever //! a value is needed): //! ``` //! use x11rb::{connection::Connection, errors::ReplyError, resource_manager::Database}; //! fn get_xft_dpi(conn: &impl Connection) -> Result, ReplyError> { //! let db = Database::new_from_default(conn)?; //! let value = db.get_value("Xft.dpi", ""); //! Ok(value.ok().flatten()) //! } //! ``` //! //! This functionality is similar to what is available to C code through xcb-util-xrm and Xlib's //! `Xrm*` function family. Not all their functionality is available in this library. Please open a //! feature request if you need something that is not available. //! //! The code in this module is only available when the `resource_manager` feature of the library is //! enabled. use std::env::var_os; use std::path::{Path, PathBuf}; use std::str::FromStr; use crate::connection::Connection; use crate::errors::ReplyError; use crate::protocol::xproto::{AtomEnum, ConnectionExt as _}; mod matcher; mod parser; /// Maximum nesting of #include directives, same value as Xlib uses. /// After following this many `#include` directives, further includes are ignored. const MAX_INCLUSION_DEPTH: u8 = 100; /// How tightly does the component of an entry match a query? #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Binding { /// We have a tight match, meaning that the next component of the entry must match the query. Tight, /// We have a loose match, meaning that any number of components can be skipped before the next /// match. Loose, } /// A component of a database entry. #[derive(Debug, Clone, PartialEq, Eq)] enum Component { /// A string component Normal(String), // Actually just a-z, A-Z, 0-9 and _ or - is allowed /// A wildcard component ("?") that matches anything Wildcard, } /// A single entry in the resource manager database. #[derive(Debug, Clone, PartialEq)] pub(crate) struct Entry { /// The components of the entry describe which queries it matches components: Vec<(Binding, Component)>, /// The value of the entry is what the caller gets after a match. value: Vec, } /// A X11 resource database. /// /// The recommended way to load a database is through [`Database::new_from_default`]. #[derive(Debug, Default, Clone)] pub struct Database { entries: Vec, } impl Database { /// Create a new X11 resource database from the default locations. /// /// The default location is a combination of two places. First, the following places are /// searched for data: /// - The `RESOURCE_MANAGER` property of the first screen's root window (See /// [`Self::new_from_resource_manager`]). /// - If not found, the file `$HOME/.Xresources` is loaded. /// - If not found, the file `$HOME/.Xdefaults` is loaded. /// /// The result of the above search of the above search is combined with: /// - The contents of the file `$XENVIRONMENT`, if this environment variable is set. /// - Otherwise, the contents of `$HOME/.Xdefaults-[hostname]`. /// /// This function only returns an error if communication with the X11 server fails. All other /// errors are ignored. It might be that an empty database is returned. /// /// The behaviour of this function is mostly equivalent to Xlib's `XGetDefault()`. The /// exception is that `XGetDefault()` does not load `$HOME/.Xresources`. /// /// The behaviour of this function is equivalent to xcb-util-xrm's /// `xcb_xrm_database_from_default()`. pub fn new_from_default(conn: &impl Connection) -> Result { let cur_dir = Path::new("."); // 1. Try to load the RESOURCE_MANAGER property let mut entries = if let Some(db) = Self::new_from_resource_manager(conn)? { db.entries } else { let mut entries = Vec::new(); if let Some(home) = var_os("HOME") { // 2. Otherwise, try to load $HOME/.Xresources let mut path = PathBuf::from(&home); path.push(".Xresources"); let read_something = if let Ok(data) = std::fs::read(&path) { parse_data_with_base_directory(&mut entries, &data, Path::new(&home), 0); true } else { false }; // Restore the path so it refers to $HOME again let _ = path.pop(); if !read_something { // 3. Otherwise, try to load $HOME/.Xdefaults path.push(".Xdefaults"); if let Ok(data) = std::fs::read(&path) { parse_data_with_base_directory(&mut entries, &data, Path::new(&home), 0); } } } entries }; // 4. If XENVIRONMENT is specified, merge the database defined by that file if let Some(xenv) = var_os("XENVIRONMENT") { if let Ok(data) = std::fs::read(&xenv) { let base = Path::new(&xenv).parent().unwrap_or(cur_dir); parse_data_with_base_directory(&mut entries, &data, base, 0); } } else { // 5. Load `$HOME/.Xdefaults-[hostname]` let mut file = std::ffi::OsString::from(".Xdefaults-"); file.push(gethostname::gethostname()); let mut path = match var_os("HOME") { Some(home) => PathBuf::from(home), None => PathBuf::new(), }; path.push(file); if let Ok(data) = std::fs::read(&path) { let base = path.parent().unwrap_or(cur_dir); parse_data_with_base_directory(&mut entries, &data, base, 0); } } Ok(Self { entries }) } /// Create a new X11 resource database from the `RESOURCE_MANAGER` property of the first /// screen's root window. /// /// This function returns an error if the `GetProperty` request to get the `RESOURCE_MANAGER` /// property fails. It returns `Ok(None)` if the property does not exist, has the wrong format, /// or is empty. pub fn new_from_resource_manager(conn: &impl Connection) -> Result, ReplyError> { let max_length = 100_000_000; // This is what Xlib does, so it must be correct (tm) let window = conn.setup().roots[0].root; let property = conn .get_property( false, window, AtomEnum::RESOURCE_MANAGER, AtomEnum::STRING, 0, max_length, )? .reply()?; if property.format == 8 && !property.value.is_empty() { Ok(Some(Self::new_from_data(&property.value))) } else { Ok(None) } } /// Construct a new X11 resource database from raw data. /// /// This function parses data like `Some.Entry: Value\n#include "some_file"\n` and returns the /// resulting resource database. Parsing cannot fail since unparsable lines are simply ignored. /// /// See [`Self::new_from_data_with_base_directory`] for a version that allows to provide a path that /// is used for resolving relative `#include` statements. pub fn new_from_data(data: &[u8]) -> Self { let mut entries = Vec::new(); parse_data_with_base_directory(&mut entries, data, Path::new("."), 0); Self { entries } } /// Construct a new X11 resource database from raw data. /// /// This function parses data like `Some.Entry: Value\n#include "some_file"\n` and returns the /// resulting resource database. Parsing cannot fail since unparsable lines are simply ignored. /// /// When a relative `#include` statement is encountered, the file to include is searched /// relative to the given `base_path`. pub fn new_from_data_with_base_directory(data: &[u8], base_path: impl AsRef) -> Self { fn helper(data: &[u8], base_path: &Path) -> Database { let mut entries = Vec::new(); parse_data_with_base_directory(&mut entries, data, base_path, 0); Database { entries } } helper(data, base_path.as_ref()) } /// Get a value from the resource database as a byte slice. /// /// The given values describe a query to the resource database. `resource_class` can be an /// empty string, but otherwise must contain the same number of components as `resource_name`. /// Both strings may only contain alphanumeric characters or '-', '_', and '.'. /// /// For example, this is how Xterm could query one of its settings if it where written in Rust /// (see `man xterm`): /// ``` /// use x11rb::resource_manager::Database; /// fn get_pointer_shape(db: &Database) -> &[u8] { /// db.get_bytes("XTerm.vt100.pointerShape", "XTerm.VT100.Cursor").unwrap_or(b"xterm") /// } /// ``` pub fn get_bytes(&self, resource_name: &str, resource_class: &str) -> Option<&[u8]> { matcher::match_entry(&self.entries, resource_name, resource_class) } /// Get a value from the resource database as a byte slice. /// /// The given values describe a query to the resource database. `resource_class` can be an /// empty string, but otherwise must contain the same number of components as `resource_name`. /// Both strings may only contain alphanumeric characters or '-', '_', and '.'. /// /// If an entry is found that is not a valid utf8 `str`, `None` is returned. /// /// For example, this is how Xterm could query one of its settings if it where written in Rust /// (see `man xterm`): /// ``` /// use x11rb::resource_manager::Database; /// fn get_pointer_shape(db: &Database) -> &str { /// db.get_string("XTerm.vt100.pointerShape", "XTerm.VT100.Cursor").unwrap_or("xterm") /// } /// ``` pub fn get_string(&self, resource_name: &str, resource_class: &str) -> Option<&str> { std::str::from_utf8(self.get_bytes(resource_name, resource_class)?).ok() } /// Get a value from the resource database as a byte slice. /// /// The given values describe a query to the resource database. `resource_class` can be an /// empty string, but otherwise must contain the same number of components as `resource_name`. /// Both strings may only contain alphanumeric characters or '-', '_', and '.'. /// /// This function interprets "true", "on", "yes" as true-ish and "false", "off", "no" als /// false-ish. Numbers are parsed and are true if they are not zero. Unknown values are mapped /// to `None`. /// /// For example, this is how Xterm could query one of its settings if it where written in Rust /// (see `man xterm`): /// ``` /// use x11rb::resource_manager::Database; /// fn get_bell_is_urgent(db: &Database) -> bool { /// db.get_bool("XTerm.vt100.bellIsUrgent", "XTerm.VT100.BellIsUrgent").unwrap_or(false) /// } /// ``` pub fn get_bool(&self, resource_name: &str, resource_class: &str) -> Option { to_bool(self.get_string(resource_name, resource_class)?) } /// Get a value from the resource database and parse it. /// /// The given values describe a query to the resource database. `resource_class` can be an /// empty string, but otherwise must contain the same number of components as `resource_name`. /// Both strings may only contain alphanumeric characters or '-', '_', and '.'. /// /// If no value is found, `Ok(None)` is returned. Otherwise, the result from /// [`FromStr::from_str]` is returned with `Ok(value)` replaced with `Ok(Some(value))`. /// /// For example, this is how Xterm could query one of its settings if it where written in Rust /// (see `man xterm`): /// ``` /// use x11rb::resource_manager::Database; /// fn get_print_attributes(db: &Database) -> u8 { /// db.get_value("XTerm.vt100.printAttributes", "XTerm.VT100.PrintAttributes") /// .ok().flatten().unwrap_or(1) /// } /// ``` pub fn get_value( &self, resource_name: &str, resource_class: &str, ) -> Result, T::Err> where T: FromStr, { self.get_string(resource_name, resource_class) .map(T::from_str) .transpose() } } /// Parse the given data as a resource database. /// /// The parsed entries are appended to `result`. `#include`s are resolved relative to the given /// `base_path`. `depth` is the number of includes that we are already handling. This value is used /// to prevent endless loops when a file (directly or indirectly) includes itself. fn parse_data_with_base_directory( result: &mut Vec, data: &[u8], base_path: &Path, depth: u8, ) { if depth > MAX_INCLUSION_DEPTH { return; } parser::parse_database(data, result, |path, entries| { // Construct the name of the file to include if let Ok(path) = std::str::from_utf8(path) { let mut path_buf = PathBuf::from(base_path); path_buf.push(path); // Read the file contents if let Ok(new_data) = std::fs::read(&path_buf) { // Parse the file contents with the new base path let new_base = path_buf.parent().unwrap_or(base_path); parse_data_with_base_directory(entries, &new_data, new_base, depth + 1); } } }); } /// Parse a value to a boolean, returning `None` if this is not possible. fn to_bool(data: &str) -> Option { if let Ok(num) = i64::from_str(data) { return Some(num != 0); } match data.to_lowercase().as_bytes() { b"true" => Some(true), b"on" => Some(true), b"yes" => Some(true), b"false" => Some(false), b"off" => Some(false), b"no" => Some(false), _ => None, } } #[cfg(test)] mod test { use super::{to_bool, Database}; #[test] fn test_bool_true() { let data = ["1", "10", "true", "TRUE", "on", "ON", "yes", "YES"]; for input in &data { assert_eq!(Some(true), to_bool(input)); } } #[test] fn test_bool_false() { let data = ["0", "false", "FALSE", "off", "OFF", "no", "NO"]; for input in &data { assert_eq!(Some(false), to_bool(input)); } } #[test] fn test_bool_none() { let data = ["", "abc"]; for input in &data { assert_eq!(None, to_bool(input)); } } #[test] fn test_parse_i32_fail() { let db = Database::new_from_data(b"a:"); assert_eq!(db.get_string("a", "a"), Some("")); assert!(db.get_value::("a", "a").is_err()); } #[test] fn test_parse_i32_success() { let data = [ (&b"a: 0"[..], 0), (b"a: 1", 1), (b"a: -1", -1), (b"a: 100", 100), ]; for (input, expected) in data.iter() { let db = Database::new_from_data(input); let result = db.get_value::("a", "a"); assert_eq!(result.unwrap().unwrap(), *expected); } } } x11rb-0.8.1/src/resource_manager/parser.rs010064400017500001750000000547611402220031600166130ustar 00000000000000//! Code for parsing resource management things use super::{Binding, Component, Entry}; // ======================= // Common helper functions // ======================= /// Check if a character (well, u8) is an octal digit fn is_octal_digit(c: u8) -> bool { match c { b'0' | b'1' | b'2' | b'3' | b'4' | b'5' | b'6' | b'7' => true, _ => false, } } /// Find the longest prefix of the given data where the given callback returns true fn parse_with_matcher(data: &[u8], matcher: M) -> (&[u8], &[u8]) where M: Fn(u8) -> bool, { let end = data .iter() .enumerate() .find(|(_, &c)| !matcher(c)) .map(|(idx, _)| idx) .unwrap_or(data.len()); (&data[..end], &data[end..]) } /// Check if a character is allowed in a quark name fn allowed_in_quark_name(c: u8) -> bool { c.is_ascii_alphanumeric() || c == b'-' || c == b'_' } /// Find the longest prefix satisfying allowed_in_quark_name(). /// This returns (Some(prefix), remaining) if a prefix is found, else (None, data). fn next_component(data: &[u8]) -> (Option<&[u8]>, &[u8]) { let (prefix, remaining) = parse_with_matcher(data, allowed_in_quark_name); match prefix { [] => (None, remaining), prefix => (Some(prefix), remaining), } } // ========================= // Parser for resource files // ========================= /// Skip to the next end of line in the given data fn skip_to_eol(data: &[u8]) -> &[u8] { parse_with_matcher(data, |c| c != b'\n').1 } /// Skip all spaces in the given data fn skip_spaces(data: &[u8]) -> &[u8] { parse_with_matcher(data, |c| c == b' ').1 } /// Skip the given text. Returns `None` if the text was not found fn skip_text<'a>(data: &'a [u8], text: &[u8]) -> Option<&'a [u8]> { if data.starts_with(text) { Some(&data[text.len()..]) } else { None } } /// Parse a single `Component` from the data. This can either be a wildcard ("?") or a /// component made up of characters accepted by `allowed_in_quark_name`. fn next_component_name(data: &[u8]) -> (Option, &[u8]) { if data.first() == Some(&b'?') { (Some(Component::Wildcard), &data[1..]) } else { let (comp, remaining) = next_component(data); let comp = comp.map(|s| { let s = std::str::from_utf8(s).expect("ascii-only"); Component::Normal(s.to_string()) }); (comp, remaining) } } /// Parse a resource like "foo.?*baz" (wildcards allowed) fn parse_components(data: &[u8]) -> (Vec<(Binding, Component)>, &[u8]) { fn parse_binding(mut data: &[u8]) -> (Binding, &[u8]) { let mut binding = Binding::Tight; loop { match data.first() { Some(&b'*') => binding = Binding::Loose, Some(&b'.') => {} _ => break, } data = &data[1..]; } (binding, data) } let mut data = data; let mut result = Vec::new(); loop { let (binding, remaining) = parse_binding(data); if let (Some(component), remaining) = next_component_name(remaining) { data = remaining; result.push((binding, component)); } else { break; } } (result, data) } /// Parse a full entry from the data. This begins with components (see `parse_components()`), /// then after a colon (":") comes the value. The value may contain escape sequences. fn parse_entry(data: &[u8]) -> (Result, &[u8]) { let (components, data) = parse_components(data); match components.last() { // Empty components are not allowed None => return (Err(()), skip_to_eol(data)), // The last component may not be a wildcard Some((_, Component::Wildcard)) => return (Err(()), skip_to_eol(data)), _ => {} } let data = skip_spaces(data); // next comes a colon let data = match data.split_first() { Some((&b':', data)) => data, _ => return (Err(()), skip_to_eol(data)), }; // skip more spaces and let \ escape line breaks let mut data = data; loop { let (_, remaining) = parse_with_matcher(data, |c| c == b' ' || c == b'\t'); if remaining.get(..2) == Some(&b"\\\n"[..]) { data = &remaining[2..]; } else { data = remaining; break; } } // Parse the value, decoding escape sequences. The most complicated case are octal escape // sequences like \123. let mut value = Vec::new(); let mut index = 0; let mut octal = None; while let Some(&b) = data.get(index) { index += 1; if b == b'\n' { break; } if let Some(oct) = octal { if is_octal_digit(b) { // We are currently parsing an octal; add the new character match oct { (x, None) => octal = Some((x, Some(b))), (x, Some(y)) => { let (x, y, z) = (x - b'0', y - b'0', b - b'0'); let decoded = (x * 8 + y) * 8 + z; value.push(decoded); octal = None; } } continue; } else { // Not an octal sequence; add the collected characters to the output value.push(b'\\'); value.push(oct.0); if let Some(oct2) = oct.1 { value.push(oct2); } octal = None; // Fall through to the parsing code below } } if b != b'\\' { value.push(b); } else { match data.get(index) { None => { value.push(b); // Keep index as-is. This is to counter the += 1 below. index -= 1; } Some(b' ') => value.push(b' '), Some(b'\t') => value.push(b'\t'), Some(b'n') => value.push(b'\n'), Some(b'\\') => value.push(b'\\'), Some(b'\n') => { /* Continue parsing next line */ } Some(&x) if is_octal_digit(x) => octal = Some((x, None)), Some(&x) => { value.push(b); value.push(x); } } index += 1; } } let entry = Entry { components, value }; (Ok(entry), &data[index..]) } /// Parse the contents of a database pub(crate) fn parse_database(mut data: &[u8], result: &mut Vec, mut include_callback: F) where for<'r> F: FnMut(&'r [u8], &mut Vec), { // Iterate over lines while let Some(first) = data.first() { match first { // Skip empty lines b'\n' => data = &data[1..], // Comment, skip the line b'!' => data = skip_to_eol(data), b'#' => { let remaining = skip_spaces(&data[1..]); // Skip to the next line for the next loop iteration. The rest of the code here // tried to parse the line. data = skip_to_eol(remaining); // Only #include is defined if let Some(remaining) = skip_text(remaining, b"include") { let (_, remaining) = parse_with_matcher(remaining, |c| c == b' '); // Find the text enclosed in quotation marks if let Some(b'\"') = remaining.first() { let (file, remaining) = parse_with_matcher(&remaining[1..], |c| c != b'"' && c != b'\n'); if let Some(b'\"') = remaining.first() { // Okay, we found a well-formed include directive. include_callback(file, result); } } } } _ => { let (entry, remaining) = parse_entry(data); data = remaining; // Add the entry to the result if we parsed one; ignore errors result.extend(entry.ok()); } } } } /// Parse a resource query like "foo.bar.baz" (no wildcards allowed, no bindings allowed) pub(crate) fn parse_query(data: &[u8]) -> Option> { let mut data = data; let mut result = Vec::new(); while let (Some(component), remaining) = next_component(data) { data = remaining; while let Some(&b'.') = data.first() { data = &data[1..]; } let component = std::str::from_utf8(component).expect("ascii-only"); result.push(component.to_string()); } if data.is_empty() { Some(result) } else { None } } #[cfg(test)] mod test { use super::{parse_database, parse_entry, parse_query, Binding, Component, Entry}; // Most tests in here are based on [1], which is: Copyright © 2016 Ingo Bürk // [1]: https://github.com/Airblader/xcb-util-xrm/blob/master/tests/tests_parser.c #[test] fn test_parse_query_success() { let tests = [ ( &b"First.second"[..], vec!["First".to_string(), "second".to_string()], ), (b"", Vec::new()), ( b"urxvt.scrollBar_right", vec!["urxvt".to_string(), "scrollBar_right".to_string()], ), ( b"urxvt.Control-Shift-Up", vec!["urxvt".to_string(), "Control-Shift-Up".to_string()], ), ]; for (data, expected) in tests.iter() { let result = parse_query(*data); assert_eq!(result.as_ref(), Some(expected), "while parsing {:?}", data); } } #[test] fn test_parse_query_error() { let tests = [ &b"First.second: on"[..], b"First*second", b"First.?.second", b"*second", b"?.second", ]; for data in tests.iter() { let result = parse_query(*data); if result.is_some() { panic!("Unexpected success parsing '{:?}': {:?}", data, result); } } } #[test] fn test_parse_entry_success() { let tests = [ // Basics ( &b"First: 1"[..], vec![(Binding::Tight, Component::Normal("First".to_string()))], &b"1"[..], ), ( b"First.second: 1", vec![ (Binding::Tight, Component::Normal("First".to_string())), (Binding::Tight, Component::Normal("second".to_string())), ], b"1", ), ( b"First..second: 1", vec![ (Binding::Tight, Component::Normal("First".to_string())), (Binding::Tight, Component::Normal("second".to_string())), ], b"1", ), // Wildcards ( b"?.second: 1", vec![ (Binding::Tight, Component::Wildcard), (Binding::Tight, Component::Normal("second".to_string())), ], b"1", ), ( b"First.?.third: 1", vec![ (Binding::Tight, Component::Normal("First".to_string())), (Binding::Tight, Component::Wildcard), (Binding::Tight, Component::Normal("third".to_string())), ], b"1", ), // Loose bindings ( b"*second: 1", vec![(Binding::Loose, Component::Normal("second".to_string()))], b"1", ), ( b"First*third: 1", vec![ (Binding::Tight, Component::Normal("First".to_string())), (Binding::Loose, Component::Normal("third".to_string())), ], b"1", ), ( b"First**third: 1", vec![ (Binding::Tight, Component::Normal("First".to_string())), (Binding::Loose, Component::Normal("third".to_string())), ], b"1", ), // Combinations ( b"First*?.fourth: 1", vec![ (Binding::Tight, Component::Normal("First".to_string())), (Binding::Loose, Component::Wildcard), (Binding::Tight, Component::Normal("fourth".to_string())), ], b"1", ), // Values ( b"First: 1337", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"1337", ), ( b"First: -1337", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"-1337", ), ( b"First: 13.37", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"13.37", ), ( b"First: value", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"value", ), ( b"First: #abcdef", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"#abcdef", ), ( b"First: { key: 'value' }", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"{ key: 'value' }", ), ( b"First: x?y", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x?y", ), ( b"First: x*y", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x*y", ), // Whitespace ( b"First: x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x", ), ( b"First: x ", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x ", ), ( b"First: x ", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x ", ), ( b"First:x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x", ), ( b"First: \t x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x", ), ( b"First: \t x \t", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x \t", ), // Special characters ( b"First: \\ x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b" x", ), ( b"First: x\\ x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x x", ), ( b"First: \\\tx", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\tx", ), ( b"First: \\011x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\tx", ), ( b"First: x\\\\x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x\\x", ), ( b"First: x\\nx", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"x\nx", ), ( b"First: \\080", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\\080", ), ( b"First: \\00a", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\\00a", ), // Own tests // Some more escape tests, e.g. escape at end of input ( b"First: \\", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\\", ), ( b"First: \\xxx", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\\xxx", ), ( b"First: \\1xx", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\\1xx", ), ( b"First: \\10x", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\\10x", ), ( b"First: \\100", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"@", ), ( b"First: \\n", vec![(Binding::Tight, Component::Normal("First".to_string()))], b"\n", ), ]; for (data, resource, value) in tests.iter() { run_entry_test(data, resource, value); } } #[test] fn test_parse_entry_error() { let tests = [ &b": 1"[..], b"?: 1", b"First", b"First second", b"First.?: 1", b"F\xc3\xb6rst: 1", b"F~rst: 1", ]; for data in tests.iter() { match parse_entry(*data) { (Ok(v), _) => panic!("Unexpected success parsing '{:?}': {:?}", data, v), (Err(_), b"") => {} (Err(_), remaining) => panic!( "Unexpected remaining data parsing '{:?}': {:?}", data, remaining ), } } } #[test] fn test_parse_large_value() { let value = vec![b'x'; 1025]; let mut data = b"First: ".to_vec(); data.extend(&value); let resource = (Binding::Tight, Component::Normal("First".to_string())); run_entry_test(&data, &[resource], &value); } #[test] fn test_parse_large_resource() { let x = vec![b'x'; 1025]; let y = vec![b'y'; 1025]; let mut data = x.clone(); data.push(b'.'); data.extend(&y); data.extend(b": 1"); let resource = [ ( Binding::Tight, Component::Normal(String::from_utf8(x).unwrap()), ), ( Binding::Tight, Component::Normal(String::from_utf8(y).unwrap()), ), ]; run_entry_test(&data, &resource, b"1"); } #[test] fn test_parse_database() { let expected_entry = Entry { components: vec![(Binding::Tight, Component::Normal("First".to_string()))], value: b"1".to_vec(), }; let tests = [ (&b"First: 1\n\n\n"[..], vec![expected_entry.clone()]), (b"First: 1\n!Foo", vec![expected_entry.clone()]), (b"!First: 1\nbar\n\n\n", Vec::new()), (b"!bar\nFirst: 1\nbaz", vec![expected_entry.clone()]), (b"First :\\\n \\\n\\\n1\n", vec![expected_entry]), ( b"First: \\\n 1\\\n2\n", vec![Entry { components: vec![(Binding::Tight, Component::Normal("First".to_string()))], value: b"12".to_vec(), }], ), ]; let mut success = true; for (data, expected) in tests.iter() { let mut result = Vec::new(); parse_database(data, &mut result, |_, _| unreachable!()); if &result != expected { eprintln!("While testing {:?}", data); eprintln!("Expected: {:?}", expected); eprintln!("Got: {:?}", result); eprintln!(); success = false; } } if !success { panic!() } } #[test] fn test_include_parsing() { let tests = [ (&b"#include\"test\""[..], vec![&b"test"[..]]), (b"#include\"test", Vec::new()), (b"#include\"", Vec::new()), (b"#include", Vec::new()), (b"#includ", Vec::new()), (b"#in", Vec::new()), (b"# foo", Vec::new()), ( b"# include \" test \" \n#include \"foo\"", vec![b" test ", b"foo"], ), ]; let mut success = true; for (data, expected) in tests.iter() { let mut result = Vec::new(); let mut calls = Vec::new(); parse_database(data, &mut result, |file, _| calls.push(file.to_vec())); if &calls != expected { eprintln!("While testing {:?}", data); eprintln!("Expected: {:?}", expected); eprintln!("Got: {:?}", calls); eprintln!(); success = false; } } if !success { panic!() } } #[test] fn test_include_additions() { let entry = Entry { components: Vec::new(), value: b"42".to_vec(), }; let mut result = Vec::new(); parse_database(b"#include\"test\"", &mut result, |file, result| { assert_eq!(file, b"test"); result.push(entry.clone()); }); assert_eq!(result, [entry]); } fn run_entry_test(data: &[u8], resource: &[(Binding, Component)], value: &[u8]) { match parse_entry(data) { (Ok(result), remaining) => { assert_eq!(remaining, b"", "failed to parse {:?}", data); assert_eq!( result.components, resource, "incorrect components when parsing {:?}", data ); assert_eq!( result.value, value, "incorrect value when parsing {:?}", data ); } (Err(err), _) => panic!("Failed to parse '{:?}': {:?}", data, err), } } } x11rb-0.8.1/src/rust_connection/id_allocator.rs010064400017500001750000000131571402220031600176400ustar 00000000000000use crate::connection::RequestConnection; use crate::errors::{ConnectError, ReplyOrIdError}; use crate::protocol::xc_misc::{self, ConnectionExt as _, GetXIDRangeReply}; /// An allocator for X11 IDs. /// /// This struct handles the client-side generation of X11 IDs. The ID allocation is based on a /// range of IDs that the server assigned us. This range is described by a base and a mask. From /// the X11 protocol reference manual: /// /// > The resource-id-mask contains a single contiguous set of bits (at least 18). The client /// > allocates resource IDs [..] by choosing a value with only some subset of these bits set and /// > ORing it with resource-id-base. #[derive(Debug)] pub(crate) struct IDAllocator { next_id: u32, max_id: u32, increment: u32, } impl IDAllocator { /// Create a new instance of an ID allocator. /// /// The arguments should be the `resource_id_base` and `resource_id_mask` values that the X11 /// server sent in a `Setup` response. pub(crate) fn new(id_base: u32, id_mask: u32) -> Result { if id_mask == 0 { return Err(ConnectError::ZeroIDMask); } // Find the right-most set bit in id_mask, e.g. for 0b110, this results in 0b010. let increment = id_mask & (1 + !id_mask); Ok(Self { next_id: id_base, max_id: id_base | id_mask, increment, }) } /// Generate the next ID. /// /// The given connection is used to ask for more IDs if necessary. pub(crate) fn generate_id( &mut self, conn: &C, ) -> Result { self.generate_id_impl(|| { if conn .extension_information(xc_misc::X11_EXTENSION_NAME)? .is_none() { // IDs are exhausted and XC-MISC is not available Err(ReplyOrIdError::IdsExhausted) } else { Ok(conn.xc_misc_get_xid_range()?.reply()?) } }) } /// Generate the next ID. /// /// The `get_xid_range` callback is used to request more IDs from the X11 server if necessary. fn generate_id_impl(&mut self, get_xid_range: F) -> Result where F: FnOnce() -> Result, { if self.next_id > self.max_id { // Send an XC-MISC GetXIDRange request. let xidrange = get_xid_range()?; let (start, count) = (xidrange.start_id, xidrange.count); // Apparently (0, 1) is how the server signals "I am out of IDs". // The second case avoids an underflow below and should never happen. if (start, count) == (0, 1) || count == 0 { return Err(ReplyOrIdError::IdsExhausted); } self.next_id = start; self.max_id = start + (count - 1) * self.increment; } assert!(self.next_id <= self.max_id); let id = self.next_id; self.next_id += self.increment; Ok(id) } } #[cfg(test)] mod test { use crate::errors::ReplyOrIdError; use crate::protocol::xc_misc::GetXIDRangeReply; use super::IDAllocator; fn unreachable_cb() -> Result { unreachable!() } #[test] fn exhaustive() { let mut allocator = IDAllocator::new(0x2800, 0x1ff).unwrap(); for expected in 0x2800..=0x29ff { assert_eq!( expected, allocator.generate_id_impl(unreachable_cb).unwrap() ); } let cb = || -> Result<_, ReplyOrIdError> { Err(ReplyOrIdError::IdsExhausted) }; assert!(allocator.generate_id_impl(cb).is_err()); } #[test] fn increment() { let mut allocator = IDAllocator::new(0, 0b1100).unwrap(); assert_eq!(0b0000, allocator.generate_id_impl(unreachable_cb).unwrap()); assert_eq!(0b0100, allocator.generate_id_impl(unreachable_cb).unwrap()); assert_eq!(0b1000, allocator.generate_id_impl(unreachable_cb).unwrap()); assert_eq!(0b1100, allocator.generate_id_impl(unreachable_cb).unwrap()); let cb = || -> Result<_, ReplyOrIdError> { Err(ReplyOrIdError::IdsExhausted) }; assert!(allocator.generate_id_impl(cb).is_err()); } #[test] fn new_range() { let reply = generate_get_xid_range_reply(0x13370, 3); let mut allocator = IDAllocator::new(0x420, 2).unwrap(); assert_eq!(0x420, allocator.generate_id_impl(unreachable_cb).unwrap()); assert_eq!(0x422, allocator.generate_id_impl(unreachable_cb).unwrap()); // At this point the range is exhausted and a GetXIDRange request is sent let cb = || -> Result<_, ReplyOrIdError> { Ok(reply) }; assert_eq!(0x13370, allocator.generate_id_impl(cb).unwrap()); assert_eq!(0x13372, allocator.generate_id_impl(unreachable_cb).unwrap()); assert_eq!(0x13374, allocator.generate_id_impl(unreachable_cb).unwrap()); // At this point the range is exhausted and a GetXIDRange request is sent let cb = || -> Result<_, ReplyOrIdError> { Ok(reply) }; assert_eq!(0x13370, allocator.generate_id_impl(cb).unwrap()); } #[test] fn invalid_arg() { let err = IDAllocator::new(1234, 0).unwrap_err(); if let super::ConnectError::ZeroIDMask = err { } else { panic!("Wrong error: {:?}", err); } } fn generate_get_xid_range_reply(start_id: u32, count: u32) -> GetXIDRangeReply { GetXIDRangeReply { sequence: 0, length: 0, start_id, count, } } } x11rb-0.8.1/src/rust_connection/inner.rs010064400017500001750000000341131402220031600163120ustar 00000000000000//! A pure-rust implementation of a connection to an X11 server. use std::collections::VecDeque; use super::{BufWithFds, RawEventAndSeqNumber, ReplyFDKind, WriteBuffer}; use crate::connection::{DiscardMode, SequenceNumber}; use crate::utils::RawFdContainer; #[derive(Debug, Clone)] pub(crate) enum PollReply { /// It is not clear yet what the result will be; try again. TryAgain, /// There will be no reply; polling is done. NoReply, /// Here is the result of the polling; polling is done. Reply(Vec), } #[derive(Debug, Clone, Copy, Eq, PartialEq)] struct SentRequest { seqno: SequenceNumber, discard_mode: Option, has_fds: bool, } #[derive(Debug)] pub(crate) struct ConnectionInner { // The sequence number of the last request that was written last_sequence_written: SequenceNumber, // Sorted(!) list with information on requests that were written, but no answer received yet. sent_requests: VecDeque, // The sequence number of the next reply that is expected to come in next_reply_expected: SequenceNumber, // The sequence number of the last reply/error/event that was read last_sequence_read: SequenceNumber, // Events that were read, but not yet returned to the API user pending_events: VecDeque<(SequenceNumber, Vec)>, // Replies that were read, but not yet returned to the API user pending_replies: VecDeque<(SequenceNumber, BufWithFds)>, // FDs that were read, but not yet assigned to any reply pending_fds: VecDeque, // Buffer used for writing into the stream. pub(super) write_buffer: WriteBuffer, } impl ConnectionInner { /// Crate a new `ConnectionInner`. /// /// It is assumed that the connection was just established. This means that the next request /// that is sent will have sequence number one. pub(crate) fn new() -> Self { ConnectionInner { last_sequence_written: 0, next_reply_expected: 0, last_sequence_read: 0, sent_requests: VecDeque::new(), pending_events: VecDeque::new(), pending_replies: VecDeque::new(), pending_fds: VecDeque::new(), write_buffer: WriteBuffer::new(), } } /// Send a request to the X11 server. /// /// When this returns `None`, a sync with the server is necessary. Afterwards, the caller /// should try again. pub(crate) fn send_request(&mut self, kind: ReplyFDKind) -> Option { let has_response = match kind { ReplyFDKind::NoReply => false, ReplyFDKind::ReplyWithoutFDs => true, ReplyFDKind::ReplyWithFDs => true, }; if self.next_reply_expected + SequenceNumber::from(u16::max_value()) <= self.last_sequence_written && !has_response { // The caller need to call send_sync(). Otherwise, we might not be able to reconstruct // full sequence numbers for received packets. return None; } self.last_sequence_written += 1; let seqno = self.last_sequence_written; if has_response { self.next_reply_expected = self.last_sequence_written; } let sent_request = SentRequest { seqno, discard_mode: None, has_fds: kind == ReplyFDKind::ReplyWithFDs, }; self.sent_requests.push_back(sent_request); Some(seqno) } /// Ignore the reply for a request that was previously sent. pub(crate) fn discard_reply(&mut self, seqno: SequenceNumber, mode: DiscardMode) { if let Some(entry) = self.sent_requests.iter_mut().find(|r| r.seqno == seqno) { entry.discard_mode = Some(mode); } match mode { DiscardMode::DiscardReplyAndError => self.pending_replies.retain(|r| r.0 != seqno), DiscardMode::DiscardReply => { if let Some(index) = self.pending_replies.iter().position(|r| r.0 == seqno) { while self .pending_replies .get(index) .filter(|r| r.0 == seqno) .is_some() { if let Some((_, packet)) = self.pending_replies.remove(index) { if packet.0[0] == 0 { // This is an error self.pending_events.push_back((seqno, packet.0)); } } } } } } } // Extract the sequence number from a packet read from the X11 server. The packet must be a // reply, an event, or an error. All of these have a u16 sequence number in bytes 2 and 3... // except for KeymapNotify events. fn extract_sequence_number(&mut self, buffer: &[u8]) -> Option { use crate::protocol::xproto::KEYMAP_NOTIFY_EVENT; if buffer[0] == KEYMAP_NOTIFY_EVENT { return None; } // We get the u16 from the wire... let number = u16::from_ne_bytes([buffer[2], buffer[3]]); // ...and use our state to reconstruct the high bytes let high_bytes = self.last_sequence_read & !SequenceNumber::from(u16::max_value()); let mut full_number = SequenceNumber::from(number) | high_bytes; if full_number < self.last_sequence_read { full_number += SequenceNumber::from(u16::max_value()) + 1; } // Update our state self.last_sequence_read = full_number; if self.next_reply_expected < full_number { // This is most likely an event/error that allows us to update our sequence number // implicitly. Normally, only requests with a reply update this (in send_request()). self.next_reply_expected = full_number; } Some(full_number) } /// Add FDs that were received to the internal state. /// /// This must be called before the corresponding packets are enqueued. pub(crate) fn enqueue_fds(&mut self, fds: Vec) { self.pending_fds.extend(fds); } /// An X11 packet was received from the connection and is now enqueued into our state. /// /// Any FDs that were received must already be enqueued before this can be called. pub(crate) fn enqueue_packet(&mut self, packet: Vec) { let kind = packet[0]; // extract_sequence_number() updates our state and is thus important to call even when we // do not need the sequence number let seqno = self .extract_sequence_number(&packet) .unwrap_or(self.last_sequence_read); // Remove all entries for older requests while let Some(request) = self.sent_requests.front() { if request.seqno >= seqno { break; } let _ = self.sent_requests.pop_front(); } let request = self.sent_requests.front().filter(|r| r.seqno == seqno); if kind == 0 { // It is an error. Let's see where we have to send it to. if let Some(request) = request { match request.discard_mode { Some(DiscardMode::DiscardReplyAndError) => { /* This error should be ignored */ } Some(DiscardMode::DiscardReply) => { self.pending_events.push_back((seqno, packet)) } None => self .pending_replies .push_back((seqno, (packet, Vec::new()))), } } else { // Unexpected error, send to main loop self.pending_events.push_back((seqno, packet)); } } else if kind == 1 { let fds = if request.filter(|r| r.has_fds).is_some() { // This reply has FDs, the number of FDs is always in the second byte let num_fds = usize::from(packet[1]); if num_fds > self.pending_fds.len() { // FIXME Turn this into some kind of "permanent error state" (so that // everything fails with said error) instead of using a panic (this panic will // likely poison some Mutex and produce an error state that way). panic!( "FIXME: The server sent us too few FDs. The connection is now unusable \ since we will never be sure again which FD belongs to which reply." ); } self.pending_fds.drain(..num_fds).collect() } else { Vec::new() }; // It is a reply if request.filter(|r| r.discard_mode.is_some()).is_some() { // This reply should be discarded } else { self.pending_replies.push_back((seqno, (packet, fds))); } } else { // It is an event self.pending_events.push_back((seqno, packet)); } } /// Check if the server already sent an answer to the request with the given sequence number. /// /// This function is meant to be used for requests that have a reply. Such requests always /// cause a reply or an error to be sent. pub(crate) fn poll_for_reply_or_error( &mut self, sequence: SequenceNumber, ) -> Option { for (index, (seqno, _packet)) in self.pending_replies.iter().enumerate() { if *seqno == sequence { return Some(self.pending_replies.remove(index).unwrap().1); } } None } /// Prepare for calling `poll_check_for_reply_or_error()`. /// /// To check if a request with a reply caused an error, one simply has to wait for the error or /// reply to be received. However, this approach does not work for requests without errors: /// Success is indicated by the absence of an error. /// /// Thus, this function returns true if a sync is necessary to ensure that a reply with a /// higher sequence number will be received. Since the X11 server handles requests in-order, /// if the reply to a later request is received, this means that the earlier request did not /// fail. pub(crate) fn prepare_check_for_reply_or_error(&mut self, sequence: SequenceNumber) -> bool { self.next_reply_expected < sequence } /// Check if the request with the given sequence number was already handled by the server. /// /// Before calling this function, you must call `prepare_check_for_reply_or_error()` with the /// sequence number. /// /// This function can be used for requests with and without a reply. pub(crate) fn poll_check_for_reply_or_error(&mut self, sequence: SequenceNumber) -> PollReply { if let Some(result) = self.poll_for_reply_or_error(sequence) { return PollReply::Reply(result.0); } if self.last_sequence_read > sequence { // We can be sure that there will be no reply/error PollReply::NoReply } else { // Hm, we cannot be sure yet. Perhaps there will still be a reply/error PollReply::TryAgain } } /// Find the reply for the request with the given sequence number. /// /// If the request caused an error, that error will be handled as an event. This means that a /// latter call to `poll_for_event()` will return it. pub(crate) fn poll_for_reply(&mut self, sequence: SequenceNumber) -> PollReply { if let Some(reply) = self.poll_for_reply_or_error(sequence) { if reply.0[0] == 0 { self.pending_events.push_back((sequence, reply.0)); PollReply::NoReply } else { PollReply::Reply(reply.0) } } else { PollReply::TryAgain } } /// Get a pending event. pub(crate) fn poll_for_event_with_sequence(&mut self) -> Option { self.pending_events .pop_front() .map(|(seqno, event)| (event, seqno)) } } #[cfg(test)] mod test { use super::{ConnectionInner, ReplyFDKind}; #[test] fn insert_sync_no_reply() { // The connection must send a sync (GetInputFocus) request every 2^16 requests (that do not // have a reply). Thus, this test sends more than that and tests for the sync to appear. let mut connection = ConnectionInner::new(); for num in 1..0x10000 { let seqno = connection.send_request(ReplyFDKind::NoReply); assert_eq!(Some(num), seqno); } // request 0x10000 should be a sync, hence the next one is 0x10001 let seqno = connection.send_request(ReplyFDKind::NoReply); assert_eq!(None, seqno); let seqno = connection.send_request(ReplyFDKind::ReplyWithoutFDs); assert_eq!(Some(0x10000), seqno); let seqno = connection.send_request(ReplyFDKind::NoReply); assert_eq!(Some(0x10001), seqno); } #[test] fn insert_no_sync_with_reply() { // Compared to the previous test, this uses ReplyFDKind::ReplyWithoutFDs, so no sync needs to // be inserted. let mut connection = ConnectionInner::new(); for num in 1..=0x10001 { let seqno = connection.send_request(ReplyFDKind::ReplyWithoutFDs); assert_eq!(Some(num), seqno); } } #[test] fn insert_no_sync_when_already_syncing() { // This test sends enough ReplyFDKind::NoReply requests that a sync becomes necessary on // the next request. Then it sends a ReplyFDKind::ReplyWithoutFDs request so that no sync is // necessary. This is a regression test: Once upon a time, an unnecessary sync was done. let mut connection = ConnectionInner::new(); for num in 1..0x10000 { let seqno = connection.send_request(ReplyFDKind::NoReply); assert_eq!(Some(num), seqno); } let seqno = connection.send_request(ReplyFDKind::ReplyWithoutFDs); assert_eq!(Some(0x10000), seqno); } } x11rb-0.8.1/src/rust_connection/mod.rs010064400017500001750000000761441402220031600157700ustar 00000000000000//! A pure-rust implementation of a connection to an X11 server. use std::convert::TryInto; use std::io::IoSlice; use std::sync::{Condvar, Mutex, MutexGuard, TryLockError}; use crate::connection::{ compute_length_field, Connection, DiscardMode, ReplyOrError, RequestConnection, RequestKind, SequenceNumber, }; use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; pub use crate::errors::{ConnectError, ConnectionError, ParseError, ReplyError, ReplyOrIdError}; use crate::extension_manager::ExtensionManager; use crate::protocol::bigreq::{ConnectionExt as _, EnableReply}; use crate::protocol::xproto::{Setup, SetupRequest, GET_INPUT_FOCUS_REQUEST}; use crate::utils::RawFdContainer; use crate::x11_utils::{ExtensionInformation, Serialize, TryParse, TryParseFd}; mod id_allocator; mod inner; mod packet_reader; mod parse_display; mod stream; mod write_buffer; mod xauth; use inner::PollReply; use packet_reader::PacketReader; pub use stream::{DefaultStream, PollMode, Stream}; use write_buffer::WriteBuffer; type Buffer = ::Buf; /// The raw bytes of an event received by [`RustConnection`] and its sequence number. pub type RawEventAndSeqNumber = crate::connection::RawEventAndSeqNumber; /// A combination of a buffer and a list of file descriptors for use by [`RustConnection`]. pub type BufWithFds = crate::connection::BufWithFds; #[derive(Debug)] enum MaxRequestBytes { Unknown, Requested(Option), Known(usize), } type MutexGuardInner<'a> = MutexGuard<'a, inner::ConnectionInner>; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) enum ReplyFDKind { NoReply, ReplyWithoutFDs, ReplyWithFDs, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) enum BlockingMode { Blocking, NonBlocking, } /// A connection to an X11 server implemented in pure rust /// /// This type is generic over `S`, which allows to use a generic stream to communicate with the /// server. This stream can written to and read from, but it can also be polled, meaning that one /// checks if new data can be read or written. /// /// `RustConnection` always used an internal buffer for reading, so `R` does not need /// to be buffered. #[derive(Debug)] pub struct RustConnection { inner: Mutex, stream: S, // This mutex is only locked with `try_lock` (never blocks), so a simpler // lock based only on a atomic variable would be more efficient. packet_reader: Mutex, reader_condition: Condvar, id_allocator: Mutex, setup: Setup, extension_manager: Mutex, maximum_request_bytes: Mutex, } // Locking rules // ============= // // To avoid deadlocks, it is important to have a defined ordering about mutexes: // // Mutexes that may be locked when no other mutex is held: // - maximum_request_bytes // - extension_manager // - id_allocator // // Then comes `inner`. This mutex protects the information about in-flight requests and packets // that were already read from the connection but not given out to callers. This mutex also // contains the write buffer and has to be locked in order to write something to the X11 server. // In this case, the mutex has to be kept locked until writing the request has finished. This is // necessary to ensure correct sync insertion without threads interfering with each other. When // this mutex is locked for operations other than writing, the lock should be kept only for a // short time. // // The inner level is `packet_reader`. This mutex is only locked when `inner` is already held and // only with `try_lock()`. This ensures that there is only one reader. While actually reading, the // lock on `inner` is released so that other threads can make progress. If more threads want to // read while `read` is already locked, they sleep on `reader_condition`. The actual reader will // then notify this condition variable once it is done reading. // // The condition variable is necessary since one thread may read packets that another thread waits // for. Thus, after reading something from the connection, all threads that wait for something have // to check if they are the intended recipient. impl RustConnection { /// Establish a new connection. /// /// If no `dpy_name` is provided, the value from `$DISPLAY` is used. pub fn connect(dpy_name: Option<&str>) -> Result<(Self, usize), ConnectError> { // Parse display information let parsed_display = parse_display::parse_display(dpy_name).ok_or(ConnectError::DisplayParsingError)?; // Establish connection let protocol = parsed_display.protocol.as_deref(); let stream = DefaultStream::connect(&*parsed_display.host, protocol, parsed_display.display)?; let screen = parsed_display.screen.into(); let (family, address) = stream.peer_addr()?; let (auth_name, auth_data) = xauth::get_auth(family, &address, parsed_display.display) // Ignore all errors while determining auth; instead we just try without auth info. .unwrap_or(None) .unwrap_or_else(|| (Vec::new(), Vec::new())); Ok(( Self::connect_to_stream_with_auth_info(stream, screen, auth_name, auth_data)?, screen, )) } } impl RustConnection { /// Establish a new connection to the given streams. /// /// `read` is used for reading data from the X11 server and `write` is used for writing. /// `screen` is the number of the screen that should be used. This function checks that a /// screen with that number exists. pub fn connect_to_stream(stream: S, screen: usize) -> Result { Self::connect_to_stream_with_auth_info(stream, screen, Vec::new(), Vec::new()) } /// Establish a new connection to the given streams. /// /// `read` is used for reading data from the X11 server and `write` is used for writing. /// `screen` is the number of the screen that should be used. This function checks that a /// screen with that number exists. /// /// The parameters `auth_name` and `auth_data` are used for the members /// `authorization_protocol_name` and `authorization_protocol_data` of the `SetupRequest` that /// is sent to the X11 server. pub fn connect_to_stream_with_auth_info( stream: S, screen: usize, auth_name: Vec, auth_data: Vec, ) -> Result { write_setup(&stream, auth_name, auth_data)?; let setup = read_setup(&stream)?; // Check that we got a valid screen number if screen >= setup.roots.len() { return Err(ConnectError::InvalidScreen); } // Success! Set up our state Self::for_connected_stream(stream, setup) } /// Establish a new connection for an already connected stream. /// /// `read` is used for reading data from the X11 server and `write` is used for writing. /// It is assumed that `setup` was just received from the server. Thus, the first reply to a /// request that is sent will have sequence number one. pub fn for_connected_stream(stream: S, setup: Setup) -> Result { Self::for_inner(stream, inner::ConnectionInner::new(), setup) } fn for_inner( stream: S, inner: inner::ConnectionInner, setup: Setup, ) -> Result { let allocator = id_allocator::IDAllocator::new(setup.resource_id_base, setup.resource_id_mask)?; Ok(RustConnection { inner: Mutex::new(inner), stream, packet_reader: Mutex::new(PacketReader::new()), reader_condition: Condvar::new(), id_allocator: Mutex::new(allocator), setup, extension_manager: Default::default(), maximum_request_bytes: Mutex::new(MaxRequestBytes::Unknown), }) } /// Internal function for actually sending a request. /// /// This function "does the actual work" for `send_request_with_reply()` and /// `send_request_without_reply()`. fn send_request( &self, bufs: &[IoSlice<'_>], fds: Vec, kind: ReplyFDKind, ) -> Result { let mut storage = Default::default(); let bufs = compute_length_field(self, bufs, &mut storage)?; // Note: `inner` must be kept blocked until the request has been completely written // or buffered to avoid sending the data of different requests interleaved. For this // reason, `read_packet_and_enqueue` must always be called with `BlockingMode::NonBlocking` // during a write, otherise `inner` would be temporarily released. let mut inner = self.inner.lock().unwrap(); loop { match inner.send_request(kind) { Some(seqno) => { // Now actually send the buffers let _inner = self.write_all_vectored(inner, bufs, fds)?; return Ok(seqno); } None => { inner = self.send_sync(inner)?; } } } } /// Send a synchronisation packet to the X11 server. /// /// This function sends a `GetInputFocus` request to the X11 server and arranges for its reply /// to be ignored. This ensures that a reply is expected (`ConnectionInner.next_reply_expected` /// increases). fn send_sync<'a>( &'a self, mut inner: MutexGuardInner<'a>, ) -> Result, std::io::Error> { let length = 1u16.to_ne_bytes(); let request = [ GET_INPUT_FOCUS_REQUEST, 0, /* pad */ length[0], length[1], ]; let seqno = inner .send_request(ReplyFDKind::ReplyWithoutFDs) .expect("Sending a HasResponse request should not be blocked by syncs"); inner.discard_reply(seqno, DiscardMode::DiscardReplyAndError); let inner = self.write_all_vectored(inner, &[IoSlice::new(&request)], Vec::new())?; Ok(inner) } /// Write a set of buffers on a `writer`. May also read packets /// from the server. fn write_all_vectored<'a>( &'a self, mut inner: MutexGuardInner<'a>, mut bufs: &[IoSlice<'_>], mut fds: Vec, ) -> std::io::Result> { let mut partial_buf: &[u8] = &[]; while !partial_buf.is_empty() || !bufs.is_empty() || !fds.is_empty() { self.stream.poll(PollMode::ReadAndWritable)?; let write_result = if !partial_buf.is_empty() { inner .write_buffer .write(&self.stream, partial_buf, &mut fds) } else { inner .write_buffer .write_vectored(&self.stream, bufs, &mut fds) }; match write_result { Ok(0) => { return Err(std::io::Error::new( std::io::ErrorKind::WriteZero, "failed to write anything", )); } Ok(mut count) => { // Successful write if count >= partial_buf.len() { count -= partial_buf.len(); partial_buf = &[]; } else { partial_buf = &partial_buf[count..]; count = 0; } while count > 0 { if count >= bufs[0].len() { count -= bufs[0].len(); } else { partial_buf = &bufs[0][count..]; count = 0; } bufs = &bufs[1..]; // Skip empty slices while bufs.first().map(|s| s.len()) == Some(0) { bufs = &bufs[1..]; } } } Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => { // Writing would block, try to read instead because the // server might not accept new requests after its // buffered replies have been read. inner = self.read_packet_and_enqueue(inner, BlockingMode::NonBlocking)?; } Err(e) => return Err(e), } } Ok(inner) } fn flush_impl<'a>( &'a self, mut inner: MutexGuardInner<'a>, ) -> std::io::Result> { while inner.write_buffer.needs_flush() { self.stream.poll(PollMode::ReadAndWritable)?; match inner.write_buffer.flush(&self.stream) { // Flush completed Ok(()) => break, Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => { // Writing would block, try to read instead because the // server might not accept new requests after its // buffered replies have been read. inner = self.read_packet_and_enqueue(inner, BlockingMode::NonBlocking)?; } Err(e) => return Err(e), } } Ok(inner) } /// Read a packet from the connection. /// /// This function waits for an X11 packet to be received. It drops the mutex protecting the /// inner data while waiting for a packet so that other threads can make progress. For this /// reason, you need to pass in a `MutexGuard` to be dropped. This function locks the mutex /// again and returns a new `MutexGuard`. /// /// Note: If `mode` is `BlockingMode::Blocking`, the lock on `inner` will be temporarily /// released. While sending a request, `inner` must be kept locked to avoid sending the data /// of different requests interleaved. So, when `read_packet_and_enqueue` is called as part /// of a write, it must always be done with `mode` set to `BlockingMode::NonBlocking`. fn read_packet_and_enqueue<'a>( &'a self, mut inner: MutexGuardInner<'a>, mode: BlockingMode, ) -> Result, std::io::Error> { // 0.1. Try to lock the `packet_reader` mutex. match self.packet_reader.try_lock() { Err(TryLockError::WouldBlock) => { // In non-blocking mode, we just return immediately match mode { BlockingMode::NonBlocking => return Ok(inner), BlockingMode::Blocking => {} } // 1.1. Someone else is reading (other thread is at 2.2); // wait for it. `Condvar::wait` will unlock `inner`, so // the other thread can relock `inner` at 2.1.3 (and to allow // other threads to arrive 0.1). // // When `wait` finishes, other thread has enqueued a packet, // so the purpose of this function has been fulfilled. `wait` // will relock `inner` when it returns. Ok(self.reader_condition.wait(inner).unwrap()) } Err(TryLockError::Poisoned(e)) => panic!("{}", e), Ok(mut packet_reader) => { // Make sure sleeping readers are woken up when we return // (Even in case of errors) let notify_on_drop = NotifyOnDrop(&self.reader_condition); // 2.1. Poll for read if mode is blocking. if mode == BlockingMode::Blocking { // 2.1.1. Unlock `inner`, so other threads can use it while // during the poll. drop(inner); // 2.1.2. Do the actual poll self.stream.poll(PollMode::Readable)?; // 2.1.3. Relock inner inner = self.inner.lock().unwrap(); } // 2.2. Try to read as many packets as possible without blocking. let mut fds = Vec::new(); let mut packets = Vec::new(); packet_reader.try_read_packets(&self.stream, &mut packets, &mut fds)?; // 2.3. Once `inner` has been relocked, drop the // lock on `packet_reader`. While inner is locked, other // threads cannot arrive at 0.1 anyways. // // `packet_reader` must be unlocked with `inner` is locked, // otherwise it could let another thread wait on 2.1 // for a reply that has been read but not enqueued yet. drop(packet_reader); // 2.4. Actually enqueue the read packets. inner.enqueue_fds(fds); packets .into_iter() .for_each(|packet| inner.enqueue_packet(packet)); // 2.5. Notify the condvar by dropping the `notify_on_drop` object. // The object would have been dropped when the function returns, so // the explicit drop is not really needed. The purpose of having a // explicit drop is to... make it explicit. drop(notify_on_drop); // 2.6. Return the locked `inner` back to the caller. Ok(inner) } } } fn prefetch_maximum_request_bytes_impl(&self, max_bytes: &mut MutexGuard<'_, MaxRequestBytes>) { if let MaxRequestBytes::Unknown = **max_bytes { let request = self .bigreq_enable() .map(|cookie| cookie.into_sequence_number()) .ok(); **max_bytes = MaxRequestBytes::Requested(request); } } /// Returns a reference to the contained stream. pub fn stream(&self) -> &S { &self.stream } } impl RequestConnection for RustConnection { type Buf = Vec; fn send_request_with_reply( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> where Reply: TryParse, { Ok(Cookie::new( self, self.send_request(bufs, fds, ReplyFDKind::ReplyWithoutFDs)?, )) } fn send_request_with_reply_with_fds( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> where Reply: TryParseFd, { Ok(CookieWithFds::new( self, self.send_request(bufs, fds, ReplyFDKind::ReplyWithFDs)?, )) } fn send_request_without_reply( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> { Ok(VoidCookie::new( self, self.send_request(bufs, fds, ReplyFDKind::NoReply)?, )) } fn discard_reply(&self, sequence: SequenceNumber, _kind: RequestKind, mode: DiscardMode) { self.inner.lock().unwrap().discard_reply(sequence, mode); } fn prefetch_extension_information( &self, extension_name: &'static str, ) -> Result<(), ConnectionError> { self.extension_manager .lock() .unwrap() .prefetch_extension_information(self, extension_name) } fn extension_information( &self, extension_name: &'static str, ) -> Result, ConnectionError> { self.extension_manager .lock() .unwrap() .extension_information(self, extension_name) } fn wait_for_reply_or_raw_error( &self, sequence: SequenceNumber, ) -> Result>, ConnectionError> { match self.wait_for_reply_with_fds_raw(sequence)? { ReplyOrError::Reply((reply, _fds)) => Ok(ReplyOrError::Reply(reply)), ReplyOrError::Error(e) => Ok(ReplyOrError::Error(e)), } } fn wait_for_reply(&self, sequence: SequenceNumber) -> Result>, ConnectionError> { let mut inner = self.inner.lock().unwrap(); inner = self.flush_impl(inner)?; loop { match inner.poll_for_reply(sequence) { PollReply::TryAgain => {} PollReply::NoReply => return Ok(None), PollReply::Reply(buffer) => return Ok(Some(buffer)), } inner = self.read_packet_and_enqueue(inner, BlockingMode::Blocking)?; } } fn check_for_raw_error( &self, sequence: SequenceNumber, ) -> Result, ConnectionError> { let mut inner = self.inner.lock().unwrap(); if inner.prepare_check_for_reply_or_error(sequence) { inner = self.send_sync(inner)?; assert!(!inner.prepare_check_for_reply_or_error(sequence)); } // Ensure the request is sent inner = self.flush_impl(inner)?; loop { match inner.poll_check_for_reply_or_error(sequence) { PollReply::TryAgain => {} PollReply::NoReply => return Ok(None), PollReply::Reply(buffer) => return Ok(Some(buffer)), } inner = self.read_packet_and_enqueue(inner, BlockingMode::Blocking)?; } } fn wait_for_reply_with_fds_raw( &self, sequence: SequenceNumber, ) -> Result, ConnectionError> { let mut inner = self.inner.lock().unwrap(); // Ensure the request is sent inner = self.flush_impl(inner)?; loop { if let Some(reply) = inner.poll_for_reply_or_error(sequence) { if reply.0[0] == 0 { return Ok(ReplyOrError::Error(reply.0)); } else { return Ok(ReplyOrError::Reply(reply)); } } inner = self.read_packet_and_enqueue(inner, BlockingMode::Blocking)?; } } fn maximum_request_bytes(&self) -> usize { let mut max_bytes = self.maximum_request_bytes.lock().unwrap(); self.prefetch_maximum_request_bytes_impl(&mut max_bytes); use MaxRequestBytes::*; match *max_bytes { Unknown => unreachable!("We just prefetched this"), Requested(seqno) => { let length = seqno // If prefetching the request succeeded, get a cookie .and_then(|seqno| { Cookie::<_, EnableReply>::new(self, seqno) // and then get the reply to the request .reply() .map(|reply| reply.maximum_request_length) .ok() }) // If anything failed (sending the request, getting the reply), use Setup .unwrap_or_else(|| self.setup.maximum_request_length.into()) // Turn the u32 into usize, using the max value in case of overflow .try_into() .unwrap_or(usize::max_value()); let length = length * 4; *max_bytes = Known(length); length } Known(length) => length, } } fn prefetch_maximum_request_bytes(&self) { let mut max_bytes = self.maximum_request_bytes.lock().unwrap(); self.prefetch_maximum_request_bytes_impl(&mut max_bytes); } fn parse_error(&self, error: &[u8]) -> Result { let ext_mgr = self.extension_manager.lock().unwrap(); crate::x11_utils::X11Error::try_parse(error, &*ext_mgr) } fn parse_event(&self, event: &[u8]) -> Result { let ext_mgr = self.extension_manager.lock().unwrap(); crate::protocol::Event::parse(event, &*ext_mgr) } } impl Connection for RustConnection { fn wait_for_raw_event_with_sequence(&self) -> Result { let mut inner = self.inner.lock().unwrap(); loop { if let Some(event) = inner.poll_for_event_with_sequence() { return Ok(event); } inner = self.read_packet_and_enqueue(inner, BlockingMode::Blocking)?; } } fn poll_for_raw_event_with_sequence( &self, ) -> Result, ConnectionError> { let mut inner = self.inner.lock().unwrap(); if let Some(event) = inner.poll_for_event_with_sequence() { Ok(Some(event)) } else { inner = self.read_packet_and_enqueue(inner, BlockingMode::NonBlocking)?; Ok(inner.poll_for_event_with_sequence()) } } fn flush(&self) -> Result<(), ConnectionError> { let inner = self.inner.lock().unwrap(); let _inner = self.flush_impl(inner)?; Ok(()) } fn setup(&self) -> &Setup { &self.setup } fn generate_id(&self) -> Result { self.id_allocator.lock().unwrap().generate_id(self) } } #[cfg(target_endian = "little")] fn byte_order() -> u8 { 0x6c } #[cfg(target_endian = "big")] fn byte_order() -> u8 { 0x42 } /// Send a `SetupRequest` to the X11 server. fn write_setup( write: &impl Stream, auth_name: Vec, auth_data: Vec, ) -> Result<(), std::io::Error> { let request = SetupRequest { byte_order: byte_order(), protocol_major_version: 11, protocol_minor_version: 0, authorization_protocol_name: auth_name, authorization_protocol_data: auth_data, }; // Write the data let data = request.serialize(); let mut nwritten = 0; while nwritten != data.len() { write.poll(PollMode::Writable)?; // poll returned successfully, so the stream is writable. match write.write(&data[nwritten..], &mut Vec::new()) { Ok(0) => { return Err(std::io::Error::new( std::io::ErrorKind::WriteZero, "failed to write whole buffer", )) } Ok(n) => nwritten += n, // Spurious wakeup from poll, try again Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {} Err(e) => return Err(e), } } Ok(()) } /// Read a `Setup` from the X11 server. /// /// If the server sends a `SetupFailed` or `SetupAuthenticate` packet, these will be returned /// as errors. fn read_setup(stream: &impl Stream) -> Result { let mut fds = Vec::new(); let mut setup = vec![0; 8]; stream.read_exact(&mut setup, &mut fds)?; let extra_length = usize::from(u16::from_ne_bytes([setup[6], setup[7]])) * 4; // Use `Vec::reserve_exact` because this will be the final // length of the vector. setup.reserve_exact(extra_length); setup.resize(8 + extra_length, 0); stream.read_exact(&mut setup[8..], &mut fds)?; if !fds.is_empty() { return Err(std::io::Error::new( std::io::ErrorKind::Other, "unexpectedly received FDs in connection setup", ) .into()); } match setup[0] { // 0 is SetupFailed 0 => Err(ConnectError::SetupFailed( TryParse::try_parse(&setup[..])?.0, )), // Success 1 => Ok(Setup::try_parse(&setup[..])?.0), // 2 is SetupAuthenticate 2 => Err(ConnectError::SetupAuthenticate( TryParse::try_parse(&setup[..])?.0, )), // Uhm... no other cases are defined _ => Err(ParseError::InvalidValue.into()), } } /// Call `notify_all` on a condition variable when dropped. #[derive(Debug)] struct NotifyOnDrop<'a>(&'a Condvar); impl Drop for NotifyOnDrop<'_> { fn drop(&mut self) { self.0.notify_all(); } } #[cfg(test)] mod test { use std::cell::RefCell; use std::io::{Read, Result, Write}; use super::{read_setup, PollMode, Stream}; use crate::errors::ConnectError; use crate::protocol::xproto::{ImageOrder, Setup, SetupAuthenticate, SetupFailed}; use crate::utils::RawFdContainer; use crate::x11_utils::Serialize; struct SliceStream<'a, 'b> { read_slice: RefCell<&'a [u8]>, write_slice: RefCell<&'b mut [u8]>, } impl<'a, 'b> Stream for SliceStream<'a, 'b> { fn poll(&self, _mode: PollMode) -> Result<()> { Ok(()) } fn read(&self, buf: &mut [u8], _fd_storage: &mut Vec) -> Result { self.read_slice.borrow_mut().read(buf) } fn write(&self, buf: &[u8], fds: &mut Vec) -> Result { assert!(fds.is_empty()); self.write_slice.borrow_mut().write(buf) } } #[test] fn read_setup_success() { let mut setup = Setup { status: 1, protocol_major_version: 11, protocol_minor_version: 0, length: 0, release_number: 0, resource_id_base: 0, resource_id_mask: 0, motion_buffer_size: 0, maximum_request_length: 0, image_byte_order: ImageOrder::LSB_FIRST, bitmap_format_bit_order: ImageOrder::LSB_FIRST, bitmap_format_scanline_unit: 0, bitmap_format_scanline_pad: 0, min_keycode: 0, max_keycode: 0, vendor: vec![], pixmap_formats: vec![], roots: vec![], }; setup.length = ((setup.serialize().len() - 8) / 4) as _; let setup_bytes = setup.serialize(); let stream = SliceStream { read_slice: RefCell::new(&setup_bytes), write_slice: RefCell::new(&mut []), }; let read = read_setup(&stream); assert_eq!(setup, read.unwrap()); } #[test] fn read_setup_failed() { let mut setup = SetupFailed { status: 0, protocol_major_version: 11, protocol_minor_version: 0, length: 0, reason: b"whatever".to_vec(), }; setup.length = ((setup.serialize().len() - 8) / 4) as _; let setup_bytes = setup.serialize(); let stream = SliceStream { read_slice: RefCell::new(&setup_bytes), write_slice: RefCell::new(&mut []), }; match read_setup(&stream) { Err(ConnectError::SetupFailed(read)) => assert_eq!(setup, read), value => panic!("Unexpected value {:?}", value), } } #[test] fn read_setup_authenticate() { let setup = SetupAuthenticate { status: 2, reason: b"12345678".to_vec(), }; let setup_bytes = setup.serialize(); let stream = SliceStream { read_slice: RefCell::new(&setup_bytes), write_slice: RefCell::new(&mut []), }; match read_setup(&stream) { Err(ConnectError::SetupAuthenticate(read)) => assert_eq!(setup, read), value => panic!("Unexpected value {:?}", value), } } } x11rb-0.8.1/src/rust_connection/packet_reader.rs010064400017500001750000000121611402220031600177670ustar 00000000000000//! Read X11 packets from a reader use std::convert::TryInto; use std::io::{Error, ErrorKind, Result}; use super::Stream; use crate::utils::RawFdContainer; /// Minimal length of an X11 packet const MINIMAL_PACKET_LENGTH: usize = 32; /// A wrapper around a reader that reads X11 packet. #[derive(Debug)] pub(crate) struct PacketReader { read_buffer: Box<[u8]>, // A packet that was partially read. pending_packet: Vec, // Up to where the packet is already read. already_read: usize, } impl PacketReader { /// Create a new `PacketReader` that reads from the given stream. pub(crate) fn new() -> Self { Self { // Buffer size chosen by checking what libxcb does read_buffer: vec![0; 4096].into_boxed_slice(), pending_packet: vec![0; MINIMAL_PACKET_LENGTH], already_read: 0, } } /// To be called after `nread` bytes have been writen into `pending_packet`. fn handle_partial_read(&mut self, nread: usize, out_packets: &mut Vec>) { self.already_read += nread; // Do we still need to compute the length field? (length == MINIMAL_PACKET_LENGTH) if self.already_read == MINIMAL_PACKET_LENGTH { // Yes, then compute the packet length and resize the `Vec` to its final size. let extra = extra_length(self.pending_packet[..].try_into().unwrap()); self.pending_packet.reserve_exact(extra); self.pending_packet.resize(MINIMAL_PACKET_LENGTH + extra, 0); } // Has the packet been completely read? if self.already_read == self.pending_packet.len() { // Check that we really read the whole packet let initial_packet = &self.pending_packet[0..MINIMAL_PACKET_LENGTH] .try_into() .unwrap(); let extra = extra_length(&initial_packet); assert_eq!(self.pending_packet.len(), MINIMAL_PACKET_LENGTH + extra); out_packets.push(std::mem::replace( &mut self.pending_packet, vec![0; MINIMAL_PACKET_LENGTH], )); self.already_read = 0; } } /// Reads as many packets as possible from stream reader without blocking. pub(crate) fn try_read_packets( &mut self, stream: &impl Stream, out_packets: &mut Vec>, fd_storage: &mut Vec, ) -> Result<()> { loop { if (self.pending_packet.len() - self.already_read) >= self.read_buffer.len() { assert_ne!(self.already_read, self.pending_packet.len()); // Bypass the read buffer match stream.read(&mut self.pending_packet[self.already_read..], fd_storage) { Ok(0) => { return Err(Error::new( ErrorKind::UnexpectedEof, "The X11 server closed the connection", )); } Ok(nread) => self.handle_partial_read(nread, out_packets), Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break, Err(e) => return Err(e), } } else { // Fill the read buffer match stream.read(&mut self.read_buffer, fd_storage) { Ok(0) => { return Err(Error::new( ErrorKind::UnexpectedEof, "The X11 server closed the connection", )); } Ok(nread) => { let mut used_from_buffer = 0; // Take packets from `read_buffer`. while used_from_buffer != nread { let rem_read_buffer = &self.read_buffer[used_from_buffer..nread]; let rem_packet = &mut self.pending_packet[self.already_read..]; let to_copy = rem_read_buffer.len().min(rem_packet.len()); assert_ne!(to_copy, 0); rem_packet[..to_copy].copy_from_slice(&rem_read_buffer[..to_copy]); used_from_buffer += to_copy; self.handle_partial_read(to_copy, out_packets); } } Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break, Err(e) => return Err(e), } } } Ok(()) } } // Compute the length beyond `MINIMAL_PACKET_LENGTH` of an X11 packet. fn extra_length(buffer: &[u8; MINIMAL_PACKET_LENGTH]) -> usize { use crate::protocol::xproto::GE_GENERIC_EVENT; let response_type = buffer[0]; const REPLY: u8 = 1; if response_type == REPLY || response_type & 0x7f == GE_GENERIC_EVENT { let length_field = buffer[4..8].try_into().unwrap(); let length_field = u32::from_ne_bytes(length_field) as usize; 4 * length_field } else { // Fixed size packet: error or event that is not GE_GENERIC_EVENT 0 } } x11rb-0.8.1/src/rust_connection/parse_display.rs010064400017500001750000000273471402220031600200510ustar 00000000000000#[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct ParsedDisplay { pub(crate) host: String, pub(crate) protocol: Option, pub(crate) display: u16, pub(crate) screen: u16, } pub(crate) fn parse_display(dpy_name: Option<&str>) -> Option { // If no dpy name was provided, use the env var. If no env var exists, return None. match dpy_name { Some(dpy_name) => parse_display_impl(dpy_name), None => parse_display_impl(&std::env::var("DISPLAY").ok()?), } } fn parse_display_impl(dpy_name: &str) -> Option { // Everything up to the last '/' is the protocol. This part is optional. let (protocol, remaining) = if let Some(pos) = dpy_name.rfind('/') { (Some(&dpy_name[..pos]), &dpy_name[pos + 1..]) } else { (None, dpy_name) }; // Everything up to the last ':' is the host. This part is required. let pos = remaining.rfind(':')?; let (host, remaining) = (&remaining[..pos], &remaining[pos + 1..]); // The remaining part is display.screen. The display is required and the screen optional. let (display, screen) = match remaining.find('.') { Some(pos) => (&remaining[..pos], &remaining[pos + 1..]), None => (remaining, "0"), }; // Parse the display and screen number let (display, screen) = (display.parse().ok()?, screen.parse().ok()?); let host = host.to_string(); let protocol = protocol.map(|p| p.to_string()); Some(ParsedDisplay { host, protocol, display, screen, }) } #[cfg(test)] mod test { use super::{parse_display, ParsedDisplay}; fn do_parse_display(input: &str) -> Option { std::env::set_var("DISPLAY", input); let result1 = parse_display(None); std::env::remove_var("DISPLAY"); let result2 = parse_display(Some(input)); assert_eq!(result1, result2); result1 } // The tests modify environment variables. This is process-global. Thus, the tests in this // module cannot be run concurrently. We achieve this by having only a single test functions // that calls all other functions. #[test] fn test_parsing() { test_missing_input(); xcb_good_cases(); xcb_bad_cases(); own_good_cases(); } fn test_missing_input() { std::env::remove_var("DISPLAY"); assert_eq!(parse_display(None), None); } fn own_good_cases() { // The XCB test suite does not test protocol parsing for (input, output) in &[ ( "foo/bar:1", ParsedDisplay { host: "bar".to_string(), protocol: Some("foo".to_string()), display: 1, screen: 0, }, ), ( "foo/bar:1.2", ParsedDisplay { host: "bar".to_string(), protocol: Some("foo".to_string()), display: 1, screen: 2, }, ), ( "a:b/c/foo:bar:1.2", ParsedDisplay { host: "foo:bar".to_string(), protocol: Some("a:b/c".to_string()), display: 1, screen: 2, }, ), ] { assert_eq!( do_parse_display(input).as_ref(), Some(output), "Failed parsing correctly: {}", input ); } } // Based on libxcb's test suite; (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett fn xcb_good_cases() { for (input, output) in &[ // unix ( ":0", ParsedDisplay { host: "".to_string(), protocol: None, display: 0, screen: 0, }, ), ( ":1", ParsedDisplay { host: "".to_string(), protocol: None, display: 1, screen: 0, }, ), ( ":0.1", ParsedDisplay { host: "".to_string(), protocol: None, display: 0, screen: 1, }, ), // ip ( "x.org:0", ParsedDisplay { host: "x.org".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "expo:0", ParsedDisplay { host: "expo".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "bigmachine:1", ParsedDisplay { host: "bigmachine".to_string(), protocol: None, display: 1, screen: 0, }, ), ( "hydra:0.1", ParsedDisplay { host: "hydra".to_string(), protocol: None, display: 0, screen: 1, }, ), // ipv4 ( "198.112.45.11:0", ParsedDisplay { host: "198.112.45.11".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "198.112.45.11:0.1", ParsedDisplay { host: "198.112.45.11".to_string(), protocol: None, display: 0, screen: 1, }, ), // ipv6 ( ":::0", ParsedDisplay { host: "::".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "1:::0", ParsedDisplay { host: "1::".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "::1:0", ParsedDisplay { host: "::1".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "::1:0.1", ParsedDisplay { host: "::1".to_string(), protocol: None, display: 0, screen: 1, }, ), ( "::127.0.0.1:0", ParsedDisplay { host: "::127.0.0.1".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "::ffff:127.0.0.1:0", ParsedDisplay { host: "::ffff:127.0.0.1".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "2002:83fc:3052::1:0", ParsedDisplay { host: "2002:83fc:3052::1".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "2002:83fc:3052::1:0.1", ParsedDisplay { host: "2002:83fc:3052::1".to_string(), protocol: None, display: 0, screen: 1, }, ), ( "[::]:0", ParsedDisplay { host: "[::]".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "[1::]:0", ParsedDisplay { host: "[1::]".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "[::1]:0", ParsedDisplay { host: "[::1]".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "[::1]:0.1", ParsedDisplay { host: "[::1]".to_string(), protocol: None, display: 0, screen: 1, }, ), ( "[::127.0.0.1]:0", ParsedDisplay { host: "[::127.0.0.1]".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "[2002:83fc:d052::1]:0", ParsedDisplay { host: "[2002:83fc:d052::1]".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "[2002:83fc:d052::1]:0.1", ParsedDisplay { host: "[2002:83fc:d052::1]".to_string(), protocol: None, display: 0, screen: 1, }, ), // decnet ( "myws::0", ParsedDisplay { host: "myws:".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "big::0", ParsedDisplay { host: "big:".to_string(), protocol: None, display: 0, screen: 0, }, ), ( "hydra::0.1", ParsedDisplay { host: "hydra:".to_string(), protocol: None, display: 0, screen: 1, }, ), ] { assert_eq!( do_parse_display(input).as_ref(), Some(output), "Failed parsing correctly: {}", input ); } } // Based on libxcb's test suite; (C) 2001-2006 Bart Massey, Jamey Sharp, and Josh Triplett fn xcb_bad_cases() { for input in &[ "", ":", "::", ":::", ":.", ":a", ":a.", ":0.", ":.a", ":.0", ":0.a", ":0.0.", "127.0.0.1", "127.0.0.1:", "127.0.0.1::", "::127.0.0.1", "::127.0.0.1:", "::127.0.0.1::", "::ffff:127.0.0.1", "::ffff:127.0.0.1:", "::ffff:127.0.0.1::", "localhost", "localhost:", "localhost::", ] { assert_eq!( do_parse_display(input), None, "Unexpectedly parsed: {}", input ); } } } x11rb-0.8.1/src/rust_connection/stream.rs010064400017500001750000000474771402220031600165130ustar 00000000000000use std::io::{IoSlice, Result}; use std::net::{Ipv4Addr, SocketAddr, TcpStream}; #[cfg(unix)] use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; #[cfg(unix)] use std::os::unix::net::UnixStream; #[cfg(windows)] use std::os::windows::io::{AsRawSocket, IntoRawSocket, RawSocket}; use super::xauth::Family; #[cfg(unix)] use crate::utils::nix_error_to_io; use crate::utils::RawFdContainer; /// The kind of operation that one want to poll for. #[derive(Debug, Clone, Copy)] pub enum PollMode { /// Check if the stream is readable, i.e. there is pending data to be read. Readable, /// Check if the stream is writable, i.e. some data could be successfully written to it. Writable, /// Check for both readability and writability. ReadAndWritable, } impl PollMode { /// Does this poll mode include readability? pub fn readable(self) -> bool { match self { PollMode::Readable | PollMode::ReadAndWritable => true, PollMode::Writable => false, } } /// Does this poll mode include writability? pub fn writable(self) -> bool { match self { PollMode::Writable | PollMode::ReadAndWritable => true, PollMode::Readable => false, } } } /// A trait used to implement the raw communication with the X11 server. /// /// None of the functions of this trait shall return [`std::io::ErrorKind::Interrupted`]. /// If a system call fails with this error, the implementation should try again. pub trait Stream { /// Waits for level-triggered read and/or write events on the stream. /// /// This function does not return what caused it to complete the poll. /// Instead, callers should try to read or write and check for /// [`std::io::ErrorKind::WouldBlock`]. /// /// This function is allowed to spuriously return even if the stream /// is neither readable nor writable. However, it shall not do it /// continuously, which would cause a 100% CPU usage. /// /// # Multithreading /// /// If `Self` is `Send + Sync` and `poll` is used concurrently from more than /// one thread, all threads should wake when the stream becomes readable (when /// `read` is `true`) or writable (when `write` is `true`). fn poll(&self, mode: PollMode) -> Result<()>; /// Read some bytes and FDs from this reader without blocking, returning how many bytes /// were read. /// /// This function works like [`std::io::Read::read`], but also supports the reception of file /// descriptors. Any received file descriptors are appended to the given `fd_storage`. /// Whereas implementation of [`std::io::Read::read`] are allowed to block or not to block, /// this method shall never block and return `ErrorKind::WouldBlock` if needed. /// /// This function does not guarantee that all file descriptors were sent together with the data /// with which they are received. However, file descriptors may not be received later than the /// data that was sent at the same time. Instead, file descriptors may only be received /// earlier. /// /// # Multithreading /// /// If `Self` is `Send + Sync` and `read` is used concurrently from more than one thread: /// /// * Both the data and the file descriptors shall be read in order, but possibly /// interleaved across threads. /// * Neither the data nor the file descriptors shall be duplicated. /// * The returned value shall always be the actual number of bytes read into `buf`. fn read(&self, buf: &mut [u8], fd_storage: &mut Vec) -> Result; /// Read the exact number of bytes required to fill `buf` and also some amount of FDs. /// /// Unlike `read`, this method always blocks until `buf` has been filled or there is an /// error. /// /// This function works like [`std::io::Read::read`], but also supports the reception of file /// descriptors. Any received file descriptors are appended to the given `fd_storage`. /// /// This function does not guarantee that all file descriptors were sent together with the data /// with which they are received. However, file descriptors may not be received later than the /// data that was sent at the same time. Instead, file descriptors may only be received /// earlier. /// /// # Multithreading /// /// Same as `read`. In any case, if this function returns without error, `buf.len()` bytes /// should have been read into `buf`. fn read_exact(&self, mut buf: &mut [u8], fd_storage: &mut Vec) -> Result<()> { while !buf.is_empty() { self.poll(PollMode::Readable)?; match self.read(buf, fd_storage) { Ok(0) => { return Err(std::io::Error::new( std::io::ErrorKind::UnexpectedEof, "failed to fill the whole buffer", )) } Ok(n) => buf = &mut buf[n..], // Spurious wakeup from poll Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {} Err(e) => return Err(e), } } Ok(()) } /// Write a buffer and some FDs into this writer without blocking, returning how many /// bytes were written. /// /// This function works like [`std::io::Write::write`], but also supports sending file /// descriptors. The `fds` argument contains the file descriptors to send. The order of file /// descriptors is maintained. Whereas implementation of [`std::io::Write::write`] are /// allowed to block or not to block, this function must never block and return /// `ErrorKind::WouldBlock` if needed. /// /// This function does not guarantee that all file descriptors are sent together with the data. /// Any file descriptors that were sent are removed from the beginning of the given `Vec`. /// /// There is no guarantee that the given file descriptors are received together with the given /// data. File descriptors might be received earlier than their corresponding data. It is not /// allowed for file descriptors to be received later than the bytes that were sent at the same /// time. /// /// # Multithreading /// /// If `Self` is `Send + Sync` and `write` is used concurrently from more than one thread: /// /// * Both the data and the file descriptors shall be written in order, but possibly /// interleaved across threads. /// * Neither the data nor the file descriptors shall be duplicated. /// * The returned value shall always be the actual number of bytes written from `buf`. fn write(&self, buf: &[u8], fds: &mut Vec) -> Result; /// Like `write`, except that it writes from a slice of buffers. Like `write`, this /// method must never block. /// /// This method must behave as a call to `write` with the buffers concatenated would. /// /// The default implementation calls `write` with the first nonempty buffer provided. /// /// # Multithreading /// /// Same as `write`. fn write_vectored(&self, bufs: &[IoSlice<'_>], fds: &mut Vec) -> Result { for buf in bufs { if !buf.is_empty() { return self.write(&**buf, fds); } } Ok(0) } } /// A wrapper around a `TcpStream` or `UnixStream`. /// /// Use by default in `RustConnection` as stream. #[derive(Debug)] pub struct DefaultStream { inner: DefaultStreamInner, } #[derive(Debug)] enum DefaultStreamInner { TcpStream(TcpStream), #[cfg(unix)] UnixStream(UnixStream), } impl DefaultStream { /// Try to connect to the X11 server described by the given arguments. pub fn connect(host: &str, protocol: Option<&str>, display: u16) -> Result { const TCP_PORT_BASE: u16 = 6000; if (protocol.is_none() || protocol != Some("unix")) && !host.is_empty() && host != "unix" { let stream = TcpStream::connect((host, TCP_PORT_BASE + display))?; Self::from_tcp_stream(stream) } else { // On non-unix, this variable is not mutated. #[allow(unused_mut)] let mut error = None; #[cfg(unix)] { if protocol.is_none() || protocol == Some("unix") { let file_name = format!("/tmp/.X11-unix/X{}", display); // TODO: Try abstract socket (file name with prepended '\0') // Not supported on Rust right now: https://github.com/rust-lang/rust/issues/42048 match UnixStream::connect(file_name) { Ok(stream) => { return Self::from_unix_stream(stream); } Err(err) => error = Some(err), } } } if protocol.is_none() && host.is_empty() { let stream = TcpStream::connect(("localhost", TCP_PORT_BASE + display))?; Self::from_tcp_stream(stream) } else { use crate::errors::ConnectError; use std::io::{Error, ErrorKind}; Err(error.unwrap_or_else(|| { Error::new(ErrorKind::Other, ConnectError::DisplayParsingError) })) } } } /// Creates a new `Stream` from an already connected `TcpStream`. /// /// The stream will be set in non-blocking mode. pub fn from_tcp_stream(stream: TcpStream) -> Result { stream.set_nonblocking(true)?; Ok(Self { inner: DefaultStreamInner::TcpStream(stream), }) } /// Creates a new `Stream` from an already connected `UnixStream`. /// /// The stream will be set in non-blocking mode. #[cfg(unix)] pub fn from_unix_stream(stream: UnixStream) -> Result { stream.set_nonblocking(true)?; Ok(Self { inner: DefaultStreamInner::UnixStream(stream), }) } /// Get the peer's address in a format suitable for xauth. /// /// The returned values can be directly given to `super::xauth::get_auth` as `family` and /// `address`. pub(crate) fn peer_addr(&self) -> Result<(Family, Vec)> { match self.inner { DefaultStreamInner::TcpStream(ref stream) => { // Get the v4 address of the other end (if there is one) let ip = match stream.peer_addr()? { SocketAddr::V4(addr) => *addr.ip(), SocketAddr::V6(addr) => { let ip = addr.ip(); if ip.is_loopback() { // This is a local connection. // Use LOCALHOST to cause a fall-through in the code below. Ipv4Addr::LOCALHOST } else if let Some(ip) = ip.to_ipv4() { // Let the ipv4 code below handle this ip } else { // Okay, this is really a v6 address return Ok((Family::INTERNET6, ip.octets().to_vec())); } } }; // Handle the v4 address if !ip.is_loopback() { return Ok((Family::INTERNET, ip.octets().to_vec())); } else { // This is only reached for loopback addresses. The code below handles this. } } #[cfg(unix)] DefaultStreamInner::UnixStream(_) => { // Fall through to the code below. } }; // If we get to here: This is a local connection. Use the host name as address. let hostname = gethostname::gethostname() .to_str() .map(|name| name.as_bytes().to_vec()) .unwrap_or_else(Vec::new); Ok((Family::LOCAL, hostname)) } } #[cfg(unix)] impl AsRawFd for DefaultStream { fn as_raw_fd(&self) -> RawFd { match self.inner { DefaultStreamInner::TcpStream(ref stream) => stream.as_raw_fd(), DefaultStreamInner::UnixStream(ref stream) => stream.as_raw_fd(), } } } #[cfg(unix)] impl IntoRawFd for DefaultStream { fn into_raw_fd(self) -> RawFd { match self.inner { DefaultStreamInner::TcpStream(stream) => stream.into_raw_fd(), DefaultStreamInner::UnixStream(stream) => stream.into_raw_fd(), } } } #[cfg(windows)] impl AsRawSocket for DefaultStream { fn as_raw_socket(&self) -> RawSocket { match self.inner { DefaultStreamInner::TcpStream(ref stream) => stream.as_raw_socket(), } } } #[cfg(windows)] impl IntoRawSocket for DefaultStream { fn into_raw_socket(self) -> RawSocket { match self.inner { DefaultStreamInner::TcpStream(stream) => stream.into_raw_socket(), } } } #[cfg(unix)] fn do_write( stream: &DefaultStream, bufs: &[nix::sys::uio::IoVec<&[u8]>], fds: &mut Vec, ) -> Result { use nix::sys::socket::{sendmsg, ControlMessage, MsgFlags}; fn sendmsg_wrapper( fd: RawFd, iov: &[nix::sys::uio::IoVec<&[u8]>], cmsgs: &[ControlMessage<'_>], flags: MsgFlags, addr: Option<&nix::sys::socket::SockAddr>, ) -> Result { loop { match sendmsg(fd, iov, cmsgs, flags, addr) { Ok(n) => return Ok(n), // try again Err(nix::Error::Sys(nix::errno::Errno::EINTR)) => {} Err(e) => return Err(nix_error_to_io(e)), } } } let fd = stream.as_raw_fd(); let res = if !fds.is_empty() { let fds = fds.iter().map(|fd| fd.as_raw_fd()).collect::>(); let cmsgs = [ControlMessage::ScmRights(&fds[..])]; sendmsg_wrapper(fd, bufs, &cmsgs, MsgFlags::empty(), None)? } else { sendmsg_wrapper(fd, bufs, &[], MsgFlags::empty(), None)? }; // We successfully sent all FDs fds.clear(); Ok(res) } impl Stream for DefaultStream { fn poll(&self, mode: PollMode) -> Result<()> { #[cfg(unix)] { use nix::errno::Errno; use nix::poll::{poll, PollFd, PollFlags}; let mut poll_flags = PollFlags::empty(); if mode.readable() { poll_flags |= PollFlags::POLLIN; } if mode.writable() { poll_flags |= PollFlags::POLLOUT; } let fd = self.as_raw_fd(); let mut poll_fds = [PollFd::new(fd, poll_flags)]; loop { match poll(&mut poll_fds, -1) { Ok(_) => break, Err(nix::Error::Sys(Errno::EINTR)) => {} Err(e) => return Err(nix_error_to_io(e)), } } // Let the errors (POLLERR) be handled when trying to read or write. Ok(()) } #[cfg(windows)] { use winapi::um::winsock2::{POLLRDNORM, POLLWRNORM, SOCKET, WSAPOLLFD}; use winapi_wsapoll::wsa_poll; let raw_socket = self.as_raw_socket(); let mut events = 0; if mode.readable() { events |= POLLRDNORM; } if mode.writable() { events |= POLLWRNORM; } let mut poll_fds = [WSAPOLLFD { fd: raw_socket as SOCKET, events, revents: 0, }]; let _ = wsa_poll(&mut poll_fds, -1)?; // Let the errors (POLLERR) be handled when trying to read or write. Ok(()) } } fn read(&self, buf: &mut [u8], fd_storage: &mut Vec) -> Result { #[cfg(unix)] { use nix::sys::{ socket::{recvmsg, ControlMessageOwned, MsgFlags}, uio::IoVec, }; // Chosen by checking what libxcb does const MAX_FDS_RECEIVED: usize = 16; let mut cmsg = nix::cmsg_space!([RawFd; MAX_FDS_RECEIVED]); let iov = [IoVec::from_mut_slice(buf)]; let fd = self.as_raw_fd(); let msg = loop { match recvmsg(fd, &iov[..], Some(&mut cmsg), MsgFlags::empty()) { Ok(msg) => break msg, // try again Err(nix::Error::Sys(nix::errno::Errno::EINTR)) => {} Err(e) => return Err(nix_error_to_io(e)), } }; let fds_received = msg .cmsgs() .flat_map(|cmsg| match cmsg { ControlMessageOwned::ScmRights(r) => r, _ => Vec::new(), }) .map(RawFdContainer::new); fd_storage.extend(fds_received); Ok(msg.bytes) } #[cfg(not(unix))] { use std::io::Read; // No FDs are read, so nothing needs to be done with fd_storage let _ = fd_storage; loop { let read_result = match self.inner { DefaultStreamInner::TcpStream(ref stream) => { // Use `impl Read for &TcpStream` to avoid needing a mutable `TcpStream`. (&mut &*stream).read(buf) } }; match read_result { Ok(n) => return Ok(n), // try again Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {} Err(e) => return Err(e), } } } } fn write(&self, buf: &[u8], fds: &mut Vec) -> Result { #[cfg(unix)] { do_write(self, &[nix::sys::uio::IoVec::from_slice(buf)], fds) } #[cfg(not(unix))] { use std::io::{Error, ErrorKind, Write}; if !fds.is_empty() { return Err(Error::new(ErrorKind::Other, "FD passing is unsupported")); } loop { let write_result = match self.inner { DefaultStreamInner::TcpStream(ref stream) => { // Use `impl Write for &TcpStream` to avoid needing a mutable `TcpStream`. (&mut &*stream).write(buf) } }; match write_result { Ok(n) => return Ok(n), // try again Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {} Err(e) => return Err(e), } } } } fn write_vectored(&self, bufs: &[IoSlice<'_>], fds: &mut Vec) -> Result { #[cfg(unix)] { let bufs = bufs .iter() .map(|b| nix::sys::uio::IoVec::from_slice(&**b)) .collect::>(); do_write(self, &bufs, fds) } #[cfg(not(unix))] { use std::io::{Error, ErrorKind, Write}; if !fds.is_empty() { return Err(Error::new(ErrorKind::Other, "FD passing is unsupported")); } loop { let write_result = match self.inner { DefaultStreamInner::TcpStream(ref stream) => { // Use `impl Write for &TcpStream` to avoid needing a mutable `TcpStream`. (&mut &*stream).write_vectored(bufs) } }; match write_result { Ok(n) => return Ok(n), // try again Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {} Err(e) => return Err(e), } } } } } x11rb-0.8.1/src/rust_connection/write_buffer.rs010064400017500001750000000155311402220031600176650ustar 00000000000000use std::collections::VecDeque; use std::io::IoSlice; use super::Stream; use crate::utils::RawFdContainer; #[derive(Debug)] pub(super) struct WriteBuffer { data_buf: VecDeque, fd_buf: Vec, } impl WriteBuffer { pub(super) fn new() -> Self { // Buffer size chosen by checking what libxcb does Self::with_capacity(16384) } fn with_capacity(capacity: usize) -> Self { Self { data_buf: VecDeque::with_capacity(capacity), fd_buf: Vec::new(), } } fn flush_buffer(&mut self, stream: &impl Stream) -> std::io::Result<()> { while self.needs_flush() { let (data_buf_1, data_buf_2) = self.data_buf.as_slices(); let data_bufs = [IoSlice::new(data_buf_1), IoSlice::new(data_buf_2)]; match stream.write_vectored(&data_bufs, &mut self.fd_buf) { Ok(0) => { if self.data_buf.is_empty() { assert!(!self.fd_buf.is_empty()); return Err(std::io::Error::new( std::io::ErrorKind::WriteZero, "failed to write the buffered FDs", )); } else { return Err(std::io::Error::new( std::io::ErrorKind::WriteZero, "failed to write the buffered data", )); } } Ok(n) => { let _ = self.data_buf.drain(..n); } Err(e) => return Err(e), } } Ok(()) } fn write_helper( &mut self, stream: &W, fds: &mut Vec, write_buffer: F, write_inner: G, first_buffer: &[u8], to_write_length: usize, ) -> std::io::Result where F: FnOnce(&mut VecDeque), G: FnOnce(&W, &mut Vec) -> std::io::Result, { self.fd_buf.append(fds); // Is there enough buffer space left for this write? if (self.data_buf.capacity() - self.data_buf.len()) < to_write_length { // Not enough space, try to flush match self.flush_buffer(stream) { Ok(_) => {} Err(e) => { if e.kind() == std::io::ErrorKind::WouldBlock { let available_buf = self.data_buf.capacity() - self.data_buf.len(); if available_buf == 0 { // Buffer filled and cannot flush anything without // blocking, so return `WouldBlock`. return Err(e); } else { let n_to_write = first_buffer.len().min(available_buf); self.data_buf.extend(&first_buffer[..n_to_write]); // Return `Ok` because some or all data has been buffered, // so from the outside it is seen as a successful write. return Ok(n_to_write); } } else { return Err(e); } } } } if to_write_length >= self.data_buf.capacity() { // Write is larger than the buffer capacity, thus we just flushed the buffer. This // means that at this point the buffer is empty. Write directly to self.inner. No data // is copied into the buffer, since that would just mean that the large write gets // split into multiple smaller ones. assert!(self.data_buf.is_empty()); write_inner(stream, &mut self.fd_buf) } else { // At this point there is enough space available in the buffer. write_buffer(&mut self.data_buf); Ok(to_write_length) } } pub(super) fn write( &mut self, stream: &impl Stream, buf: &[u8], fds: &mut Vec, ) -> std::io::Result { self.write_helper( stream, fds, |w| w.extend(buf), |w, fd| w.write(buf, fd), buf, buf.len(), ) } pub(super) fn write_vectored( &mut self, stream: &impl Stream, bufs: &[IoSlice<'_>], fds: &mut Vec, ) -> std::io::Result { let first_nonempty = bufs .iter() .find(|b| !b.is_empty()) .map_or(&[][..], |b| &**b); let total_len = bufs.iter().map(|b| b.len()).sum(); self.write_helper( stream, fds, |w| { for buf in bufs.iter() { w.extend(&**buf); } }, |w, fd| w.write_vectored(bufs, fd), first_nonempty, total_len, ) } /// Returns `true` if there is buffered data or FDs. pub(super) fn needs_flush(&self) -> bool { !self.data_buf.is_empty() || !self.fd_buf.is_empty() } pub(super) fn flush(&mut self, stream: &impl Stream) -> std::io::Result<()> { self.flush_buffer(stream) } } #[cfg(test)] mod test { use std::io::{Error, ErrorKind, IoSlice, Result}; use super::super::{PollMode, Stream}; use super::WriteBuffer; use crate::utils::RawFdContainer; struct WouldBlockWriter; impl Stream for WouldBlockWriter { fn poll(&self, _mode: PollMode) -> Result<()> { unimplemented!(); } fn read(&self, _buf: &mut [u8], _fd_storage: &mut Vec) -> Result { unimplemented!(); } fn write(&self, _buf: &[u8], _fds: &mut Vec) -> Result { Err(Error::new(ErrorKind::WouldBlock, "would block")) } } // Once upon a time, this paniced because it did bufs[0] #[test] fn empty_write() { let stream = WouldBlockWriter; let mut write_buffer = WriteBuffer::new(); let bufs = &[]; let _ = write_buffer .write_vectored(&stream, bufs, &mut Vec::new()) .unwrap(); } // Once upon a time, BufWriteFD fell back to only writing the first buffer. This could be // mistaken as EOF. #[test] fn incorrect_eof() { let stream = WouldBlockWriter; let mut write_buffer = WriteBuffer::with_capacity(1); let bufs = &[IoSlice::new(&[]), IoSlice::new(b"fooo")]; match write_buffer.write_vectored(&stream, bufs, &mut Vec::new()) { Ok(0) => panic!("This looks like EOF!?"), Ok(_) => {} Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} Err(e) => panic!("Unexpected error: {:?}", e), } } } x11rb-0.8.1/src/rust_connection/xauth.rs010064400017500001750000000300501402220031600163240ustar 00000000000000//! Helpers for working with `~/.Xauthority`. use std::io::Error; use crate::protocol::xproto::Family as X11Family; const MIT_MAGIC_COOKIE_1: &[u8] = b"MIT-MAGIC-COOKIE-1"; /// A family describes how to interpret some bytes as an address in an `AuthEntry`. /// /// Compared to [`x11rb::protocol::xproto::Family`], this is a `u16` and not an `u8`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) struct Family(u16); #[allow(dead_code)] // Some of these constants are unused, but still serve as documentation impl Family { pub(crate) const INTERNET: Self = Self(0); pub(crate) const DEC_NET: Self = Self(1); pub(crate) const CHAOS: Self = Self(2); pub(crate) const SERVER_INTERPRETED: Self = Self(5); pub(crate) const INTERNET6: Self = Self(6); pub(crate) const WILD: Self = Self(65535); pub(crate) const LOCAL: Self = Self(256); pub(crate) const NETNAME: Self = Self(254); pub(crate) const KRB5_PRINCIPAL: Self = Self(253); pub(crate) const LOCAL_HOST: Self = Self(252); } impl From for Family { fn from(value: X11Family) -> Self { Self(value.into()) } } impl From for Family { fn from(value: u16) -> Self { Self(value) } } /// A single entry of an `.Xauthority` file. #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct AuthEntry { family: Family, address: Vec, number: Vec, name: Vec, data: Vec, } mod file { //! Code for actually reading `~/.Xauthority`. use std::env::var_os; use std::fs::File; use std::io::{BufReader, Error, ErrorKind, Read}; use std::path::PathBuf; use super::AuthEntry; /// Read a single `u16` from an `~/.Xauthority` file. /// /// The file stores these entries in big endian. fn read_u16(read: &mut R) -> Result { let mut buffer = [0; 2]; read.read_exact(&mut buffer)?; Ok(u16::from_be_bytes(buffer)) } /// Read a single "byte array" from an `~/.Xauthority` file. /// /// The file stores these as a length field followed by a number of bytes that contain the /// actual data. fn read_string(read: &mut R) -> Result, Error> { let length = read_u16(read)?; let mut result = vec![0; length.into()]; read.read_exact(&mut result[..])?; Ok(result) } /// Read a single entry from an `~/.Xauthority` file. /// /// This function tries to return `Ok(None)` when the end of the file is reached. However, the /// code also treats a single byte as 'end of file', because things were simpler to implement /// like this. fn read_entry(read: &mut R) -> Result, Error> { let family = match read_u16(read) { Ok(family) => family, Err(ref e) if e.kind() == ErrorKind::UnexpectedEof => return Ok(None), Err(e) => return Err(e), } .into(); let address = read_string(read)?; let number = read_string(read)?; let name = read_string(read)?; let data = read_string(read)?; Ok(Some(AuthEntry { family, address, number, name, data, })) } /// Get the file name for `~/.Xauthority` based on environment variables. /// /// The code in libXau contains a special case for Windows (looks like cygwin) that is not /// handled here (yet?). fn get_xauthority_file_name() -> Option { if let Some(name) = var_os("XAUTHORITY") { return Some(name.into()); } var_os("HOME").map(|prefix| { let mut result = PathBuf::new(); result.push(prefix); result.push(".Xauthority"); result }) } /// An iterator over the entries of an `.Xauthority` file #[derive(Debug)] pub(crate) struct XAuthorityEntries(BufReader); impl XAuthorityEntries { /// Open `~/.Xauthority` for reading. /// /// This function returns `Ok(None)` when the location of the `.Xauthority` file could not /// be determined. If opening the file failed (for example, because it does not exist), /// that error is returned. pub(crate) fn new() -> Result, Error> { get_xauthority_file_name() .map(File::open) .transpose()? // At this point we have Option and errors while opening the file were // returned to the caller. .map(|file| Ok(XAuthorityEntries(BufReader::new(file)))) .transpose() } } impl Iterator for XAuthorityEntries { type Item = Result; fn next(&mut self) -> Option { read_entry(&mut self.0).transpose() } } #[cfg(test)] mod test { use super::super::{AuthEntry, Family}; use super::read_entry; use std::io::Cursor; #[test] fn test_read() { // Data generated via xauth -f /tmp/file add :1 bar deadbeef let data = [ 0x01, 0x00, 0x00, 0x07, 0x5a, 0x77, 0x65, 0x69, 0x4c, 0x45, 0x44, 0x00, 0x01, 0x31, 0x00, 0x03, 0x62, 0x61, 0x72, 0x00, 0x04, 0xde, 0xad, 0xbe, 0xef, ]; let mut cursor = Cursor::new(&data[..]); let entry = read_entry(&mut cursor).unwrap(); assert_eq!( entry, Some(AuthEntry { family: Family::LOCAL, address: b"ZweiLED".to_vec(), number: b"1".to_vec(), name: b"bar".to_vec(), data: u32::to_be_bytes(0xdead_beef).to_vec(), }) ); } #[test] fn test_read_iterate() { // Data generated via: // xauth -f /tmp/file add :1 bar deadbeef // xauth -f /tmp/file add 1.2.3.4:2 baz aabbccdd let data = [ 0x01, 0x00, 0x00, 0x07, 0x5a, 0x77, 0x65, 0x69, 0x4c, 0x45, 0x44, 0x00, 0x01, 0x31, 0x00, 0x03, 0x62, 0x61, 0x72, 0x00, 0x04, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x01, 0x32, 0x00, 0x03, 0x62, 0x61, 0x7a, 0x00, 0x04, 0xaa, 0xbb, 0xcc, 0xdd, ]; let mut cursor = Cursor::new(&data[..]); for expected in &[ AuthEntry { family: Family::LOCAL, address: b"ZweiLED".to_vec(), number: b"1".to_vec(), name: b"bar".to_vec(), data: u32::to_be_bytes(0xdead_beef).to_vec(), }, AuthEntry { family: Family::INTERNET, address: vec![1, 2, 3, 4], number: b"2".to_vec(), name: b"baz".to_vec(), data: u32::to_be_bytes(0xaabb_ccdd).to_vec(), }, ] { let entry = read_entry(&mut cursor).unwrap(); assert_eq!(entry.as_ref(), Some(expected)); } let entry = read_entry(&mut cursor).unwrap(); assert_eq!(entry, None); } } } pub(crate) type AuthInfo = (Vec, Vec); /// Get the authentication information necessary for connecting to the given display. /// /// - `family` is the protocol family that is used for connecting; this describes how to interpret /// the `address`. /// - `address` is the raw bytes describing the address that is being connected to. /// - `display` is the display number. /// /// If successful, this function returns that can be written to the X11 server as authorization /// protocol name and data, respectively. pub(crate) fn get_auth( family: Family, address: &[u8], display: u16, ) -> Result, Error> { match file::XAuthorityEntries::new()? { None => Ok(None), Some(entries) => get_auth_impl(entries, family, address, display), } } pub(crate) fn get_auth_impl( entries: impl Iterator>, family: Family, address: &[u8], display: u16, ) -> Result, Error> { fn address_matches( (family1, address1): (Family, &[u8]), (family2, address2): (Family, &[u8]), ) -> bool { if family1 == Family::WILD || family2 == Family::WILD { true } else if family1 != family2 { false } else { address1 == address2 } } fn display_number_matches(entry_number: &[u8], display_number: &[u8]) -> bool { debug_assert!(!display_number.is_empty()); // This case is not handled here and would be a match entry_number.is_empty() || entry_number == display_number } let display = display.to_string(); let display = display.as_bytes(); for entry in entries { let entry = entry?; if address_matches((family, address), (entry.family, &entry.address)) && display_number_matches(&entry.number, display) && entry.name == MIT_MAGIC_COOKIE_1 { return Ok(Some((entry.name, entry.data))); } } Ok(None) } #[cfg(test)] mod test { use super::{get_auth_impl, AuthEntry, Family, MIT_MAGIC_COOKIE_1}; // Call the given function on a matching auth entry. The function can change the entry. // Afterwards, it should still be a match. fn expect_match(f: F) where F: FnOnce(&mut AuthEntry), { let mut entry = AuthEntry { family: Family::LOCAL, address: b"whatever".to_vec(), number: b"42".to_vec(), name: MIT_MAGIC_COOKIE_1.to_vec(), data: b"1234".to_vec(), }; f(&mut entry); let entries = vec![Ok(entry)]; assert_eq!( get_auth_impl(entries.into_iter(), Family::LOCAL, b"whatever", 42) .unwrap() .unwrap(), (MIT_MAGIC_COOKIE_1.to_vec(), b"1234".to_vec()) ); } // Call the given function on a matching auth entry. The function can change the entry. // Afterwards, it should no longer match. fn expect_mismatch(f: F) where F: FnOnce(&mut AuthEntry), { let mut entry = AuthEntry { family: Family::LOCAL, address: b"whatever".to_vec(), number: b"42".to_vec(), name: MIT_MAGIC_COOKIE_1.to_vec(), data: b"1234".to_vec(), }; f(&mut entry); let entries = vec![Ok(entry)]; assert_eq!( get_auth_impl(entries.into_iter(), Family::LOCAL, b"whatever", 42).unwrap(), None ); } #[test] fn direct_match() { // This checks that an auth entry where all members match, really matches expect_match(|_| {}); } #[test] fn display_wildcard() { expect_match(|entry| entry.number = vec![]); } #[test] fn address_wildcard_match1() { expect_match(|entry| entry.family = Family::WILD); } #[test] fn address_wildcard_match2() { let entry = AuthEntry { family: Family::LOCAL, address: b"whatever".to_vec(), number: b"42".to_vec(), name: MIT_MAGIC_COOKIE_1.to_vec(), data: b"1234".to_vec(), }; let entries = vec![Ok(entry)]; assert_eq!( get_auth_impl(entries.into_iter(), Family::WILD, &[], 42) .unwrap() .unwrap(), (MIT_MAGIC_COOKIE_1.to_vec(), b"1234".to_vec()) ); } #[test] fn family_mismatch() { expect_mismatch(|entry| entry.family = Family::KRB5_PRINCIPAL); } #[test] fn address_mismatch() { expect_mismatch(|entry| entry.address = b"something else".to_vec()); } #[test] fn number_mismatch() { expect_mismatch(|entry| entry.number = b"1337".to_vec()); } #[test] fn protocol_mismatch() { expect_mismatch(|entry| entry.name = b"XDM-AUTHORIZATION-1".to_vec()); } } x11rb-0.8.1/src/test.rs010064400017500001750000000017751402220031600127520ustar 00000000000000use crate::protocol::xproto::{ModMask, SendEventDest, VisualClass}; #[test] fn test_enum_debug() { assert_eq!("TRUE_COLOR", format!("{:?}", VisualClass::TRUE_COLOR)); assert_eq!("TrueColor", format!("{:#?}", VisualClass::TRUE_COLOR)); assert_eq!( "POINTER_WINDOW", format!("{:?}", SendEventDest::POINTER_WINDOW) ); assert_eq!( "PointerWindow", format!("{:#?}", SendEventDest::POINTER_WINDOW) ); assert_eq!("ITEM_FOCUS", format!("{:?}", SendEventDest::ITEM_FOCUS)); assert_eq!("ItemFocus", format!("{:#?}", SendEventDest::ITEM_FOCUS)); } #[test] fn test_bitmask_debug() { assert_eq!("SHIFT", format!("{:?}", ModMask::SHIFT)); assert_eq!("Shift", format!("{:#?}", ModMask::SHIFT)); assert_eq!( "SHIFT | LOCK", format!("{:?}", ModMask::SHIFT | ModMask::LOCK) ); assert_eq!( "Shift | Lock", format!("{:#?}", ModMask::SHIFT | ModMask::LOCK) ); assert_eq!("0", format!("{:?}", ModMask::from(0u8))); } x11rb-0.8.1/src/utils.rs010064400017500001750000000260741402220031600131320ustar 00000000000000//! Utility functions that are not specific to X11. //! //! //! # CSlice //! //! [`CSlice`] is a wrapper around some bytes in memory. It is unsafe to construct, but takes //! ownership of the bytes and allows accessing them as a `[u8]`. When dropped, the underlying //! memory is freed via [`libc::free`]. //! //! `CSlice` is only available when the `allow-unsafe-code` feature is enabled. //! //! //! # RawFdContainer //! //! [`RawFdContainer`] is a variant of [`std::os::unix::io::RawFd`] with ownership semantics. This //! means that the `RawFd` will be closed when the `RawFdContainer` is dropped. //! //! On non-`cfg(unix)`-systems, this is an empty type without methods. It still exists as a type so //! that it can appear in interfaces, but it is not actually possible to construct an instance of //! `RawFdContainer`. #[cfg(feature = "allow-unsafe-code")] mod unsafe_code { use std::mem::forget; use std::ops::{Deref, Index}; use std::ptr::NonNull; use std::slice::{from_raw_parts, SliceIndex}; use libc::free; /// Wrapper around a slice that was allocated in C code. /// /// `CSlice` is only available when the `allow-unsafe-code` feature is enabled. pub struct CSlice { ptr: NonNull<[u8]>, } // `CSlice` is `Send` and `Sync` because, once created, it is // completely immutable (it does not have interior mutability), // so it can be safely accessed from different threads simultaneously. unsafe impl Send for CSlice {} unsafe impl Sync for CSlice {} impl CSlice { /// Constructs a new `CSlice` from the given parts. `libc::free` will be called on the given /// pointer when the slice is dropped. /// /// # Safety /// /// The same rules as for `std::slice::from_raw_parts` apply. Additionally, the given pointer /// must be safe to free with `libc::free`. pub unsafe fn new(ptr: *const u8, len: usize) -> CSlice { CSlice { ptr: NonNull::from(from_raw_parts(ptr, len)), } } /// Convert `self` into a raw part. /// /// Ownership of the returned pointer is given to the caller. Specifically, `libc::free` will /// not be called on it by `CSlice`. pub fn into_ptr(self) -> *const u8 { let ptr = self.ptr.as_ptr() as *const u8; forget(self); ptr } } impl Drop for CSlice { fn drop(&mut self) { unsafe { free(self.ptr.as_ptr() as _) } } } impl Deref for CSlice { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { self.ptr.as_ref() } } } impl AsRef<[u8]> for CSlice { fn as_ref(&self) -> &[u8] { &**self } } impl Index for CSlice where I: SliceIndex<[u8]>, { type Output = I::Output; fn index(&self, index: I) -> &I::Output { (**self).index(index) } } impl std::fmt::Debug for CSlice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Debug::fmt(&**self, f) } } } #[cfg(feature = "allow-unsafe-code")] pub use unsafe_code::CSlice; #[cfg(unix)] pub(crate) fn nix_error_to_io(e: nix::Error) -> std::io::Error { match e { nix::Error::Sys(errno) => errno.into(), nix::Error::InvalidPath | nix::Error::InvalidUtf8 => { std::io::Error::new(std::io::ErrorKind::InvalidInput, e) } nix::Error::UnsupportedOperation => std::io::Error::new(std::io::ErrorKind::Other, e), } } #[cfg(unix)] mod raw_fd_container { use std::mem::forget; #[cfg(unix)] use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; use super::nix_error_to_io; /// A simple wrapper around RawFd that closes the fd on drop. /// /// On non-unix systems, this type is empty and does not provide /// any method. #[derive(Debug, Hash, PartialEq, Eq)] pub struct RawFdContainer(RawFd); impl Drop for RawFdContainer { fn drop(&mut self) { let _ = nix::unistd::close(self.0); } } impl RawFdContainer { /// Create a new `RawFdContainer` for the given `RawFd`. /// /// The `RawFdContainer` takes ownership of the `RawFd` and closes it on drop. pub fn new(fd: RawFd) -> Self { RawFdContainer(fd) } /// Tries to clone the `RawFdContainer` creating a new FD /// with `dup`. The new `RawFdContainer` will take ownership /// of the `dup`ed version, whereas the original `RawFdContainer` /// will keep the ownership of its FD. pub fn try_clone(&self) -> Result { Ok(Self::new( nix::unistd::dup(self.0).map_err(nix_error_to_io)?, )) } /// Get the `RawFd` out of this `RawFdContainer`. /// /// This function would be an implementation of `IntoRawFd` if that were possible. However, it /// causes a conflict with an `impl` from libcore... pub fn into_raw_fd(self) -> RawFd { let fd = self.0; forget(self); fd } /// Consumes the `RawFdContainer` and closes the wrapped FD with /// the `close` system call. /// /// This is similar to dropping the `RawFdContainer`, but it allows /// the caller to handle errors. pub fn close(self) -> Result<(), std::io::Error> { let fd = self.into_raw_fd(); nix::unistd::close(fd).map_err(nix_error_to_io) } } impl From for RawFdContainer { fn from(fd: T) -> Self { Self::new(fd.into_raw_fd()) } } impl AsRawFd for RawFdContainer { fn as_raw_fd(&self) -> RawFd { self.0 } } } #[cfg(not(unix))] mod raw_fd_container { /// A simple wrapper around RawFd that closes the fd on drop. /// /// On non-unix systems, this type is empty and does not provide /// any method. #[derive(Debug, Hash, PartialEq, Eq)] pub struct RawFdContainer(()); impl Drop for RawFdContainer { fn drop(&mut self) { // This function exists for symmetry with cfg(unix) } } } mod pretty_printer { use std::fmt::{Debug, Formatter, Result}; /// A helper to pretty-print an enumeration value. /// /// This function prints the given number. If it matches one of the provided variants, that /// match is used. Otherwise, the number is printed as a decimal. /// /// In alternate mode, the second string in the given array is used, else the first. pub(crate) fn pretty_print_enum( fmt: &mut Formatter<'_>, value: u32, cases: &[(u32, &str, &str)], ) -> Result { for (variant, name1, name2) in cases { if &value == variant { if fmt.alternate() { return fmt.write_str(name2); } else { return fmt.write_str(name1); } } } Debug::fmt(&value, fmt) } /// A helper to pretty-print a bitmask. /// /// This function prints the given number. All bit-matches with the given variants are printed. /// Any left-over number is printed as a decimal. /// /// In alternate mode, the second string in the given array is used, else the first. pub(crate) fn pretty_print_bitmask( fmt: &mut Formatter<'_>, value: u32, cases: &[(u32, &str, &str)], ) -> Result { // First, figure out if there are any bits not covered by any case let known_bits = cases.iter().fold(0, |acc, (value, _, _)| acc | value); let remaining = value & !known_bits; let mut already_printed = if value == 0 || remaining != 0 { Debug::fmt(&remaining, fmt)?; true } else { false }; for (variant, name1, name2) in cases { if variant & value != 0 { if already_printed { fmt.write_str(" | ")?; } already_printed = true; if fmt.alternate() { fmt.write_str(name2)?; } else { fmt.write_str(name1)?; } } } Ok(()) } #[cfg(test)] mod test { use super::{pretty_print_bitmask, pretty_print_enum}; use std::fmt::{Display, Formatter, Result}; type CallbackType = fn(&mut Formatter<'_>, u32, &[(u32, &str, &str)]) -> Result; struct CallbackFormating<'a, 'b> { callback: CallbackType, value: u32, cases: &'a [(u32, &'b str, &'b str)], } fn new_enum<'a, 'b>( value: u32, cases: &'a [(u32, &'b str, &'b str)], ) -> CallbackFormating<'a, 'b> { CallbackFormating { callback: pretty_print_enum, value, cases, } } fn new_bitmask<'a, 'b>( value: u32, cases: &'a [(u32, &'b str, &'b str)], ) -> CallbackFormating<'a, 'b> { CallbackFormating { callback: pretty_print_bitmask, value, cases, } } impl Display for CallbackFormating<'_, '_> { fn fmt(&self, f: &mut Formatter<'_>) -> Result { (self.callback)(f, self.value, self.cases) } } #[test] fn test_enum() { let cases = [(0, "zero", "ZERO"), (42, "the answer", "ANSWER")]; let printer = new_enum(0, &cases); assert_eq!(&format!("{}", printer), "zero"); assert_eq!(&format!("{:#}", printer), "ZERO"); let printer = new_enum(1, &cases); assert_eq!(&format!("{}", printer), "1"); assert_eq!(&format!("{:#}", printer), "1"); let printer = new_enum(42, &cases); assert_eq!(&format!("{}", printer), "the answer"); assert_eq!(&format!("{:#}", printer), "ANSWER"); } #[test] fn test_bitmask() { let bits = [ (1 << 5, "b5", "B5"), (1 << 1, "b1", "B1"), (1 << 0, "unused", "UNUSED"), ]; let printer = new_bitmask(8, &bits); assert_eq!(&format!("{}", printer), "8"); assert_eq!(&format!("{:#}", printer), "8"); let printer = new_bitmask(32, &bits); assert_eq!(&format!("{}", printer), "b5"); assert_eq!(&format!("{:#}", printer), "B5"); let printer = new_bitmask(34, &bits); assert_eq!(&format!("{}", printer), "b5 | b1"); assert_eq!(&format!("{:#}", printer), "B5 | B1"); let printer = new_bitmask(42, &bits); assert_eq!(&format!("{}", printer), "8 | b5 | b1"); assert_eq!(&format!("{:#}", printer), "8 | B5 | B1"); } } } pub(crate) use pretty_printer::{pretty_print_bitmask, pretty_print_enum}; pub use raw_fd_container::RawFdContainer; x11rb-0.8.1/src/wrapper.rs010064400017500001750000000102441402220031600134420ustar 00000000000000//! Some wrappers around the generated code to simplify use. use std::convert::TryInto; use std::marker::PhantomData; use super::cookie::VoidCookie; use super::errors::{ConnectionError, ReplyError}; use super::protocol::xproto::{Atom, ConnectionExt as XProtoConnectionExt, PropMode, Window}; use super::x11_utils::TryParse; /// Iterator implementation used by `GetPropertyReply`. /// /// This is the actual type returned by `GetPropertyReply::value8`, `GetPropertyReply::value16`, /// and `GetPropertyReply::value32`. This type needs to be public due to Rust's visibility rules. #[derive(Debug, Clone)] pub struct PropertyIterator<'a, T>(&'a [u8], PhantomData); impl<'a, T> PropertyIterator<'a, T> { pub(crate) fn new(value: &'a [u8]) -> Self { PropertyIterator(value, PhantomData) } } impl Iterator for PropertyIterator<'_, T> where T: TryParse, { type Item = T; fn next(&mut self) -> Option { match T::try_parse(self.0) { Ok((value, remaining)) => { self.0 = remaining; Some(value) } Err(_) => { self.0 = &[]; None } } } fn size_hint(&self) -> (usize, Option) { let size = self.0.len() / std::mem::size_of::(); (size, Some(size)) } } impl std::iter::FusedIterator for PropertyIterator<'_, T> {} /// Extension trait that simplifies API use pub trait ConnectionExt: XProtoConnectionExt { /// Change a property on a window with format 8. fn change_property8( &self, mode: PropMode, window: Window, property: A, type_: B, data: &[u8], ) -> Result, ConnectionError> where A: Into, B: Into, { self.change_property( mode, window, property, type_, 8, data.len().try_into().expect("`data` has too many elements"), data, ) } /// Change a property on a window with format 16. fn change_property16( &self, mode: PropMode, window: Window, property: A, type_: B, data: &[u16], ) -> Result, ConnectionError> where A: Into, B: Into, { let mut data_u8 = Vec::with_capacity(data.len() * 2); for item in data { data_u8.extend(&item.to_ne_bytes()); } self.change_property( mode, window, property, type_, 16, data.len().try_into().expect("`data` has too many elements"), &data_u8, ) } /// Change a property on a window with format 32. fn change_property32( &self, mode: PropMode, window: Window, property: A, type_: B, data: &[u32], ) -> Result, ConnectionError> where A: Into, B: Into, { let mut data_u8 = Vec::with_capacity(data.len() * 4); for item in data { data_u8.extend(&item.to_ne_bytes()); } self.change_property( mode, window, property, type_, 32, data.len().try_into().expect("`data` has too many elements"), &data_u8, ) } /// Synchronise with the X11 server. /// /// This function synchronises with the X11 server. This means that all requests that are still /// in the output buffer are sent to the server. Then, we wait until the X11 server processed /// all requests. fn sync(&self) -> Result<(), ReplyError> { // When a new request is generated, it is appended to the output buffer. Thus, this causes // all previous requests to be sent. // The X11 server is single-threaded and processes requests in-order. Thus, it will only // reply to our GetInputFocus after everything before was processed. self.get_input_focus()?.reply().and(Ok(())) } } impl ConnectionExt for C {} x11rb-0.8.1/src/x11_utils.rs010064400017500001750000000515361402220031600136240ustar 00000000000000//! Utility functions for X11 things. //! //! The most important definitions in this module are the [`TryParse`], [`TryParseFd`] and //! [`Serialize`] traits. These traits are used internally for parsing incoming data and producing //! outgoing data when talking with the X11 server. use std::convert::TryInto; use crate::errors::ParseError; use crate::protocol::ErrorKind; use crate::utils::RawFdContainer; /// Representation of an X11 error packet that was sent by the server. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct X11Error { /// The kind of error that occurred. pub error_kind: ErrorKind, /// The kind of error that occurred as it appears "on the wire". pub error_code: u8, /// The sequence number of the request that caused this error. pub sequence: u16, /// The value in the request that caused the error. pub bad_value: u32, /// The minor opcode of the request that caused this error. pub minor_opcode: u16, /// The major opcode of the request that caused this error. pub major_opcode: u8, } impl X11Error { /// Parse an X11 error. pub fn try_parse( data: &[u8], ext_info_provider: &dyn ExtInfoProvider, ) -> Result { let (response_type, remaining) = u8::try_parse(data)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; let (bad_value, remaining) = u32::try_parse(remaining)?; let (minor_opcode, remaining) = u16::try_parse(remaining)?; let (major_opcode, _) = u8::try_parse(remaining)?; if response_type != 0 { Err(ParseError::InvalidValue) } else { let error_kind = ErrorKind::from_wire_error_code(error_code, ext_info_provider); Ok(X11Error { error_kind, error_code, sequence, bad_value, minor_opcode, major_opcode, }) } } } impl From<&X11Error> for [u8; 32] { fn from(input: &X11Error) -> Self { let sequence_bytes = input.sequence.serialize(); let bad_value_bytes = input.bad_value.serialize(); let minor_opcode_bytes = input.minor_opcode.serialize(); [ 0, input.error_code, sequence_bytes[0], sequence_bytes[1], bad_value_bytes[0], bad_value_bytes[1], bad_value_bytes[2], bad_value_bytes[3], minor_opcode_bytes[0], minor_opcode_bytes[1], input.major_opcode, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } } impl From for [u8; 32] { fn from(input: X11Error) -> Self { Self::from(&input) } } /// Information about a X11 extension. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct ExtensionInformation { /// Major opcode used in request pub major_opcode: u8, /// Lowest event number used by the extension. pub first_event: u8, /// Lowest error number used by the extension. pub first_error: u8, } /// Trait to provide information about extensions. pub trait ExtInfoProvider { /// Returns the information of the extension that whose /// opcode is `major_opcode`. fn get_from_major_opcode(&self, major_opcode: u8) -> Option<(&str, ExtensionInformation)>; /// Returns the information of the extension that whose /// event number range includes `event_number`. fn get_from_event_code(&self, event_code: u8) -> Option<(&str, ExtensionInformation)>; /// Returns the information of the extension that whose /// error number range includes `error_number`. fn get_from_error_code(&self, error_code: u8) -> Option<(&str, ExtensionInformation)>; } /// A type implementing this trait can be parsed from some raw bytes. pub trait TryParse: Sized { /// Try to parse the given values into an instance of this type. /// /// If parsing is successful, an instance of the type and a slice for the remaining data should /// be returned. Otherwise, an error is returned. fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError>; } /// A type implementing this trait can be parsed from some raw bytes and a list of fds. pub trait TryParseFd: Sized { /// Try to parse the given values into an instance of this type. /// /// File descriptors are consumed by removing them from the beginning of the given `fds` `Vec`. /// If a file descriptor is expected, but missing, a `ParseError` should be returned. If more file /// descriptors are provided than expected, this is not an error and the remaining descriptors /// should be left in the `Vec`. /// /// If parsing is successful, an instance of the type and a slice for the remaining data should /// be returned. Otherwise, an error is returned. fn try_parse_fd<'a>( value: &'a [u8], fds: &mut Vec, ) -> Result<(Self, &'a [u8]), ParseError>; } impl TryParseFd for T { fn try_parse_fd<'a>( value: &'a [u8], _: &mut Vec, ) -> Result<(Self, &'a [u8]), ParseError> { T::try_parse(value) } } /// A representation of the header of a request. #[derive(Debug, Clone, Copy)] pub struct RequestHeader { /// The major opcode of the request. pub major_opcode: u8, /// The minor opcode of the request (which, for some requests, may not be an /// opcode at all). pub minor_opcode: u8, /// The remaining length of the request, measured in 4 bytes units. Unlike the wire format, /// this does *not* include the header itself, which is 1 unit (or 2 if BigRequests is /// enabled and the length in the first unit is zero). If the BigRequests extension is /// enabled this can be greater than u16::max_value - 1. pub remaining_length: u32, } /// Has the BigRequests extension been enabled? #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BigRequests { /// The BigRequests extension has been enabled. Enabled, /// The BigRequests extension has not been enabled. NotEnabled, } /// Parse the given input for a RequestHeader and the remaining input. pub fn parse_request_header( input: &[u8], big_requests_enabled: BigRequests, ) -> Result<(RequestHeader, &[u8]), ParseError> { let (major_opcode, remaining) = u8::try_parse(input)?; let (minor_opcode, remaining) = u8::try_parse(remaining)?; let (length, remaining) = u16::try_parse(remaining)?; let (remaining_length, finally_remaining) = if length == 0 { if big_requests_enabled == BigRequests::NotEnabled { return Err(ParseError::InvalidValue); } let (length, remaining) = u32::try_parse(remaining)?; if length < 2 { return Err(ParseError::InvalidValue); } // Adjust length for the size of this header (two 4 byte units). (length - 2, remaining) } else { // Adjust length for the size of this header (one 4 byte unit). (u32::from(length) - 1, remaining) }; Ok(( RequestHeader { major_opcode, minor_opcode, remaining_length, }, finally_remaining, )) } /// A type implementing this trait is an X11 request. pub trait Request { /// The kind of reply that this request generates. type Reply: Into + TryParseFd; /// Parse a reply to this request. /// /// The default implementation of this function uses `Self::Reply::try_parse_fd`. There should /// not be a reason why you need different behaviour. fn parse_reply<'a>( bytes: &'a [u8], fds: &mut Vec, ) -> Result<(crate::protocol::Reply, &'a [u8]), ParseError> { let (reply, remaining) = Self::Reply::try_parse_fd(bytes, fds)?; Ok((reply.into(), remaining)) } } /// A type alias for reply parsers (matches the signature of TryParseFd). pub type ReplyParsingFunction = for<'a> fn( &'a [u8], &mut Vec, ) -> Result<(crate::protocol::Reply, &'a [u8]), ParseError>; /// A type implementing this trait can be serialized into X11 raw bytes. pub trait Serialize { /// The value returned by `serialize`. /// /// This should be `Vec` in most cases. However, arrays like `[u8; 4]` should also be /// allowed and thus this is an associated type. /// /// If generic associated types were available, implementing `AsRef<[u8]>` would be required. type Bytes; /// Serialize this value into X11 raw bytes. fn serialize(&self) -> Self::Bytes; /// Serialize this value into X11 raw bytes, appending the result into `bytes`. /// /// When calling this method, the given vector must satisfy `assert_eq!(bytes.len() % 4, 0);`. /// In words: Its length must be a multiple of four. fn serialize_into(&self, bytes: &mut Vec); } // Now implement TryParse and Serialize for some primitive data types that we need. macro_rules! implement_try_parse { ($t:ty) => { impl TryParse for $t { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let len = std::mem::size_of::<$t>(); let bytes = value .get(..len) .ok_or(ParseError::InsufficientData)? .try_into() // TryInto<[u8; len]> .unwrap(); Ok((<$t>::from_ne_bytes(bytes), &value[len..])) } } }; } macro_rules! implement_serialize { ($t:ty: $size:expr) => { impl Serialize for $t { type Bytes = [u8; $size]; fn serialize(&self) -> Self::Bytes { self.to_ne_bytes() } fn serialize_into(&self, bytes: &mut Vec) { bytes.extend_from_slice(&self.to_ne_bytes()); } } }; } macro_rules! forward_float { ($from:ty: $to:ty) => { impl TryParse for $from { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (data, remaining) = <$to>::try_parse(value)?; Ok((<$from>::from_bits(data), remaining)) } } impl Serialize for $from { type Bytes = <$to as Serialize>::Bytes; fn serialize(&self) -> Self::Bytes { self.to_bits().serialize() } fn serialize_into(&self, bytes: &mut Vec) { self.to_bits().serialize_into(bytes); } } }; } implement_try_parse!(u8); implement_try_parse!(i8); implement_try_parse!(u16); implement_try_parse!(i16); implement_try_parse!(u32); implement_try_parse!(i32); implement_try_parse!(u64); implement_try_parse!(i64); implement_serialize!(u8: 1); implement_serialize!(i8: 1); implement_serialize!(u16: 2); implement_serialize!(i16: 2); implement_serialize!(u32: 4); implement_serialize!(i32: 4); implement_serialize!(u64: 8); implement_serialize!(i64: 8); forward_float!(f32: u32); forward_float!(f64: u64); impl TryParse for bool { fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let (data, remaining) = u8::try_parse(value)?; Ok((data != 0, remaining)) } } impl Serialize for bool { type Bytes = [u8; 1]; fn serialize(&self) -> Self::Bytes { [u8::from(*self)] } fn serialize_into(&self, bytes: &mut Vec) { bytes.push(u8::from(*self)); } } // Tuple handling macro_rules! tuple_try_parse { ($($name:ident)*) => { impl<$($name,)*> TryParse for ($($name,)*) where $($name: TryParse,)* { #[allow(non_snake_case)] fn try_parse(remaining: &[u8]) -> Result<(($($name,)*), &[u8]), ParseError> { $(let ($name, remaining) = $name::try_parse(remaining)?;)* Ok((($($name,)*), remaining)) } } } } macro_rules! tuple_serialize { ($($name:ident:$idx:tt)*) => { impl<$($name,)*> Serialize for ($($name,)*) where $($name: Serialize,)* { type Bytes = Vec; fn serialize(&self) -> Self::Bytes { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { $(self.$idx.serialize_into(bytes);)* } } } } macro_rules! tuple_impls { ($($name:ident:$idx:tt)*) => { tuple_try_parse!($($name)*); tuple_serialize!($($name:$idx)*); } } // We can optimise serialisation of empty tuples or one-element-tuples with different Bytes type impl Serialize for () { type Bytes = [u8; 0]; fn serialize(&self) -> Self::Bytes { [] } fn serialize_into(&self, _bytes: &mut Vec) {} } impl Serialize for (T,) { type Bytes = T::Bytes; fn serialize(&self) -> Self::Bytes { self.0.serialize() } fn serialize_into(&self, bytes: &mut Vec) { self.0.serialize_into(bytes) } } tuple_try_parse!(); tuple_try_parse!(A); tuple_impls!(A:0 B:1); tuple_impls!(A:0 B:1 C:2); tuple_impls!(A:0 B:1 C:2 D:3); tuple_impls!(A:0 B:1 C:2 D:3 E:4); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12 N:13); tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12 N:13 O:14); /// Parse a list of objects from the given data. /// /// This function parses a list of objects where the length of the list was specified externally. /// The wire format for `list_length` instances of `T` will be read from the given data. pub fn parse_list(data: &[u8], list_length: usize) -> Result<(Vec, &[u8]), ParseError> where T: TryParse, { let mut remaining = data; let mut result = Vec::with_capacity(list_length); for _ in 0..list_length { let (entry, new_remaining) = T::try_parse(remaining)?; result.push(entry); remaining = new_remaining; } Ok((result, remaining)) } /// Parse a list of `u8` from the given data. pub fn parse_u8_list(data: &[u8], list_length: usize) -> Result<(&[u8], &[u8]), ParseError> { if data.len() < list_length { Err(ParseError::InsufficientData) } else { Ok(data.split_at(list_length)) } } impl Serialize for [T] { type Bytes = Vec; fn serialize(&self) -> Self::Bytes { let mut result = Vec::new(); self.serialize_into(&mut result); result } fn serialize_into(&self, bytes: &mut Vec) { for item in self { item.serialize_into(bytes); } } } // This macro is used by the generated code to implement `std::ops::BitOr` and // `std::ops::BitOrAssign`. macro_rules! bitmask_binop { ($t:ty, $u:ty) => { impl std::ops::BitOr for $t { type Output = $t; fn bitor(self, other: Self) -> Self::Output { Self::from(<$u>::from(self) | <$u>::from(other)) } } impl std::ops::BitOr<$u> for $t { type Output = $t; fn bitor(self, other: $u) -> Self::Output { self | Self::from(other) } } impl std::ops::BitOr<$t> for $u { type Output = $t; fn bitor(self, other: $t) -> Self::Output { <$t>::from(self) | other } } impl std::ops::BitOrAssign<$t> for $u { fn bitor_assign(&mut self, other: $t) { *self |= Self::from(other) } } impl std::ops::BitOrAssign<$u> for $t { fn bitor_assign(&mut self, other: $u) { *self = *self | Self::from(other) } } }; } /// Wrapper around TryInto that produces a ParseError. /// /// This trait shortens `x.try_into().or(Err(ParseError::ConversionFailed))` to `x.try_to_usize()`. pub(crate) trait TryIntoUSize: TryInto { /// Attempt the conversion fn try_to_usize(self) -> Result { self.try_into().or(Err(ParseError::ConversionFailed)) } } impl TryIntoUSize for u8 {} impl TryIntoUSize for u16 {} impl TryIntoUSize for u32 {} impl TryIntoUSize for u64 {} impl TryIntoUSize for i8 {} impl TryIntoUSize for i16 {} impl TryIntoUSize for i32 {} impl TryIntoUSize for i64 {} /// A helper macro for managing atoms /// /// If we need to use multiple atoms, one would normally write code such as /// ``` /// # use x11rb::protocol::xproto::{Atom, ConnectionExt, InternAtomReply}; /// # use x11rb::errors::{ConnectionError, ReplyError}; /// # use x11rb::cookie::Cookie; /// #[allow(non_snake_case)] /// pub struct AtomCollection { /// pub _NET_WM_NAME: Atom, /// pub _NET_WM_ICON: Atom, /// pub ATOM_WITH_SPACES: Atom, /// pub WHATEVER: Atom, /// } /// /// #[allow(non_snake_case)] /// struct AtomCollectionCookie<'c, C: ConnectionExt> { /// _NET_WM_NAME: Cookie<'c, C, InternAtomReply>, /// _NET_WM_ICON: Cookie<'c, C, InternAtomReply>, /// ATOM_WITH_SPACES: Cookie<'c, C, InternAtomReply>, /// WHATEVER: Cookie<'c, C, InternAtomReply>, /// } /// /// impl AtomCollection { /// pub fn new( /// conn: &C, /// ) -> Result, ConnectionError> { /// Ok(AtomCollectionCookie { /// _NET_WM_NAME: conn.intern_atom(false, b"_NET_WM_NAME")?, /// _NET_WM_ICON: conn.intern_atom(false, b"_NET_WM_ICON")?, /// ATOM_WITH_SPACES: conn.intern_atom(false, b"ATOM WITH SPACES")?, /// WHATEVER: conn.intern_atom(false, b"WHATEVER")?, /// }) /// } /// } /// /// impl<'c, C> AtomCollectionCookie<'c, C> /// where /// C: ConnectionExt, /// { /// pub fn reply(self) -> Result { /// Ok(AtomCollection { /// _NET_WM_NAME: self._NET_WM_NAME.reply()?.atom, /// _NET_WM_ICON: self._NET_WM_ICON.reply()?.atom, /// ATOM_WITH_SPACES: self.ATOM_WITH_SPACES.reply()?.atom, /// WHATEVER: self.WHATEVER.reply()?.atom, /// }) /// } /// } /// ``` /// This macro automatically produces this code with /// ``` /// # use x11rb::atom_manager; /// atom_manager! { /// pub AtomCollection: AtomCollectionCookie { /// _NET_WM_NAME, /// _NET_WM_ICON, /// ATOM_WITH_SPACES: b"ATOM WITH SPACES", /// WHATEVER, /// } /// } /// ``` #[macro_export] macro_rules! atom_manager { { $vis:vis $struct_name:ident: $cookie_name:ident { $($field_name:ident$(: $atom_value:expr)?,)* } } => { // Cookie version #[allow(non_snake_case)] #[derive(Debug)] $vis struct $cookie_name<'a, C: $crate::protocol::xproto::ConnectionExt> { phantom: std::marker::PhantomData<&'a C>, $( $field_name: $crate::cookie::Cookie<'a, C, $crate::protocol::xproto::InternAtomReply>, )* } // Replies #[allow(non_snake_case)] #[derive(Debug, Clone, Copy)] $vis struct $struct_name { $( $vis $field_name: $crate::protocol::xproto::Atom, )* } impl $struct_name { $vis fn new( _conn: &C, ) -> ::std::result::Result<$cookie_name<'_, C>, $crate::errors::ConnectionError> { Ok($cookie_name { phantom: std::marker::PhantomData, $( $field_name: _conn.intern_atom( false, $crate::__atom_manager_atom_value!($field_name$(: $atom_value)?), )?, )* }) } } impl<'a, C: $crate::protocol::xproto::ConnectionExt> $cookie_name<'a, C> { $vis fn reply(self) -> ::std::result::Result<$struct_name, $crate::errors::ReplyError> { Ok($struct_name { $( $field_name: self.$field_name.reply()?.atom, )* }) } } } } #[doc(hidden)] #[macro_export] macro_rules! __atom_manager_atom_value { ($field_name:ident) => { stringify!($field_name).as_bytes() }; ($field_name:ident: $atom_value:expr) => { $atom_value }; } x11rb-0.8.1/src/xcb_ffi/mod.rs010064400017500001750000000634451402220031600141540ustar 00000000000000//! A FFI-based connection to an X11 server, using libxcb. //! //! This module is only available when the `allow-unsafe-code` feature is enabled. use std::convert::TryInto; use std::ffi::CStr; use std::io::{Error as IOError, ErrorKind, IoSlice}; use std::os::raw::c_int; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd}; use std::ptr::{null, null_mut}; use std::sync::{ atomic::{AtomicU64, Ordering}, Mutex, }; use libc::c_void; use crate::connection::{ compute_length_field, Connection, DiscardMode, ReplyOrError, RequestConnection, RequestKind, SequenceNumber, }; use crate::cookie::{Cookie, CookieWithFds, VoidCookie}; pub use crate::errors::{ConnectError, ConnectionError, ParseError, ReplyError, ReplyOrIdError}; use crate::extension_manager::ExtensionManager; use crate::protocol::xproto::Setup; use crate::utils::{CSlice, RawFdContainer}; use crate::x11_utils::{ExtensionInformation, TryParse, TryParseFd}; mod pending_errors; mod raw_ffi; #[cfg(all(not(test), feature = "dl-libxcb"))] pub use raw_ffi::libxcb_library::load_libxcb; type Buffer = ::Buf; /// The raw bytes of an event received by [`XCBConnection`] and its sequence number. pub type RawEventAndSeqNumber = crate::connection::RawEventAndSeqNumber; /// A combination of a buffer and a list of file descriptors for use by [`XCBConnection`]. pub type BufWithFds = crate::connection::BufWithFds; /// A connection to an X11 server. /// /// This type wraps `*mut xcb_connection_t` that is provided by libxcb. It provides a rust /// interface to this C library. #[derive(Debug)] pub struct XCBConnection { conn: raw_ffi::XCBConnectionWrapper, setup: Setup, ext_mgr: Mutex, errors: pending_errors::PendingErrors, maximum_sequence_received: AtomicU64, } impl XCBConnection { unsafe fn connection_error_from_connection( c: *mut raw_ffi::xcb_connection_t, ) -> ConnectionError { Self::connection_error_from_c_error(raw_ffi::xcb_connection_has_error(c)) } fn connection_error_from_c_error(error: c_int) -> ConnectionError { use crate::xcb_ffi::raw_ffi::connection_errors::*; assert_ne!(error, 0); match error { ERROR => IOError::new(ErrorKind::Other, ConnectionError::UnknownError).into(), EXT_NOTSUPPORTED => ConnectionError::UnsupportedExtension, MEM_INSUFFICIENT => ConnectionError::InsufficientMemory, REQ_LEN_EXCEED => ConnectionError::MaximumRequestLengthExceeded, FDPASSING_FAILED => ConnectionError::FDPassingFailed, _ => ConnectionError::UnknownError, // Not possible here: PARSE_ERR, INVALID_SCREEN } } fn connect_error_from_c_error(error: c_int) -> ConnectError { use crate::xcb_ffi::raw_ffi::connection_errors::*; assert_ne!(error, 0); match error { ERROR => IOError::new(ErrorKind::Other, ConnectionError::UnknownError).into(), MEM_INSUFFICIENT => ConnectError::InsufficientMemory, PARSE_ERR => ConnectError::DisplayParsingError, INVALID_SCREEN => ConnectError::InvalidScreen, _ => ConnectError::UnknownError, // Not possible here: EXT_NOTSUPPORTED, REQ_LEN_EXCEED, FDPASSING_FAILED } } /// Establish a new connection to an X11 server. /// /// If a `dpy_name` is provided, it describes the display that should be connected to, for /// example `127.0.0.1:1`. If no value is provided, the `$DISPLAY` environment variable is /// used. pub fn connect(dpy_name: Option<&CStr>) -> Result<(XCBConnection, usize), ConnectError> { use libc::c_int; unsafe { let mut screen: c_int = 0; let dpy_ptr = dpy_name.map_or(null(), |s| s.as_ptr()); let connection = raw_ffi::XCBConnectionWrapper::new( raw_ffi::xcb_connect(dpy_ptr, &mut screen), true, ); let error = raw_ffi::xcb_connection_has_error(connection.as_ptr()); if error != 0 { Err(Self::connect_error_from_c_error(error)) } else { let setup = raw_ffi::xcb_get_setup(connection.as_ptr()); let conn = XCBConnection { // `xcb_connect` will never return null. conn: connection, setup: Self::parse_setup(setup)?, ext_mgr: Default::default(), errors: Default::default(), maximum_sequence_received: AtomicU64::new(0), }; Ok((conn, screen as usize)) } } } /// Create a connection wrapper for a raw libxcb `xcb_connection_t`. /// /// `xcb_disconnect` is called on drop only if `should_drop` is `true`. /// /// # Safety /// /// If `should_drop` is `false`, the connection must live longer than the returned /// `XCBConnection`. If `should_drop` is `true`, the returned `XCBConnection` will /// take the ownership of the connection. pub unsafe fn from_raw_xcb_connection( ptr: *mut c_void, should_drop: bool, ) -> Result { let ptr = ptr as *mut raw_ffi::xcb_connection_t; let setup = raw_ffi::xcb_get_setup(ptr); Ok(XCBConnection { conn: raw_ffi::XCBConnectionWrapper::new(ptr, should_drop), setup: Self::parse_setup(setup)?, ext_mgr: Default::default(), errors: Default::default(), maximum_sequence_received: AtomicU64::new(0), }) } unsafe fn parse_setup(setup: *const raw_ffi::xcb_setup_t) -> Result { use std::slice::from_raw_parts; // We know that the setup information has at least eight bytes. // Use a slice instead of Buffer::CSlice since we must not free() the xcb_setup_t that libxcb owns. let wrapper = from_raw_parts(setup as *const u8, 8); // The length field is in the last two bytes let length = u16::from_ne_bytes([wrapper[6], wrapper[7]]); // The length is in four-byte-units after the known header let length = usize::from(length) * 4 + 8; let slice = from_raw_parts(wrapper.as_ptr(), length); let result = Setup::try_parse(&*slice)?.0; Ok(result) } // Slince the warning about ioslice.len().try_into().unwrap(). The target type is sometimes // usize (where this warning is correct) and sometimes c_int (where we need the conversion). We // need this here due to https://github.com/rust-lang/rust/issues/60681. #[allow(clippy::useless_conversion)] fn send_request( &self, bufs: &[IoSlice<'_>], fds: Vec, has_reply: bool, reply_has_fds: bool, ) -> Result { let mut storage = Default::default(); let new_bufs = compute_length_field(self, bufs, &mut storage)?; // Now wrap the buffers with IoSlice let mut new_bufs_ffi = Vec::with_capacity(2 + new_bufs.len()); // XCB wants to access bufs[-1] and bufs[-2], so we need to add two empty items in front. new_bufs_ffi.push(raw_ffi::iovec { iov_base: null_mut(), iov_len: 0, }); new_bufs_ffi.push(raw_ffi::iovec { iov_base: null_mut(), iov_len: 0, }); new_bufs_ffi.extend(new_bufs.iter().map(|ioslice| raw_ffi::iovec { iov_base: ioslice.as_ptr() as _, iov_len: ioslice.len().try_into().unwrap(), })); // Set up the information that libxcb needs let protocol_request = raw_ffi::xcb_protocol_request_t { count: new_bufs.len(), ext: null_mut(), // Not needed since we always use raw opcode: 0, isvoid: if has_reply { 0 } else { 1 }, }; let mut flags = raw_ffi::send_request_flags::RAW; assert!(has_reply || !reply_has_fds); flags |= raw_ffi::send_request_flags::CHECKED; if reply_has_fds { flags |= raw_ffi::send_request_flags::REPLY_FDS; } let seqno = if fds.is_empty() { unsafe { raw_ffi::xcb_send_request64( self.conn.as_ptr(), flags, &mut new_bufs_ffi[2], &protocol_request, ) } } else { #[cfg(unix)] { // Convert the FDs into an array of ints. libxcb will close the FDs. let mut fds: Vec<_> = fds.into_iter().map(RawFdContainer::into_raw_fd).collect(); let num_fds = fds.len().try_into().unwrap(); let fds_ptr = fds.as_mut_ptr(); unsafe { raw_ffi::xcb_send_request_with_fds64( self.conn.as_ptr(), flags, &mut new_bufs_ffi[2], &protocol_request, num_fds, fds_ptr, ) } } #[cfg(not(unix))] { unreachable!("it is not possible to create a `RawFdContainer` on non-unix"); } }; if seqno == 0 { unsafe { Err(Self::connection_error_from_connection(self.conn.as_ptr())) } } else { Ok(seqno) } } /// Check if the underlying XCB connection is in an error state. pub fn has_error(&self) -> Option { unsafe { let error = raw_ffi::xcb_connection_has_error(self.conn.as_ptr()); if error == 0 { None } else { Some(Self::connection_error_from_c_error(error)) } } } /// Get access to the raw libxcb `xcb_connection_t`. /// /// The returned pointer is valid for as long as the original object was not dropped. No /// ownerhsip is transferred. pub fn get_raw_xcb_connection(&self) -> *mut c_void { self.conn.as_ptr() as _ } /// Check if a reply to the given request already received. /// /// Return Err(()) when the reply was not yet received. Returns Ok(None) when there can be no /// reply. Returns Ok(buffer) with the reply if there is one (this buffer can be an error or a /// reply). fn poll_for_reply(&self, sequence: SequenceNumber) -> Result, ()> { unsafe { let mut reply = null_mut(); let mut error = null_mut(); let found = raw_ffi::xcb_poll_for_reply64(self.conn.as_ptr(), sequence, &mut reply, &mut error); if found == 0 { return Err(()); } assert_eq!(found, 1); match (reply.is_null(), error.is_null()) { (true, true) => Ok(None), (true, false) => Ok(Some(self.wrap_error(error as _, sequence))), (false, true) => Ok(Some(self.wrap_reply(reply as _, sequence))), (false, false) => unreachable!(), } } } unsafe fn wrap_reply(&self, reply: *const u8, sequence: SequenceNumber) -> CSlice { // Update our "max sequence number received" field atomic_u64_max(&self.maximum_sequence_received, sequence); let header = CSlice::new(reply, 32); let length_field = u32::from_ne_bytes(header[4..8].try_into().unwrap()); let length_field: usize = length_field .try_into() .expect("usize should have at least 32 bits"); let length = 32 + length_field * 4; CSlice::new(header.into_ptr(), length) } unsafe fn wrap_error(&self, error: *const u8, sequence: SequenceNumber) -> CSlice { // Update our "max sequence number received" field atomic_u64_max(&self.maximum_sequence_received, sequence); CSlice::new(error, 32) } unsafe fn wrap_event(&self, event: *mut u8) -> Result { let header = CSlice::new(event, 36); let mut length = 32; // XCB inserts a uint32_t with the sequence number after the first 32 bytes. let seqno = u32::from_ne_bytes([header[32], header[33], header[34], header[35]]); let seqno = self.reconstruct_full_sequence(seqno); // The first byte contains the event type, check for XGE events if (*event & 0x7f) == super::protocol::xproto::GE_GENERIC_EVENT { // Read the length field of the event to get its length let length_field = u32::from_ne_bytes([header[4], header[5], header[6], header[7]]); let length_field: usize = length_field .try_into() .or(Err(ParseError::ConversionFailed))?; length += length_field * 4; // Discard the `full_sequence` field inserted by xcb at // the 32-byte boundary. std::ptr::copy(event.add(36), event.add(32), length_field * 4); } Ok((CSlice::new(header.into_ptr(), length), seqno)) } /// Reconstruct a full sequence number based on a partial value. /// /// The assumption for the algorithm here is that the given sequence number was received /// recently. Thus, the maximum sequence number that was received so far is used to fill in the /// missing bytes for the result. fn reconstruct_full_sequence(&self, seqno: u32) -> SequenceNumber { reconstruct_full_sequence_impl( self.maximum_sequence_received.load(Ordering::Relaxed), seqno, ) } } impl RequestConnection for XCBConnection { type Buf = CSlice; fn send_request_with_reply( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> where R: TryParse, { Ok(Cookie::new( self, self.send_request(bufs, fds, true, false)?, )) } fn send_request_with_reply_with_fds( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> where R: TryParseFd, { Ok(CookieWithFds::new( self, self.send_request(bufs, fds, true, true)?, )) } fn send_request_without_reply( &self, bufs: &[IoSlice<'_>], fds: Vec, ) -> Result, ConnectionError> { Ok(VoidCookie::new( self, self.send_request(bufs, fds, false, false)?, )) } fn discard_reply(&self, sequence: SequenceNumber, _kind: RequestKind, mode: DiscardMode) { match mode { DiscardMode::DiscardReplyAndError => unsafe { // libxcb can throw away everything for us raw_ffi::xcb_discard_reply64(self.conn.as_ptr(), sequence); }, // We have to check for errors ourselves DiscardMode::DiscardReply => self.errors.discard_reply(sequence), } } fn prefetch_extension_information( &self, extension_name: &'static str, ) -> Result<(), ConnectionError> { self.ext_mgr .lock() .unwrap() .prefetch_extension_information(self, extension_name) } fn extension_information( &self, extension_name: &'static str, ) -> Result, ConnectionError> { self.ext_mgr .lock() .unwrap() .extension_information(self, extension_name) } fn wait_for_reply_or_raw_error( &self, sequence: SequenceNumber, ) -> Result, ConnectionError> { unsafe { let mut error = null_mut(); let reply = raw_ffi::xcb_wait_for_reply64(self.conn.as_ptr(), sequence, &mut error); match (reply.is_null(), error.is_null()) { (true, true) => Err(Self::connection_error_from_connection(self.conn.as_ptr())), (false, true) => Ok(ReplyOrError::Reply(self.wrap_reply(reply as _, sequence))), (true, false) => Ok(ReplyOrError::Error(self.wrap_error(error as _, sequence))), // At least one of these pointers must be NULL. (false, false) => unreachable!(), } } } fn wait_for_reply(&self, sequence: SequenceNumber) -> Result, ConnectionError> { match self.wait_for_reply_or_raw_error(sequence)? { ReplyOrError::Reply(reply) => Ok(Some(reply)), ReplyOrError::Error(error) => { self.errors.append_error((sequence, error)); Ok(None) } } } #[cfg(unix)] fn wait_for_reply_with_fds_raw( &self, sequence: SequenceNumber, ) -> Result, ConnectionError> { let buffer = match self.wait_for_reply_or_raw_error(sequence)? { ReplyOrError::Reply(reply) => reply, ReplyOrError::Error(error) => return Ok(ReplyOrError::Error(error)), }; // Get a pointer to the array of integers where libxcb saved the FD numbers. // libxcb saves the list of FDs after the data of the reply. Since the reply's // length is encoded in "number of 4 bytes block", the following pointer is aligned // correctly (if malloc() returned an aligned chunk, which it does). #[allow(clippy::cast_ptr_alignment)] let fd_ptr = (unsafe { buffer.as_ptr().add(buffer.len()) }) as *const RawFd; // The number of FDs is in the second byte (= buffer[1]) in all replies. let fd_slice = unsafe { std::slice::from_raw_parts(fd_ptr, usize::from(buffer[1])) }; let fd_vec = fd_slice.iter().map(|&fd| RawFdContainer::new(fd)).collect(); Ok(ReplyOrError::Reply((buffer, fd_vec))) } #[cfg(not(unix))] fn wait_for_reply_with_fds_raw( &self, _sequence: SequenceNumber, ) -> Result, ConnectionError> { unimplemented!("FD passing is currently only implemented on Unix-like systems") } fn check_for_raw_error( &self, sequence: SequenceNumber, ) -> Result, ConnectionError> { let cookie = raw_ffi::xcb_void_cookie_t { sequence: sequence as _, }; let error = unsafe { raw_ffi::xcb_request_check(self.conn.as_ptr(), cookie) }; if error.is_null() { Ok(None) } else { unsafe { Ok(Some(self.wrap_error(error as _, sequence))) } } } fn maximum_request_bytes(&self) -> usize { 4 * unsafe { raw_ffi::xcb_get_maximum_request_length(self.conn.as_ptr()) as usize } } fn prefetch_maximum_request_bytes(&self) { unsafe { raw_ffi::xcb_prefetch_maximum_request_length(self.conn.as_ptr()) }; } fn parse_error(&self, error: &[u8]) -> Result { let ext_mgr = self.ext_mgr.lock().unwrap(); crate::x11_utils::X11Error::try_parse(error, &*ext_mgr) } fn parse_event(&self, event: &[u8]) -> Result { let ext_mgr = self.ext_mgr.lock().unwrap(); crate::protocol::Event::parse(event, &*ext_mgr) } } impl Connection for XCBConnection { fn wait_for_raw_event_with_sequence(&self) -> Result { if let Some(error) = self.errors.get(self) { return Ok((error.1, error.0)); } unsafe { let event = raw_ffi::xcb_wait_for_event(self.conn.as_ptr()); if event.is_null() { return Err(Self::connection_error_from_connection(self.conn.as_ptr())); } Ok(self.wrap_event(event as _)?) } } fn poll_for_raw_event_with_sequence( &self, ) -> Result, ConnectionError> { if let Some(error) = self.errors.get(self) { return Ok(Some((error.1, error.0))); } unsafe { let event = raw_ffi::xcb_poll_for_event(self.conn.as_ptr()); if event.is_null() { let err = raw_ffi::xcb_connection_has_error(self.conn.as_ptr()); if err == 0 { return Ok(None); } else { return Err(Self::connection_error_from_c_error(err)); } } Ok(Some(self.wrap_event(event as _)?)) } } fn flush(&self) -> Result<(), ConnectionError> { // xcb_flush() returns 0 if the connection is in (or just entered) an error state, else 1. let res = unsafe { raw_ffi::xcb_flush(self.conn.as_ptr()) }; if res != 0 { Ok(()) } else { unsafe { Err(Self::connection_error_from_connection(self.conn.as_ptr())) } } } fn generate_id(&self) -> Result { unsafe { let id = raw_ffi::xcb_generate_id(self.conn.as_ptr()); // XCB does not document the behaviour of `xcb_generate_id` when // there is an error. Looking at its source code it seems that it // returns `-1` (presumably `u32::max_value()`). if id == u32::max_value() { Err(Self::connection_error_from_connection(self.conn.as_ptr()).into()) } else { Ok(id) } } } fn setup(&self) -> &Setup { &self.setup } } #[cfg(unix)] impl AsRawFd for XCBConnection { fn as_raw_fd(&self) -> RawFd { unsafe { raw_ffi::xcb_get_file_descriptor(self.conn.as_ptr()) } } } /// Atomically sets `value` to the maximum of `value` and `new`. fn atomic_u64_max(value: &AtomicU64, new: u64) { // If only AtomicU64::fetch_max were stable... let mut old = value.load(Ordering::Relaxed); loop { if old >= new { return; } match value.compare_exchange_weak(old, new, Ordering::Relaxed, Ordering::Relaxed) { Ok(_) => return, Err(val) => old = val, } } } /// Reconstruct a partial sequence number based on a recently received 'full' sequence number. /// /// The new sequence number may be before or after the `recent` sequence number. fn reconstruct_full_sequence_impl(recent: SequenceNumber, value: u32) -> SequenceNumber { // Expand 'value' to a full sequence number. The high bits are copied from 'recent'. let u32_max = SequenceNumber::from(u32::max_value()); let expanded_value = SequenceNumber::from(value) | (recent & !u32_max); // The "step size" is the difference between two sequence numbers that cannot be told apart // from their truncated value. let step: SequenceNumber = SequenceNumber::from(1u8) << 32; // There are three possible values for the returned sequence number: // - The extended value // - The extended value plus one step // - The extended value minus one step // Pick the value out of the possible values that is closest to `recent`. let result = [ expanded_value, expanded_value + step, expanded_value.wrapping_sub(step), ] .iter() .copied() .min_by_key(|&value| { if value > recent { value - recent } else { recent - value } }) .unwrap(); // Just because: Check that the result matches the passed-in value in the low bits assert_eq!( result & SequenceNumber::from(u32::max_value()), SequenceNumber::from(value), ); result } #[cfg(test)] mod test { use super::{atomic_u64_max, XCBConnection}; use std::ffi::CString; #[test] fn xcb_connect_smoke_test() { // in cfg(test), raw_ffi does not call XCB, but instead uses a mock. This test calls into // that mock and tests a bit of XCBConnection. let str = CString::new("display name").unwrap(); let (_conn, screen) = XCBConnection::connect(Some(&str)).expect("Failed to 'connect'"); assert_eq!(screen, 0); } #[test] fn u64_max() { use std::sync::atomic::{AtomicU64, Ordering}; let value = AtomicU64::new(0); atomic_u64_max(&value, 3); assert_eq!(value.load(Ordering::Relaxed), 3); atomic_u64_max(&value, 7); assert_eq!(value.load(Ordering::Relaxed), 7); atomic_u64_max(&value, 5); assert_eq!(value.load(Ordering::Relaxed), 7); atomic_u64_max(&value, 7); assert_eq!(value.load(Ordering::Relaxed), 7); atomic_u64_max(&value, 9); assert_eq!(value.load(Ordering::Relaxed), 9); } #[test] fn reconstruct_full_sequence() { use super::reconstruct_full_sequence_impl; let max32 = u32::max_value(); let max32_: u64 = max32.into(); let max32_p1 = max32_ + 1; let large_offset = max32_p1 * u64::from(u16::max_value()); for &(recent, value, expected) in &[ (0, 0, 0), (0, 10, 10), // This one is a special case: Technically, -1 is closer and should be reconstructed, // but -1 does not fit into an unsigned integer. (0, max32, max32_), (max32_, 0, max32_p1), (max32_, 10, max32_p1 + 10), (max32_, max32, max32_), (max32_p1, 0, max32_p1), (max32_p1, 10, max32_p1 + 10), (max32_p1, max32, max32_), (large_offset | 0xdead_cafe, 0, large_offset + max32_p1), (large_offset | 0xdead_cafe, max32, large_offset + max32_), (0xabcd_1234_5678, 0xf000_0000, 0xabcc_f000_0000), (0xabcd_8765_4321, 0xf000_0000, 0xabcd_f000_0000), ] { let actual = reconstruct_full_sequence_impl(recent, value); assert_eq!( actual, expected, "reconstruct({:x}, {:x}) == {:x}, but was {:x}", recent, value, expected, actual, ); } } } x11rb-0.8.1/src/xcb_ffi/pending_errors.rs010064400017500001750000000043501402220031600164030ustar 00000000000000//! Management of pending errors for the XCB connection. //! //! We add our own error tracking ontop of what XCB already provides. For this reason, this module //! contains a struct for tracking requests that were send and also tracking errors that were //! received, but not yet given to the user of this library. use std::cmp::Reverse; use std::collections::{BinaryHeap, VecDeque}; use std::sync::Mutex; use super::{Buffer, XCBConnection}; use crate::connection::SequenceNumber; #[derive(Debug, Default)] struct PendingErrorsInner { in_flight: BinaryHeap>, pending: VecDeque<(SequenceNumber, Buffer)>, } /// A management struct for pending X11 errors #[derive(Debug, Default)] pub(crate) struct PendingErrors { inner: Mutex, } impl PendingErrors { pub(crate) fn append_error(&self, error: (SequenceNumber, Buffer)) { self.inner.lock().unwrap().pending.push_back(error) } pub(crate) fn discard_reply(&self, sequence: SequenceNumber) { self.inner.lock().unwrap().in_flight.push(Reverse(sequence)); } pub(crate) fn get(&self, conn: &XCBConnection) -> Option<(SequenceNumber, Buffer)> { let mut inner = self.inner.lock().unwrap(); // Check if we already have an element at hand let err = inner.pending.pop_front(); if err.is_some() { return err; } // Check if any of the still in-flight responses got a reply/error while let Some(&Reverse(seqno)) = inner.in_flight.peek() { let result = match conn.poll_for_reply(seqno) { Err(()) => { // This request was not answered/errored yet, so later request will not // have answers as well. return None; } Ok(reply) => reply, }; let seqno2 = inner.in_flight.pop(); assert_eq!(Some(Reverse(seqno)), seqno2); if let Some(result) = result { // Is this an error? if result[0] == 0 { return Some((seqno, result)); } else { // It's a reply, just ignore it } } } None } } x11rb-0.8.1/src/xcb_ffi/raw_ffi/ffi.rs010064400017500001750000000143651402220031600155530ustar 00000000000000//! The code in this module allows to call libxcb's C functions. //! //! At its heart, this module only contains an `extern "C"` block that defines the C functions so //! that they can be called from Rust. //! //! However, this module also contains the implementation of the `dl-libxcb` features. When this //! future is enabled, we do not link against libxcb, but instead use `libloading` to load //! `libxcb.so` at runtime. Most of the code is actually responsible for this later feature. use super::{ c_char, c_int, c_uint, c_void, iovec, xcb_connection_t, xcb_generic_error_t, xcb_generic_event_t, xcb_protocol_request_t, xcb_setup_t, xcb_void_cookie_t, }; #[cfg(feature = "dl-libxcb")] pub(crate) mod libxcb_library { use super::LibxcbFuncs; use crate::errors::LibxcbLoadError; pub(super) struct LibxcbLibrary { // Needed to keep the library loaded _library: libloading::Library, pub(super) funcs: LibxcbFuncs, } impl LibxcbLibrary { /// # Safety /// /// The functions pointers in `funcs` do not have lifetime, /// but they must not outlive the returned result. #[cold] #[inline(never)] unsafe fn load() -> Result { // TODO: Names for non-unix platforms #[cfg(unix)] const LIB_NAME: &str = "libxcb.so.1"; #[cfg(not(unix))] compile_error!("dl-libxcb feature is not supported on non-unix"); let library = libloading::Library::new(LIB_NAME) .map_err(|e| LibxcbLoadError::OpenLibError(LIB_NAME.into(), e.to_string()))?; let funcs = LibxcbFuncs::new(&library).map_err(|(symbol, e)| { LibxcbLoadError::GetSymbolError(symbol.into(), e.to_string()) })?; Ok(Self { _library: library, funcs, }) } } use once_cell::sync::Lazy; static LIBXCB_LIBRARY: Lazy> = Lazy::new(|| unsafe { LibxcbLibrary::load() }); pub(super) fn get_libxcb() -> &'static LibxcbLibrary { #[cold] #[inline(never)] fn failed(e: &LibxcbLoadError) -> ! { panic!("failed to load libxcb: {}", e); } match *LIBXCB_LIBRARY { Ok(ref library) => library, Err(ref e) => failed(e), } } /// Tries to dynamically load libxcb, returning an error on failure. /// /// It is not required to call this function, as libxcb will be lazily loaded. /// However, if a lazy load fails, a panic will be raised, missing the chance /// to (nicely) handle the error. /// /// It is safe to call this function more than once from the same or different /// threads. Only the first call will try to load libxcb, subsequent calls will /// always return the same result. pub fn load_libxcb() -> Result<(), LibxcbLoadError> { match Lazy::force(&LIBXCB_LIBRARY) { Ok(_) => Ok(()), Err(e) => Err(e.clone()), } } } macro_rules! make_ffi_fn_defs { { $( $(#[$fn_attr:meta])* fn $fn_name:ident($($fn_arg_name:ident: $fn_arg_type:ty),*) $(-> $fn_ret_ty:ty)?; )* } => { #[cfg(not(feature = "dl-libxcb"))] #[link(name = "xcb")] extern "C" { $( $(#[$fn_attr])* pub(crate) fn $fn_name($($fn_arg_name: $fn_arg_type),*) $(-> $fn_ret_ty)?; )* } #[cfg(feature = "dl-libxcb")] struct LibxcbFuncs { $( $(#[$fn_attr])* $fn_name: fn($($fn_arg_name: $fn_arg_type),*) $(-> $fn_ret_ty)?, )* } #[cfg(feature = "dl-libxcb")] impl LibxcbFuncs { unsafe fn new(library: &libloading::Library) -> Result { Ok(Self { $($fn_name: { let symbol_name = concat!(stringify!($fn_name), "\0").as_bytes(); *library.get(symbol_name).map_err(|e| (stringify!($fn_name).as_bytes(), e))? },)* }) } } $( #[cfg(feature = "dl-libxcb")] $(#[$fn_attr])* pub(crate) unsafe fn $fn_name($($fn_arg_name: $fn_arg_type),*) $(-> $fn_ret_ty)? { (libxcb_library::get_libxcb().funcs.$fn_name)($($fn_arg_name),*) } )* }; } make_ffi_fn_defs! { // From xcb.h fn xcb_flush(c: *mut xcb_connection_t) -> c_int; fn xcb_get_maximum_request_length(c: *mut xcb_connection_t) -> u32; fn xcb_prefetch_maximum_request_length(c: *mut xcb_connection_t); fn xcb_wait_for_event(c: *mut xcb_connection_t) -> *mut xcb_generic_event_t; fn xcb_poll_for_event(c: *mut xcb_connection_t) -> *mut xcb_generic_event_t; fn xcb_request_check( c: *mut xcb_connection_t, void_cookie: xcb_void_cookie_t ) -> *mut xcb_generic_error_t; fn xcb_discard_reply64(c: *mut xcb_connection_t, sequence: u64); fn xcb_get_setup(c: *mut xcb_connection_t) -> *const xcb_setup_t; #[cfg(unix)] fn xcb_get_file_descriptor(c: *mut xcb_connection_t) -> c_int; fn xcb_connection_has_error(c: *mut xcb_connection_t) -> c_int; fn xcb_disconnect(c: *mut xcb_connection_t); fn xcb_connect( displayname: *const c_char, screenp: *mut c_int ) -> *mut xcb_connection_t; fn xcb_generate_id(c: *mut xcb_connection_t) -> u32; // From xcbext.h fn xcb_send_request64( c: *mut xcb_connection_t, flags: c_int, vector: *mut iovec, request: *const xcb_protocol_request_t ) -> u64; #[cfg(unix)] fn xcb_send_request_with_fds64( c: *mut xcb_connection_t, flags: c_int, vector: *mut iovec, request: *const xcb_protocol_request_t, num_fds: c_uint, fds: *mut c_int ) -> u64; fn xcb_wait_for_reply64( c: *mut xcb_connection_t, request: u64, e: *mut *mut xcb_generic_error_t ) -> *mut c_void; fn xcb_poll_for_reply64( c: *mut xcb_connection_t, request: u64, reply: *mut *mut c_void, error: *mut *mut xcb_generic_error_t ) -> c_int; } x11rb-0.8.1/src/xcb_ffi/raw_ffi/mod.rs010064400017500001750000000067631402220031600155710ustar 00000000000000//! The low-level foreign function interface to interact with libxcb. //! //! This module contains some `#[repr(C)]` type definitions that match libxcb's definitions. The //! actual functions are defined in the `ffi` submodule. There is also a `test` submodule that //! contains a mock of the interface that is used for unit tests. use std::ptr::NonNull; #[cfg(not(all(test, unix)))] use libc::c_void; #[cfg(unix)] pub(crate) use libc::iovec; use libc::{c_char, c_int, c_uint}; // As defined in xcb_windefs.h #[cfg(not(unix))] #[derive(Copy, Clone, Debug)] #[repr(C)] pub(crate) struct iovec { pub(crate) iov_base: *mut c_void, pub(crate) iov_len: c_int, } #[allow(non_camel_case_types)] #[repr(C)] pub(crate) struct xcb_connection_t { _unused: [u8; 0], } #[derive(Debug)] pub(crate) struct XCBConnectionWrapper { ptr: NonNull, should_drop: bool, } // libxcb is fully thread-safe (well, except for xcb_disconnect()), so the following is // actually fine and safe: unsafe impl Send for XCBConnectionWrapper {} unsafe impl Sync for XCBConnectionWrapper {} impl Drop for XCBConnectionWrapper { fn drop(&mut self) { if self.should_drop { unsafe { xcb_disconnect(self.ptr.as_ptr()); } } } } impl XCBConnectionWrapper { pub(crate) unsafe fn new(ptr: *mut xcb_connection_t, should_drop: bool) -> Self { Self { ptr: NonNull::new_unchecked(ptr), should_drop, } } pub(crate) fn as_ptr(&self) -> *mut xcb_connection_t { self.ptr.as_ptr() } } #[allow(non_camel_case_types)] #[repr(C)] pub(crate) struct xcb_generic_event_t { pub(crate) response_type: u8, pub(crate) pad0: u8, pub(crate) sequence: u16, pub(crate) pad: [u32; 7], pub(crate) full_sequence: u32, } #[allow(non_camel_case_types)] #[repr(C)] pub(crate) struct xcb_generic_error_t { pub(crate) response_type: u8, pub(crate) error_code: u8, pub(crate) sequence: u16, pub(crate) resource_id: u32, pub(crate) minor_code: u16, pub(crate) major_code: u8, pub(crate) pad0: u8, pub(crate) pad: [u32; 5], pub(crate) full_sequence: u32, } #[derive(Clone, Copy)] #[allow(non_camel_case_types)] #[repr(C)] pub(crate) struct xcb_void_cookie_t { pub(crate) sequence: c_uint, } #[allow(non_camel_case_types)] #[repr(C)] pub(crate) struct xcb_extension_t { pub(crate) name: *const c_char, pub(crate) global_id: c_int, } #[allow(non_camel_case_types)] #[repr(C)] pub(crate) struct xcb_protocol_request_t { pub(crate) count: usize, pub(crate) ext: *mut xcb_extension_t, pub(crate) opcode: u8, pub(crate) isvoid: u8, } #[allow(non_camel_case_types)] #[repr(C)] pub(crate) struct xcb_setup_t { _unused: [u8; 0], } pub(crate) mod connection_errors { use std::os::raw::c_int; pub(crate) const ERROR: c_int = 1; pub(crate) const EXT_NOTSUPPORTED: c_int = 2; pub(crate) const MEM_INSUFFICIENT: c_int = 3; pub(crate) const REQ_LEN_EXCEED: c_int = 4; pub(crate) const PARSE_ERR: c_int = 5; pub(crate) const INVALID_SCREEN: c_int = 6; pub(crate) const FDPASSING_FAILED: c_int = 7; } pub(crate) mod send_request_flags { use libc::c_int; pub(crate) const CHECKED: c_int = 1; pub(crate) const RAW: c_int = 2; //pub(crate) const DISCARD_REPLY: c_int = 4; pub(crate) const REPLY_FDS: c_int = 8; } #[cfg(not(test))] mod ffi; #[cfg(not(test))] pub(crate) use ffi::*; #[cfg(test)] mod test; #[cfg(test)] pub(crate) use test::*; x11rb-0.8.1/src/xcb_ffi/raw_ffi/test.rs010064400017500001750000000103751402220031600157630ustar 00000000000000//! A mock of libxcb that is used by the unit tests in [`x11rb::xcb_ffi`]. use std::ffi::CStr; use libc::{c_char, c_int, c_uint, c_void}; use super::{ iovec, xcb_connection_t, xcb_generic_error_t, xcb_generic_event_t, xcb_protocol_request_t, xcb_setup_t, xcb_void_cookie_t, }; use crate::protocol::xproto::{ImageOrder, Setup}; use crate::x11_utils::Serialize; #[repr(C)] struct ConnectionMock { error: c_int, setup: Vec, } // From xcb.h pub(crate) unsafe fn xcb_flush(_c: *mut xcb_connection_t) -> c_int { unimplemented!(); } pub(crate) unsafe fn xcb_get_maximum_request_length(_c: *mut xcb_connection_t) -> u32 { unimplemented!(); } pub(crate) unsafe fn xcb_prefetch_maximum_request_length(_c: *mut xcb_connection_t) { unimplemented!(); } pub(crate) unsafe fn xcb_wait_for_event(_c: *mut xcb_connection_t) -> *mut xcb_generic_event_t { unimplemented!(); } pub(crate) unsafe fn xcb_poll_for_event(_c: *mut xcb_connection_t) -> *mut xcb_generic_event_t { unimplemented!(); } pub(crate) unsafe fn xcb_request_check( _c: *mut xcb_connection_t, _void_cookie: xcb_void_cookie_t, ) -> *mut xcb_generic_error_t { unimplemented!(); } pub(crate) unsafe fn xcb_discard_reply64(_c: *mut xcb_connection_t, _sequence: u64) { unimplemented!(); } pub(crate) unsafe fn xcb_get_setup(c: *mut xcb_connection_t) -> *const xcb_setup_t { // The pointer is suitable aligned since our xcb_connect() mock above created it #[allow(clippy::cast_ptr_alignment)] ((*(c as *const ConnectionMock)).setup.as_ptr() as _) } #[cfg(unix)] pub(crate) unsafe fn xcb_get_file_descriptor(_c: *mut xcb_connection_t) -> c_int { unimplemented!(); } pub(crate) unsafe fn xcb_connection_has_error(c: *mut xcb_connection_t) -> c_int { // The pointer is suitable aligned since our xcb_connect() mock above created it #[allow(clippy::cast_ptr_alignment)] (*(c as *const ConnectionMock)).error } pub(crate) unsafe fn xcb_disconnect(c: *mut xcb_connection_t) { // The pointer is suitable aligned since our xcb_connect() mock above created it #[allow(clippy::cast_ptr_alignment)] let _ = Box::from_raw(c as *mut ConnectionMock); } pub(crate) unsafe fn xcb_connect( displayname: *const c_char, screenp: *mut c_int, ) -> *mut xcb_connection_t { // Test that the provided displayname is correct if CStr::from_ptr(displayname).to_str().unwrap() != "display name" { panic!("Did not get the expected displayname"); } std::ptr::write(screenp, 0); let length_field = 10; let setup = Setup { status: 0, protocol_major_version: 0, protocol_minor_version: 0, length: length_field, release_number: 0, resource_id_base: 0, resource_id_mask: 0, motion_buffer_size: 0, maximum_request_length: 0, image_byte_order: ImageOrder::LSB_FIRST, bitmap_format_bit_order: ImageOrder::LSB_FIRST, bitmap_format_scanline_unit: 0, bitmap_format_scanline_pad: 0, min_keycode: 0, max_keycode: 0, vendor: Default::default(), pixmap_formats: Default::default(), roots: Default::default(), }; let setup = setup.serialize(); assert_eq!(setup.len(), 4 * length_field as usize); let mock = ConnectionMock { error: 0, setup }; Box::into_raw(Box::new(mock)) as _ } pub(crate) unsafe fn xcb_generate_id(_c: *mut xcb_connection_t) -> u32 { unimplemented!(); } // From xcbext.h pub(crate) unsafe fn xcb_send_request64( _c: *mut xcb_connection_t, _flags: c_int, _vector: *mut iovec, _request: *const xcb_protocol_request_t, ) -> u64 { unimplemented!(); } #[cfg(unix)] pub(crate) unsafe fn xcb_send_request_with_fds64( _c: *mut xcb_connection_t, _flags: c_int, _vector: *mut iovec, _request: *const xcb_protocol_request_t, _num_fds: c_uint, _fds: *mut c_int, ) -> u64 { unimplemented!(); } pub(crate) unsafe fn xcb_wait_for_reply64( _c: *mut xcb_connection_t, _request: u64, _e: *mut *mut xcb_generic_error_t, ) -> *mut c_void { unimplemented!(); } pub(crate) unsafe fn xcb_poll_for_reply64( _c: *mut xcb_connection_t, _request: u64, _reply: *mut *mut c_void, _error: *mut *mut xcb_generic_error_t, ) -> c_int { unimplemented!(); } x11rb-0.8.1/tests/multithread_test.rs010064400017500001750000000172721402220031600157260ustar 00000000000000use std::sync::Arc; use x11rb::connection::Connection as _; use x11rb::protocol::xproto::{ ClientMessageData, ClientMessageEvent, ConnectionExt as _, EventMask, CLIENT_MESSAGE_EVENT, }; // Regression test for https://github.com/psychon/x11rb/issues/231 #[test] fn multithread_test() { let conn = fake_stream::connect().unwrap(); let conn = Arc::new(conn); // Auxiliary thread: send requests and wait for replies let conn1 = conn.clone(); let join = std::thread::spawn(move || { // Bug #231 sometimes caused `reply` to hang forever. // Send a huge amount of requests and wait for the reply // to check if it hangs at some point. for i in 1..=1_000_000 { let cookie = conn1.get_input_focus().unwrap(); cookie.reply().unwrap(); if (i % 50_000) == 0 { eprintln!("{}", i); } } eprintln!("all replies received successfully"); let event = ClientMessageEvent { response_type: CLIENT_MESSAGE_EVENT, format: 32, sequence: 0, window: 0, // Just anything, we don't care type_: 1, data: ClientMessageData::from([0, 0, 0, 0, 0]), }; conn1 .send_event(false, 0u32, EventMask::NO_EVENT, &event) .unwrap(); conn1.flush().unwrap(); }); // Main thread: wait for events until finished loop { let event = conn.wait_for_raw_event().unwrap(); if event[0] == CLIENT_MESSAGE_EVENT { break; } } join.join().unwrap(); } /// Implementations of `Read` and `Write` that do enough for the test to work. mod fake_stream { use std::io::{Error, ErrorKind}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::{Condvar, Mutex}; use x11rb::connection::SequenceNumber; use x11rb::errors::ConnectError; use x11rb::protocol::xproto::{ ImageOrder, Setup, CLIENT_MESSAGE_EVENT, GET_INPUT_FOCUS_REQUEST, SEND_EVENT_REQUEST, }; use x11rb::rust_connection::{PollMode, RustConnection, Stream}; use x11rb::utils::RawFdContainer; /// Create a new `RustConnection` connected to a fake stream pub(crate) fn connect() -> Result, ConnectError> { let setup = Setup { status: 0, protocol_major_version: 0, protocol_minor_version: 0, length: 0, release_number: 0, resource_id_base: 0, resource_id_mask: 0xff, motion_buffer_size: 0, maximum_request_length: 0, image_byte_order: ImageOrder::LSB_FIRST, bitmap_format_bit_order: ImageOrder::LSB_FIRST, bitmap_format_scanline_unit: 0, bitmap_format_scanline_pad: 0, min_keycode: 0, max_keycode: 0, vendor: Vec::new(), pixmap_formats: Vec::new(), roots: Vec::new(), }; let stream = fake_stream(); RustConnection::for_connected_stream(stream, setup) } /// Get a pair of fake streams that are connected to each other fn fake_stream() -> FakeStream { let (send, recv) = channel(); let pending = Vec::new(); FakeStream { inner: Mutex::new(FakeStreamInner { read: FakeStreamRead { recv, pending }, write: FakeStreamWrite { send, seqno: 0, skip: 0, }, }), condvar: Condvar::new(), } } /// A packet that still needs to be read from FakeStreamRead #[derive(Debug)] enum Packet { GetInputFocusReply(SequenceNumber), Event, } impl Packet { fn to_raw(&self) -> Vec { match self { Packet::GetInputFocusReply(seqno) => { let seqno = (*seqno as u16).to_ne_bytes(); let mut reply = vec![0; 32]; reply[0] = 1; // This is a reply reply[2..4].copy_from_slice(&seqno); reply } Packet::Event => { let mut reply = vec![0; 32]; reply[0] = CLIENT_MESSAGE_EVENT; reply } } } } #[derive(Debug)] pub(crate) struct FakeStream { inner: Mutex, condvar: Condvar, } #[derive(Debug)] struct FakeStreamInner { read: FakeStreamRead, write: FakeStreamWrite, } #[derive(Debug)] struct FakeStreamRead { recv: Receiver, pending: Vec, } #[derive(Debug)] pub(crate) struct FakeStreamWrite { send: Sender, seqno: SequenceNumber, skip: usize, } impl Stream for FakeStream { fn poll(&self, mode: PollMode) -> std::io::Result<()> { if mode.writable() { Ok(()) } else { let mut inner = self.inner.lock().unwrap(); loop { if inner.read.pending.is_empty() { match inner.read.recv.try_recv() { Ok(packet) => { inner.read.pending.extend(packet.to_raw()); return Ok(()); } Err(std::sync::mpsc::TryRecvError::Empty) => { inner = self.condvar.wait(inner).unwrap(); } Err(std::sync::mpsc::TryRecvError::Disconnected) => unreachable!(), } } else { return Ok(()); } } } } fn read( &self, buf: &mut [u8], _fd_storage: &mut Vec, ) -> std::io::Result { let mut inner = self.inner.lock().unwrap(); if inner.read.pending.is_empty() { match inner.read.recv.try_recv() { Ok(packet) => inner.read.pending.extend(packet.to_raw()), Err(std::sync::mpsc::TryRecvError::Empty) => { return Err(Error::new(ErrorKind::WouldBlock, "Would block")); } Err(std::sync::mpsc::TryRecvError::Disconnected) => unreachable!(), } } let len = inner.read.pending.len().min(buf.len()); buf[..len].copy_from_slice(&inner.read.pending[..len]); inner.read.pending.drain(..len); Ok(len) } fn write(&self, buf: &[u8], fds: &mut Vec) -> std::io::Result { assert!(fds.is_empty()); let mut inner = self.inner.lock().unwrap(); if inner.write.skip > 0 { assert_eq!(inner.write.skip, buf.len()); inner.write.skip = 0; return Ok(buf.len()); } inner.write.seqno += 1; match buf[0] { GET_INPUT_FOCUS_REQUEST => inner .write .send .send(Packet::GetInputFocusReply(inner.write.seqno)) .unwrap(), SEND_EVENT_REQUEST => inner.write.send.send(Packet::Event).unwrap(), _ => unimplemented!(), } // Compute how much of the package was not yet received inner.write.skip = usize::from(u16::from_ne_bytes([buf[2], buf[3]])) * 4 - buf.len(); self.condvar.notify_all(); Ok(buf.len()) } } } x11rb-0.8.1/tests/parsing_tests.rs010064400017500001750000000127371402220031600152330ustar 00000000000000use x11rb::errors::ParseError; use x11rb::protocol::xproto::{Setup, VisualClass}; use x11rb::x11_utils::TryParse; fn get_setup_data() -> Vec { let mut s = Vec::new(); let vendor_len: u16 = 2; let num_pixmap_formats: u8 = 1; let roots_len: u8 = 18; let header: u16 = 10; let length: u16 = header + vendor_len + 2 * u16::from(num_pixmap_formats) + u16::from(roots_len); s.extend(&[1, 0]); // Status "success" and padding s.extend(&11u16.to_ne_bytes()); // major version s.extend(&0u16.to_ne_bytes()); // minor version s.extend(&length.to_ne_bytes()); // length s.extend(&0x1234_5678u32.to_ne_bytes()); // release number s.extend(&0x1000_0000u32.to_ne_bytes()); // resource id base s.extend(&0x0000_00ffu32.to_ne_bytes()); // resource id mask s.extend(&0u32.to_ne_bytes()); // motion buffer size s.extend(&6u16.to_ne_bytes()); // vendor length s.extend(&0x100u16.to_ne_bytes()); // maximum request length s.push(1); // roots length s.push(num_pixmap_formats); // pixmap formats length s.push(1); // image byte order: MSB first s.push(1); // bitmap format bit order: MSB first s.push(0); // scanline unit s.push(0); // scanline pad s.push(0); // min keycode s.push(0xff); // max keycode s.extend(&[0, 0, 0, 0]); // padding assert_eq!(s.len(), usize::from(header) * 4); s.extend("Vendor ".bytes()); // vendor + padding assert_eq!(s.len(), usize::from(header + vendor_len) * 4); // Pixmap formats, we said above there is one entry s.push(15); // depth s.push(42); // bits per pixel s.push(21); // scanline pad s.extend(&[0, 0, 0, 0, 0]); // padding assert_eq!( s.len(), 4 * usize::from(header + vendor_len + 2 * u16::from(num_pixmap_formats)) ); // Screens, we said above there is one entry s.extend(&1u32.to_ne_bytes()); // root window s.extend(&2u32.to_ne_bytes()); // default colormap s.extend(&3u32.to_ne_bytes()); // white pixel s.extend(&4u32.to_ne_bytes()); // black pixel s.extend(&0u32.to_ne_bytes()); // current input masks s.extend(&0u16.to_ne_bytes()); // width in pixels s.extend(&0u16.to_ne_bytes()); // height in pixels s.extend(&0u16.to_ne_bytes()); // width in mm s.extend(&0u16.to_ne_bytes()); // height in mm s.extend(&0u16.to_ne_bytes()); // min installed maps s.extend(&0u16.to_ne_bytes()); // max installed maps s.extend(&0u32.to_ne_bytes()); // root visual s.extend(&[0, 0, 0, 1]); // backing stores, save unders, root depths, allowed depths len // one depth entry s.extend(&[99, 0]); // depth and padding s.extend(&1u16.to_ne_bytes()); // width visuals len s.extend(&[0, 0, 0, 0]); // padding // one visualtype entry s.extend(&80u32.to_ne_bytes()); // visualid s.extend(&[2, 4]); // class and bits per rgb value s.extend(&81u16.to_ne_bytes()); // colormap entries s.extend(&82u32.to_ne_bytes()); // red mask s.extend(&83u32.to_ne_bytes()); // green mask s.extend(&84u32.to_ne_bytes()); // blue mask s.extend(&[0, 0, 0, 0]); // padding assert_eq!(s.len(), usize::from(length) * 4); s } #[test] fn parse_setup() -> Result<(), ParseError> { let setup = get_setup_data(); let (setup, remaining) = Setup::try_parse(&*setup)?; assert_eq!(remaining.len(), 0); assert_eq!( (1, 11, 0), ( setup.status, setup.protocol_major_version, setup.protocol_minor_version ) ); assert_eq!(0x1234_5678, setup.release_number); assert_eq!((0, 0xff), (setup.min_keycode, setup.max_keycode)); assert_eq!(b"Vendor", &setup.vendor[..]); assert_eq!(1, setup.pixmap_formats.len()); let format = &setup.pixmap_formats[0]; assert_eq!(15, format.depth); assert_eq!(42, format.bits_per_pixel); assert_eq!(21, format.scanline_pad); assert_eq!(1, setup.roots.len()); let root = &setup.roots[0]; assert_eq!( (1, 2, 3, 4), ( root.root, root.default_colormap, root.white_pixel, root.black_pixel ) ); assert_eq!(1, root.allowed_depths.len()); let depth = &root.allowed_depths[0]; assert_eq!(99, depth.depth); assert_eq!(1, depth.visuals.len()); let visual = &depth.visuals[0]; assert_eq!(80, visual.visual_id); assert_eq!(VisualClass::STATIC_COLOR, visual.class); assert_eq!(4, visual.bits_per_rgb_value); assert_eq!(81, visual.colormap_entries); assert_eq!(82, visual.red_mask); assert_eq!(83, visual.green_mask); assert_eq!(84, visual.blue_mask); Ok(()) } #[cfg(feature = "xinput")] #[test] fn parse_xi_get_property_reply_format_0() { let mut s = vec![ 1, // response_type 0, // pad ]; s.extend(&0u16.to_ne_bytes()); // sequence s.extend(&0u32.to_ne_bytes()); // length s.extend(&0u32.to_ne_bytes()); // type s.extend(&0u32.to_ne_bytes()); // bytes_after s.extend(&0u32.to_ne_bytes()); // num_items s.push(0); // format s.extend(&[0; 11]); // pad use x11rb::protocol::xinput::{XIGetPropertyItems, XIGetPropertyReply}; let empty: &[u8] = &[]; assert_eq!( XIGetPropertyReply::try_parse(&s), Ok(( XIGetPropertyReply { sequence: 0, length: 0, type_: 0, bytes_after: 0, num_items: 0, items: XIGetPropertyItems::InvalidValue(0), }, empty, )), ); } x11rb-0.8.1/tests/regression_tests.rs010064400017500001750000000227621402220031600157470ustar 00000000000000use std::cell::RefCell; use std::io::IoSlice; use std::ops::Deref; use x11rb::connection::{ compute_length_field, BufWithFds, DiscardMode, ReplyOrError, RequestConnection, RequestKind, SequenceNumber, }; use x11rb::cookie::{Cookie, CookieWithFds, VoidCookie}; use x11rb::errors::{ConnectionError, ParseError, ReplyError}; use x11rb::protocol::xproto::{ ClientMessageData, ConnectionExt, KeymapNotifyEvent, Segment, SetupAuthenticate, }; use x11rb::utils::RawFdContainer; use x11rb::x11_utils::{ExtensionInformation, Serialize, TryParse, TryParseFd}; #[derive(Debug)] struct SavedRequest { has_reply: bool, data: Vec, } impl SavedRequest { fn new(has_reply: bool, data: &[IoSlice]) -> SavedRequest { let data = data .iter() .flat_map(|slice| slice.deref()) .copied() .collect::>(); SavedRequest { has_reply, data } } } #[derive(Debug, Default)] struct FakeConnection(RefCell>); impl FakeConnection { fn check_requests(&self, expected: &[(bool, Vec)]) { let vec = self.0.borrow(); for (expected, actual) in expected.iter().zip(vec.iter()) { assert_eq!(expected.0, actual.has_reply); assert_eq!(actual.data, expected.1); } assert_eq!(expected.len(), vec.len()); } fn internal_send_request( &self, bufs: &[IoSlice], fds: Vec, ) -> Result { assert_eq!(fds.len(), 0); let mut storage = Default::default(); let bufs = compute_length_field(self, bufs, &mut storage)?; self.0.borrow_mut().push(SavedRequest::new(false, bufs)); Ok(0) } } impl RequestConnection for FakeConnection { type Buf = Vec; fn send_request_with_reply( &self, bufs: &[IoSlice], fds: Vec, ) -> Result, ConnectionError> where R: TryParse, { Ok(Cookie::new(self, self.internal_send_request(bufs, fds)?)) } fn send_request_with_reply_with_fds( &self, _bufs: &[IoSlice], _fds: Vec, ) -> Result, ConnectionError> where R: TryParseFd, { unimplemented!() } fn send_request_without_reply( &self, bufs: &[IoSlice], fds: Vec, ) -> Result, ConnectionError> { Ok(VoidCookie::new( self, self.internal_send_request(bufs, fds)?, )) } fn discard_reply(&self, _sequence: SequenceNumber, _kind: RequestKind, _mode: DiscardMode) { // Just ignore this } fn prefetch_extension_information( &self, _extension_name: &'static str, ) -> Result<(), ConnectionError> { unimplemented!(); } fn extension_information( &self, _extension_name: &'static str, ) -> Result, ConnectionError> { unimplemented!() } fn wait_for_reply_or_raw_error( &self, _sequence: SequenceNumber, ) -> Result>, ConnectionError> { unimplemented!() } fn wait_for_reply( &self, _sequence: SequenceNumber, ) -> Result>, ConnectionError> { unimplemented!() } fn wait_for_reply_with_fds_raw( &self, _sequence: SequenceNumber, ) -> Result>, Vec>, ConnectionError> { unimplemented!() } fn check_for_raw_error( &self, _sequence: SequenceNumber, ) -> Result>, ConnectionError> { unimplemented!() } fn maximum_request_bytes(&self) -> usize { // Must be at least 4 * 2^16 so that we can test BIG-REQUESTS 2usize.pow(19) } fn prefetch_maximum_request_bytes(&self) { unimplemented!() } fn parse_error(&self, _error: &[u8]) -> Result { unimplemented!() } fn parse_event(&self, _event: &[u8]) -> Result { unimplemented!() } } #[test] fn test_poly_segment() -> Result<(), ReplyError> { let conn = FakeConnection::default(); let drawable = 42; let gc = 0x1337; let segments = [ Segment { x1: 1, y1: 2, x2: 3, y2: 4, }, Segment { x1: 5, y1: 6, x2: 7, y2: 8, }, ]; let length: u16 = (12 + segments.len() * 8) as u16 / 4; conn.poly_segment(drawable, gc, &segments)?; let mut expected = vec![ x11rb::protocol::xproto::POLY_SEGMENT_REQUEST, 0, // padding ]; expected.extend(&length.to_ne_bytes()); // length, not in the xml expected.extend(&drawable.to_ne_bytes()); expected.extend(&gc.to_ne_bytes()); // Segments for x in 1u16..9u16 { expected.extend(&x.to_ne_bytes()); } conn.check_requests(&[(false, expected)]); Ok(()) } #[test] fn test_big_requests() -> Result<(), ConnectionError> { let conn = FakeConnection::default(); let big_buffer = [0; (1 << 18) + 1]; let drawable: u32 = 42; let gc: u32 = 0x1337; let x: i16 = 21; let y: i16 = 7; let padding = 3; // big_buffer's size rounded up to a multiple of 4 let big_request_length_field = 4; let length: u32 = (16 + big_request_length_field + big_buffer.len() as u32 + padding) / 4; conn.poly_text16(drawable, gc, x, y, &big_buffer)?; let mut expected = vec![ x11rb::protocol::xproto::POLY_TEXT16_REQUEST, // padding 0, // Length of zero: we use big requests 0, 0, ]; // Actual length expected.extend(&length.to_ne_bytes()); expected.extend(&drawable.to_ne_bytes()); expected.extend(&gc.to_ne_bytes()); expected.extend(&x.to_ne_bytes()); expected.extend(&y.to_ne_bytes()); expected.extend(big_buffer.iter()); expected.extend((0..padding).map(|_| 0)); conn.check_requests(&[(false, expected)]); Ok(()) } #[test] fn test_too_large_request() { let conn = FakeConnection::default(); let big_buffer = [0; (1 << 19) + 1]; let drawable: u32 = 42; let gc: u32 = 0x1337; let x: i16 = 21; let y: i16 = 7; let res = conn.poly_text16(drawable, gc, x, y, &big_buffer); match res.unwrap_err() { ConnectionError::MaximumRequestLengthExceeded => {} err => panic!("Wrong error: {:?}", err), }; } #[test] fn test_send_event() -> Result<(), ConnectionError> { // Prepare the event let buffer: [u8; 32] = [ 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, ]; let event = KeymapNotifyEvent::try_parse(&buffer[..])?.0; // "Send" it let conn = FakeConnection::default(); let propagate = true; let destination: u32 = 0x1337; let event_mask: u32 = 7; conn.send_event(propagate, destination, event_mask, event)?; let mut expected = vec![x11rb::protocol::xproto::SEND_EVENT_REQUEST, propagate as _]; expected.extend(&((12u16 + 32u16) / 4).to_ne_bytes()); expected.extend(&destination.to_ne_bytes()); expected.extend(&event_mask.to_ne_bytes()); expected.extend(buffer.iter()); conn.check_requests(&[(false, expected)]); Ok(()) } #[test] fn test_get_keyboard_mapping() -> Result<(), ConnectionError> { let conn = FakeConnection::default(); let cookie = conn.get_keyboard_mapping(1, 2)?; // Prevent call to discard_reply(), we only check request sending std::mem::forget(cookie); let mut expected = Vec::new(); let length: u16 = 2; expected.push(101); // request major code expected.push(0); // padding expected.extend(&length.to_ne_bytes()); // length, not in the xml expected.push(1); // first keycode expected.push(2); // length expected.extend(&[0, 0]); // padding conn.check_requests(&[(false, expected)]); Ok(()) } #[test] fn test_client_message_data_parse() { let short_array = [0, 0, 0]; let err = ClientMessageData::try_parse(&short_array); assert!(err.is_err()); assert_eq!(err.unwrap_err(), ParseError::InsufficientData); } #[test] fn test_set_modifier_mapping() -> Result<(), ConnectionError> { let conn = FakeConnection::default(); let cookie = conn.set_modifier_mapping(&(1..17).collect::>())?; // Prevent call to discard_reply(), we only check request sending std::mem::forget(cookie); let mut expected = Vec::new(); let length: u16 = 5; expected.push(118); // request major code expected.push(2); // keycodes per modifier expected.extend(&length.to_ne_bytes()); // length, not in the xml expected.extend(1u8..17u8); conn.check_requests(&[(false, expected)]); Ok(()) } #[test] fn test_serialize_setup_authenticate() { let setup = SetupAuthenticate { status: 2, reason: b"12345678".to_vec(), }; // At the time of writing, the code generator does not produce the correct code... let length = 2u16.to_ne_bytes(); let setup_bytes = [ 2, 0, 0, 0, 0, 0, length[0], length[1], b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', ]; assert_eq!(&setup_bytes[..], &setup.serialize()[..]); } #[cfg(feature = "xinput")] #[allow(dead_code)] fn compile_test(conn: &impl RequestConnection) { use x11rb::protocol::xinput::{xi_query_device, Device}; let _ = xi_query_device(conn, Device::ALL); } x11rb-0.8.1/tests/request_parsing_tests.rs010064400017500001750000000170221402220031600167730ustar 00000000000000use std::borrow::Cow; use x11rb::errors::ParseError; use x11rb::x11_utils::RequestHeader; macro_rules! add_ne { ($data:expr, $add:expr) => { $data.extend(&$add.to_ne_bytes()) }; } #[test] fn test_bad_request_header_opcode() { use x11rb::protocol::xproto::GetInputFocusRequest; let header = RequestHeader { major_opcode: 1, minor_opcode: 0, remaining_length: 0, }; let body = &[]; assert_eq!( GetInputFocusRequest::try_parse_request(header, body), Err(ParseError::InvalidValue) ); } #[test] fn test_bad_request_header_length() { use x11rb::protocol::xproto::CreateWindowRequest; let header = RequestHeader { major_opcode: 1, minor_opcode: 0, remaining_length: 42, }; let body = &[]; assert_eq!( CreateWindowRequest::try_parse_request(header, body), Err(ParseError::InsufficientData) ); } #[test] fn test_create_window1() { use x11rb::protocol::xproto::{CreateWindowAux, CreateWindowRequest, Gravity, WindowClass}; let header = RequestHeader { major_opcode: 1, minor_opcode: 0x18, remaining_length: 10, }; let mut body = vec![]; add_ne!(body, 0x05c0_0001u32); add_ne!(body, 0x0000_0513u32); add_ne!(body, 0x047bu16); add_ne!(body, 0x0134u16); add_ne!(body, 0x03f5u16); add_ne!(body, 0x033bu16); add_ne!(body, 0x0000u16); add_ne!(body, 0x0001u16); add_ne!(body, 0x0000_0047u32); add_ne!(body, 0x0000_001au32); add_ne!(body, 0xfff2_f1f0u32); add_ne!(body, 0x0000_0000u32); add_ne!(body, 0x0000_0001u32); let r = CreateWindowRequest::try_parse_request(header, &body).unwrap(); assert_eq!( r, CreateWindowRequest { depth: 0x18, wid: 0x05c0_0001, parent: 0x0000_0513, x: 0x047b, y: 0x0134, width: 0x03f5, height: 0x033b, border_width: 0, class: WindowClass::INPUT_OUTPUT, visual: 0x47, value_list: Cow::Owned(CreateWindowAux { background_pixel: Some(0xfff2_f1f0), border_pixel: Some(0), bit_gravity: Some(Gravity::NORTH_WEST), ..Default::default() }), } ); } #[test] fn test_create_window2() { use x11rb::protocol::xproto::{CreateWindowAux, CreateWindowRequest, Gravity, WindowClass}; let header = RequestHeader { major_opcode: 1, minor_opcode: 0x18, remaining_length: 11, }; let mut body = vec![]; add_ne!(body, 0x0540_0003u32); add_ne!(body, 0x0000_0513u32); add_ne!(body, 0x0000_0000u32); add_ne!(body, 0x0001u16); add_ne!(body, 0x0001u16); add_ne!(body, 0x0000u16); add_ne!(body, 0x0001u16); add_ne!(body, 0x0000_035au32); add_ne!(body, 0x0000_201au32); add_ne!(body, 0x0000_0000u32); add_ne!(body, 0x0000_0000u32); add_ne!(body, 0x0000_0001u32); add_ne!(body, 0x0540_0002u32); let r = CreateWindowRequest::try_parse_request(header, &body).unwrap(); assert_eq!( r, CreateWindowRequest { depth: 0x18, wid: 0x0540_0003, parent: 0x0000_0513, x: 0, y: 0, width: 1, height: 1, border_width: 0, class: WindowClass::INPUT_OUTPUT, visual: 0x35a, value_list: Cow::Owned(CreateWindowAux { background_pixel: Some(0), border_pixel: Some(0), bit_gravity: Some(Gravity::NORTH_WEST), colormap: Some(0x0540_0002), ..Default::default() }), } ); } #[test] fn test_change_window_attributes() { use x11rb::protocol::xproto::{ ChangeWindowAttributesAux, ChangeWindowAttributesRequest, EventMask, }; let header = RequestHeader { major_opcode: 2, minor_opcode: 0, remaining_length: 3, }; let mut body = vec![]; add_ne!(body, 0x0000_0513u32); add_ne!(body, 0x0000_0800u32); add_ne!(body, 0x0040_0000u32); let r = ChangeWindowAttributesRequest::try_parse_request(header, &body).unwrap(); assert_eq!( r, ChangeWindowAttributesRequest { window: 0x0513, value_list: Cow::Owned(ChangeWindowAttributesAux { event_mask: Some(EventMask::PROPERTY_CHANGE.into()), ..Default::default() }), } ); } #[test] fn test_get_window_attributes() { use x11rb::protocol::xproto::GetWindowAttributesRequest; let header = RequestHeader { major_opcode: 3, minor_opcode: 0, remaining_length: 1, }; let mut body = vec![]; add_ne!(body, 0x00e0_0002u32); let r = GetWindowAttributesRequest::try_parse_request(header, &body).unwrap(); assert_eq!( r, GetWindowAttributesRequest { window: 0x00e0_0002 } ); } #[test] fn test_get_input_focus() { use x11rb::protocol::xproto::GetInputFocusRequest; let header = RequestHeader { major_opcode: 43, minor_opcode: 0, remaining_length: 0, }; let body = &[]; let r = GetInputFocusRequest::try_parse_request(header, body).unwrap(); assert_eq!(r, GetInputFocusRequest,); } #[test] fn test_query_text_extents() { use x11rb::protocol::xproto::{Char2b, QueryTextExtentsRequest}; let header = RequestHeader { major_opcode: 48, minor_opcode: 0, remaining_length: 2, }; let mut body = vec![]; add_ne!(body, 0x1234_5678u32); body.extend(&[0xbc, 0x9a, 0xf0, 0xde]); let r = QueryTextExtentsRequest::try_parse_request(header, &body).unwrap(); assert_eq!( r, QueryTextExtentsRequest { font: 0x1234_5678, string: Cow::Owned(vec![ Char2b { byte1: 0xbc, byte2: 0x9a, }, Char2b { byte1: 0xf0, byte2: 0xde, }, ]), } ); } #[test] fn test_query_text_extents_odd_length() { use x11rb::protocol::xproto::{Char2b, QueryTextExtentsRequest}; let header = RequestHeader { major_opcode: 48, minor_opcode: 1, remaining_length: 2, }; let mut body = vec![]; add_ne!(body, 0x1234_5678u32); body.extend(&[0xbc, 0x9a, 0xf0, 0xde]); let r = QueryTextExtentsRequest::try_parse_request(header, &body).unwrap(); assert_eq!( r, QueryTextExtentsRequest { font: 0x1234_5678, string: Cow::Owned(vec![Char2b { byte1: 0xbc, byte2: 0x9a, },]), } ); } #[cfg(feature = "randr")] #[test] fn test_randr_get_output_property() { use x11rb::protocol::randr::GetOutputPropertyRequest; let header = RequestHeader { major_opcode: 140, minor_opcode: 15, remaining_length: 6, }; let mut body = vec![]; add_ne!(body, 0x0000_008au32); add_ne!(body, 0x0000_0045u32); add_ne!(body, 0x0000_0000u32); add_ne!(body, 0x0000_0000u32); add_ne!(body, 0x0000_0080u32); add_ne!(body, 0x0000_0000u32); let r = GetOutputPropertyRequest::try_parse_request(header, &body).unwrap(); assert_eq!( r, GetOutputPropertyRequest { output: 0x8a, property: 0x45, type_: 0, long_offset: 0, long_length: 128, delete: false, pending: false, }, ); } x11rb-0.8.1/tests/resource_manager.rs010064400017500001750000000214531402220031600156620ustar 00000000000000#[cfg(feature = "resource_manager")] mod test { use std::fs; use std::io::IoSlice; use std::path::{Path, PathBuf}; use x11rb::connection::{ BufWithFds, Connection, DiscardMode, RawEventAndSeqNumber, ReplyOrError, RequestConnection, RequestKind, SequenceNumber, }; use x11rb::cookie::{Cookie, CookieWithFds, VoidCookie}; use x11rb::errors::{ConnectionError, ParseError, ReplyOrIdError}; use x11rb::protocol::xproto::{Screen, Setup}; use x11rb::protocol::Event; use x11rb::resource_manager::Database; use x11rb::utils::RawFdContainer; use x11rb::x11_utils::{ExtensionInformation, Serialize, TryParse, TryParseFd, X11Error}; // Most tests in here are based on [1], which is: Copyright © 2016 Ingo Bürk // [1]: https://github.com/Airblader/xcb-util-xrm/blob/master/tests/tests_database.c /// Get the path to the `target` directory for the current build. /// /// This is inspired by cargo: /// https://github.com/rust-lang/cargo/blob/7302186d7beb2b11bf7366c0aa66269313ebe18f/crates/cargo-test-support/src/paths.rs#L18-L31 fn get_temporary_dir(unique_name: &str) -> PathBuf { let mut path = std::env::current_exe().unwrap(); while path.file_name().and_then(|n| n.to_str()) != Some("target") { path.pop(); } path.push("test_data"); path.push(unique_name); fs::create_dir_all(&path).unwrap(); path } fn write_file(base: impl AsRef, path: impl AsRef, content: &[u8]) -> PathBuf { let mut file_path = PathBuf::from(base.as_ref()); file_path.push(path.as_ref()); if let Some(parent) = file_path.parent() { fs::create_dir_all(&parent).unwrap(); } fs::write(&file_path, content).unwrap(); file_path } fn database_from_file(file: impl AsRef) -> Database { // I decided against adding something like this to the API... let file = file.as_ref(); let mut include = Vec::new(); include.extend(b"#include \""); include.extend(file.file_name().unwrap().to_str().unwrap().bytes()); include.extend(b"\"\n"); Database::new_from_data_with_base_directory(&include, file.parent().unwrap()) } fn check_db(db: &Database, queries: &[(&str, &[u8])]) { let mut errors = 0; for (query, expected) in queries { let result = db.get_bytes(query, ""); if result != Some(expected) { eprintln!( "Queried database for \"{}\" and expected {:?}, but got {:?}", query, expected, result ); errors += 1; } } if errors != 0 { panic!("Had {} errors", errors); } } #[test] fn relative_include() { let dir = get_temporary_dir("relative_include"); let file = write_file( &dir, "Xresources1", b"First: 1\n\n#include \"xresources2\"\n", ); write_file( &dir, "xresources2", b"#include \"sub/xresources3\"\nSecond: 2\n", ); write_file(&dir, "sub/xresources3", b"Third: 3\n"); let db = database_from_file(file); check_db(&db, &[("First", b"1"), ("Second", b"2"), ("Third", b"3")]); } #[test] fn include_loop() { let dir = get_temporary_dir("include_loop"); let file = write_file( &dir, "loop.xresources", b"First: 1\n! Provoke an endless chain of self-inclusion\n#include \"loop.xresources\"\nSecond: 2\n", ); let db = database_from_file(file); check_db(&db, &[("First", b"1")]); } #[test] fn home_resolution() { let mut dir = get_temporary_dir("home_resolution"); write_file(&dir, ".Xresources", b"First: 1\n"); write_file(&dir, "xenvironment", b"Second: 2\n"); std::env::set_var("HOME", &dir); dir.push("xenvironment"); std::env::set_var("XENVIRONMENT", dir); let conn = mock_connection(None); let db = Database::new_from_default(&conn).unwrap(); check_db(&db, &[("First", b"1"), ("Second", b"2")]); } #[test] fn from_resource_manager() { let conn = mock_connection(Some(b"First: 1\n*Second: 2\n")); let db = Database::new_from_default(&conn).unwrap(); check_db(&db, &[("First", b"1"), ("Second", b"2")]); } /// Create a mock connection that produces the given answer for queries of the RESOURCE_MANAGER /// property. fn mock_connection(resource_manager: Option<&[u8]>) -> impl Connection { // Ugly way to get a default screen: Parse enough zero bytes let screen = Screen::try_parse(&[0; 100]).unwrap().0; let mut setup = Setup::try_parse(&[0; 100]).unwrap().0; setup.roots.push(screen); MockConnection(setup, resource_manager.map(|v| v.to_vec())) } struct MockConnection(Setup, Option>); impl RequestConnection for MockConnection { type Buf = Vec; fn send_request_with_reply( &self, _: &[IoSlice<'_>], _: Vec, ) -> Result, ConnectionError> where R: TryParse, { Ok(Cookie::new(self, 42)) } fn send_request_with_reply_with_fds( &self, _: &[IoSlice<'_>], _: Vec, ) -> Result, ConnectionError> where R: TryParseFd, { unimplemented!() } fn send_request_without_reply( &self, _: &[IoSlice<'_>], _: Vec, ) -> Result, ConnectionError> { unimplemented!() } fn discard_reply(&self, _: SequenceNumber, _: RequestKind, _: DiscardMode) { unimplemented!() } fn prefetch_extension_information(&self, _: &'static str) -> Result<(), ConnectionError> { unimplemented!() } fn extension_information( &self, _: &'static str, ) -> Result, ConnectionError> { unimplemented!() } fn wait_for_reply_or_raw_error( &self, sequence: SequenceNumber, ) -> Result, ConnectionError> { let value = self.1.as_ref().map(|v| &v[..]).unwrap_or(&[]); // response type let mut reply = vec![1]; // format if value.is_empty() { reply.push(0); } else { reply.push(8); } // sequence (sequence as u16).serialize_into(&mut reply); // length 0u32.serialize_into(&mut reply); // type (STRING) 31u32.serialize_into(&mut reply); // bytes_after 0u32.serialize_into(&mut reply); (value.len() as u32).serialize_into(&mut reply); // padding reply.extend([0; 12].iter().copied()); reply.extend(value); Ok(ReplyOrError::Reply(reply)) } fn wait_for_reply(&self, _: SequenceNumber) -> Result, ConnectionError> { unimplemented!() } fn wait_for_reply_with_fds_raw( &self, _: SequenceNumber, ) -> Result, Self::Buf>, ConnectionError> { unimplemented!() } fn check_for_raw_error( &self, _: SequenceNumber, ) -> Result, ConnectionError> { unimplemented!() } fn prefetch_maximum_request_bytes(&self) { unimplemented!() } fn maximum_request_bytes(&self) -> usize { unimplemented!() } fn parse_error(&self, _: &[u8]) -> Result { unimplemented!() } fn parse_event(&self, _: &[u8]) -> Result { unimplemented!() } } impl Connection for MockConnection { fn wait_for_raw_event_with_sequence( &self, ) -> Result, ConnectionError> { unimplemented!() } fn poll_for_raw_event_with_sequence( &self, ) -> Result>, ConnectionError> { unimplemented!() } fn flush(&self) -> Result<(), ConnectionError> { unimplemented!() } fn setup(&self) -> &Setup { &self.0 } fn generate_id(&self) -> Result { unimplemented!() } } }