autocommit 2022-03-23 14:35:09 CET
This commit is contained in:
parent
6597a57ad5
commit
63be47a9fb
24 changed files with 703 additions and 722 deletions
255
Cargo.lock
generated
255
Cargo.lock
generated
|
|
@ -118,9 +118,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.15.1"
|
||||
version = "0.15.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b869e97a87170f96762f9f178eae8c461147e722ba21dd8814105bf5716bf14a"
|
||||
checksum = "129e928d3eda625f53ce257589efbe5143416875fd01bddd08c8c6feb8b9962b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-sys-rs",
|
||||
|
|
@ -148,9 +148,9 @@ checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
|||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
version = "0.10.1"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "295b6eb918a60a25fec0b23a5e633e74fddbaf7bb04411e65a10c366aca4b5cd"
|
||||
checksum = "5e068cb2806bbc15b439846dc16c5f89f8599f2c3e4d73d4449d38f9b2f0b6c5"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
|
@ -202,30 +202,6 @@ dependencies = [
|
|||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.21"
|
||||
|
|
@ -233,7 +209,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -253,12 +228,6 @@ dependencies = [
|
|||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.21"
|
||||
|
|
@ -270,12 +239,6 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.21"
|
||||
|
|
@ -288,28 +251,14 @@ version = "0.3.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4addc164932852d066774c405dbbdb7914742d2b39e39e1a7ca949c856d054d1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.4"
|
||||
|
|
@ -329,9 +278,9 @@ checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
|
|||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.15.5"
|
||||
version = "0.15.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41dcfbdb6cc6c02aee163339465d8a40d6f3f64c3a43f729a4195f0e153338b7"
|
||||
checksum = "a826fad715b57834920839d7a594c3b5e416358c7d790bdaba847a40d7c1d96d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
|
|
@ -349,9 +298,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.15.3"
|
||||
version = "0.15.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e58b262ff65ef771003873cea8c10e0fe854f1c508d48d62a4111a1ff163f7d1"
|
||||
checksum = "dac4d47c544af67747652ab1865ace0ffa1155709723ac4f32e97587dd4735b2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
|
|
@ -364,9 +313,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.15.5"
|
||||
version = "0.15.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa1d4e1a63d8574541e5b92931e4e669ddc87ffa85d58e84e631dba13ad2e10c"
|
||||
checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps",
|
||||
|
|
@ -374,9 +323,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.15.5"
|
||||
version = "0.15.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a"
|
||||
checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
|
|
@ -425,7 +374,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"default-config",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"futures-util",
|
||||
"isnt",
|
||||
"jay-config",
|
||||
"libloading",
|
||||
|
|
@ -435,15 +384,12 @@ dependencies = [
|
|||
"once_cell",
|
||||
"pango",
|
||||
"pangocairo",
|
||||
"parking_lot",
|
||||
"pin-project",
|
||||
"rand",
|
||||
"renderdoc",
|
||||
"repc",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"uapi",
|
||||
"x11rb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -476,15 +422,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
|
@ -500,15 +437,6 @@ version = "2.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
|
|
@ -519,19 +447,6 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.22.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.3.3"
|
||||
|
|
@ -579,9 +494,9 @@ checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
|||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.15.2"
|
||||
version = "0.15.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79211eff430c29cc38c69e0ab54bc78fa1568121ca9737707eee7f92a8417a94"
|
||||
checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"glib",
|
||||
|
|
@ -592,9 +507,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pango-sys"
|
||||
version = "0.15.1"
|
||||
version = "0.15.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2"
|
||||
checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
|
|
@ -629,29 +544,6 @@ dependencies = [
|
|||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.10"
|
||||
|
|
@ -698,9 +590,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dada8c9981fcf32929c3c0f0cd796a9284aca335565227ed88c83babb1d43dc"
|
||||
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"toml",
|
||||
|
|
@ -778,15 +670,6 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
|
|
@ -810,27 +693,6 @@ version = "0.6.25"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "renderdoc"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42e14087d51efd3b42eb341e37b6f320af2b0750519ea849cb68bb7289643ed"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"float-cmp",
|
||||
"libloading",
|
||||
"once_cell",
|
||||
"renderdoc-sys",
|
||||
"winapi",
|
||||
"wio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "renderdoc-sys"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157"
|
||||
|
||||
[[package]]
|
||||
name = "repc"
|
||||
version = "0.1.1"
|
||||
|
|
@ -852,12 +714,6 @@ version = "0.1.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.136"
|
||||
|
|
@ -1030,81 +886,8 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[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 = "windows-sys"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
|
||||
|
||||
[[package]]
|
||||
name = "wio"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e99be55648b3ae2a52342f9a870c0e138709a3493261ce9b469afe6e4df6d8a"
|
||||
dependencies = [
|
||||
"gethostname",
|
||||
"nix",
|
||||
"winapi",
|
||||
"winapi-wsapoll",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ thiserror = "1.0.30"
|
|||
ahash = "0.7.6"
|
||||
log = "0.4.14"
|
||||
env_logger = "0.9.0"
|
||||
futures = "0.3.19"
|
||||
futures-util = "0.3.19"
|
||||
num-traits = "0.2.14"
|
||||
num-derive = "0.3.3"
|
||||
bitflags = "1.3.2"
|
||||
|
|
@ -28,9 +28,8 @@ bstr = "0.2.17"
|
|||
isnt = "0.1.0"
|
||||
once_cell = "1.9.0"
|
||||
rand = "0.8.4"
|
||||
renderdoc = "0.10.1"
|
||||
smallvec = { version = "1.8.0", features = ["const_generics", "const_new", "union"] }
|
||||
backtrace = "0.3.64"
|
||||
backtrace = { version = "0.3.64", optional = true }
|
||||
byteorder = "1.4.3"
|
||||
chrono = "0.4.19"
|
||||
bincode = "2.0.0-beta.3"
|
||||
|
|
@ -39,9 +38,7 @@ cairo-rs = { version = "0.15.1", features = ["png"] }
|
|||
pango = { version = "0.15.2", features = ["v1_44"] }
|
||||
jay-config = { path = "jay-config" }
|
||||
default-config = { path = "default-config" }
|
||||
x11rb = { version = "0.9.0", features = ["composite", "cursor"] }
|
||||
pin-project = "1.0.10"
|
||||
parking_lot = "0.12.0"
|
||||
|
||||
[build-dependencies]
|
||||
repc = "0.1.1"
|
||||
|
|
@ -52,4 +49,4 @@ bstr = "0.2.17"
|
|||
opt-level = 3
|
||||
|
||||
[features]
|
||||
rc_tracking = []
|
||||
rc_tracking = ["backtrace"]
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
pub mod metal;
|
||||
pub mod xorgng;
|
||||
pub mod x;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ use std::rc::Rc;
|
|||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XorgngBackendError {
|
||||
pub enum XBackendError {
|
||||
#[error("Could not connect to the X server")]
|
||||
CannotConnect(#[source] XconError),
|
||||
#[error("Could not enable XInput")]
|
||||
|
|
@ -90,38 +90,38 @@ pub enum XorgngBackendError {
|
|||
QueryDevice(#[source] XconError),
|
||||
}
|
||||
|
||||
pub struct XorgngBackend {
|
||||
_data: Rc<XorgngBackendData>,
|
||||
pub struct XBackend {
|
||||
_data: Rc<XBackendData>,
|
||||
_events: SpawnedFuture<()>,
|
||||
_present: SpawnedFuture<()>,
|
||||
_grab: SpawnedFuture<()>,
|
||||
}
|
||||
|
||||
impl Backend for XorgngBackend {
|
||||
impl Backend for XBackend {
|
||||
fn switch_to(&self, _vtnr: u32) {
|
||||
log::error!("Xorg backend cannot switch vts");
|
||||
log::error!("X backend cannot switch vts");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct XorgngBackendData {
|
||||
struct XBackendData {
|
||||
state: Rc<State>,
|
||||
c: Rc<Xcon>,
|
||||
outputs: CopyHashMap<u32, Rc<XorgOutput>>,
|
||||
seats: CopyHashMap<u16, Rc<XorgSeat>>,
|
||||
mouse_seats: CopyHashMap<u16, Rc<XorgSeat>>,
|
||||
outputs: CopyHashMap<u32, Rc<XOutput>>,
|
||||
seats: CopyHashMap<u16, Rc<XSeat>>,
|
||||
mouse_seats: CopyHashMap<u16, Rc<XSeat>>,
|
||||
ctx: Rc<RenderContext>,
|
||||
gbm: GbmDevice,
|
||||
cursor: u32,
|
||||
root: u32,
|
||||
scheduled_present: AsyncQueue<Rc<XorgOutput>>,
|
||||
grab_requests: AsyncQueue<(Rc<XorgSeat>, bool)>,
|
||||
scheduled_present: AsyncQueue<Rc<XOutput>>,
|
||||
grab_requests: AsyncQueue<(Rc<XSeat>, bool)>,
|
||||
}
|
||||
|
||||
impl XorgngBackend {
|
||||
pub async fn run(state: &Rc<State>) -> Result<Rc<Self>, XorgngBackendError> {
|
||||
impl XBackend {
|
||||
pub async fn run(state: &Rc<State>) -> Result<Rc<Self>, XBackendError> {
|
||||
let c = match Xcon::connect(state.eng.clone()).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(XorgngBackendError::CannotConnect(e)),
|
||||
Err(e) => return Err(XBackendError::CannotConnect(e)),
|
||||
};
|
||||
if let Err(e) = c
|
||||
.call(&XiQueryVersion {
|
||||
|
|
@ -130,7 +130,7 @@ impl XorgngBackend {
|
|||
})
|
||||
.await
|
||||
{
|
||||
return Err(XorgngBackendError::EnableXinput(e));
|
||||
return Err(XBackendError::EnableXinput(e));
|
||||
}
|
||||
if let Err(e) = c
|
||||
.call(&Dri3QueryVersion {
|
||||
|
|
@ -139,7 +139,7 @@ impl XorgngBackend {
|
|||
})
|
||||
.await
|
||||
{
|
||||
return Err(XorgngBackendError::EnableDri3(e));
|
||||
return Err(XBackendError::EnableDri3(e));
|
||||
}
|
||||
if let Err(e) = c
|
||||
.call(&PresentQueryVersion {
|
||||
|
|
@ -148,7 +148,7 @@ impl XorgngBackend {
|
|||
})
|
||||
.await
|
||||
{
|
||||
return Err(XorgngBackendError::EnablePresent(e));
|
||||
return Err(XBackendError::EnablePresent(e));
|
||||
}
|
||||
if let Err(e) = c
|
||||
.call(&XkbUseExtension {
|
||||
|
|
@ -157,7 +157,7 @@ impl XorgngBackend {
|
|||
})
|
||||
.await
|
||||
{
|
||||
return Err(XorgngBackendError::EnableXkb(e));
|
||||
return Err(XBackendError::EnableXkb(e));
|
||||
}
|
||||
let root = c.setup().screens[0].root;
|
||||
let drm = {
|
||||
|
|
@ -169,13 +169,13 @@ impl XorgngBackend {
|
|||
.await;
|
||||
match res {
|
||||
Ok(r) => Drm::reopen(r.get().device_fd.raw(), false)?,
|
||||
Err(e) => return Err(XorgngBackendError::DriOpen(e)),
|
||||
Err(e) => return Err(XBackendError::DriOpen(e)),
|
||||
}
|
||||
};
|
||||
let gbm = GbmDevice::new(&drm)?;
|
||||
let ctx = match RenderContext::from_drm_device(&drm) {
|
||||
Ok(r) => Rc::new(r),
|
||||
Err(e) => return Err(XorgngBackendError::CreateEgl(e)),
|
||||
Err(e) => return Err(XBackendError::CreateEgl(e)),
|
||||
};
|
||||
let cursor = {
|
||||
let cp = CreatePixmap {
|
||||
|
|
@ -186,7 +186,7 @@ impl XorgngBackend {
|
|||
height: 1,
|
||||
};
|
||||
if let Err(e) = c.call(&cp).await {
|
||||
return Err(XorgngBackendError::CreatePixmap(e));
|
||||
return Err(XBackendError::CreatePixmap(e));
|
||||
}
|
||||
let cc = CreateCursor {
|
||||
cid: c.generate_id()?,
|
||||
|
|
@ -202,7 +202,7 @@ impl XorgngBackend {
|
|||
y: 0,
|
||||
};
|
||||
if let Err(e) = c.call(&cc).await {
|
||||
return Err(XorgngBackendError::CreateCursor(e));
|
||||
return Err(XBackendError::CreateCursor(e));
|
||||
}
|
||||
c.call(&FreePixmap { pixmap: cp.pid });
|
||||
cc.cid
|
||||
|
|
@ -216,11 +216,11 @@ impl XorgngBackend {
|
|||
}]),
|
||||
};
|
||||
if let Err(e) = c.call(&se).await {
|
||||
return Err(XorgngBackendError::SelectHierarchyEvents(e));
|
||||
return Err(XBackendError::SelectHierarchyEvents(e));
|
||||
}
|
||||
}
|
||||
|
||||
let data = Rc::new(XorgngBackendData {
|
||||
let data = Rc::new(XBackendData {
|
||||
state: state.clone(),
|
||||
c,
|
||||
outputs: Default::default(),
|
||||
|
|
@ -252,7 +252,7 @@ impl XorgngBackend {
|
|||
}
|
||||
}
|
||||
|
||||
impl XorgngBackendData {
|
||||
impl XBackendData {
|
||||
async fn event_handler(self: Rc<Self>) {
|
||||
loop {
|
||||
let event = self.c.event().await;
|
||||
|
|
@ -281,7 +281,7 @@ impl XorgngBackendData {
|
|||
}
|
||||
}
|
||||
|
||||
async fn handle_grab_request(&self, dev: &XorgSeat, grab: bool) {
|
||||
async fn handle_grab_request(&self, dev: &XSeat, grab: bool) {
|
||||
if grab {
|
||||
let xg = XiGrabDevice {
|
||||
window: self.root,
|
||||
|
|
@ -320,7 +320,7 @@ impl XorgngBackendData {
|
|||
window: u32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) -> Result<[XorgImage; 2], XorgngBackendError> {
|
||||
) -> Result<[XImage; 2], XBackendError> {
|
||||
let format = ModifiedFormat {
|
||||
format: XRGB8888,
|
||||
modifier: INVALID_MODIFIER,
|
||||
|
|
@ -336,7 +336,7 @@ impl XorgngBackendData {
|
|||
let size = plane.stride * dma.height as u32;
|
||||
let fb = match self.ctx.dmabuf_fb(dma) {
|
||||
Ok(f) => f,
|
||||
Err(e) => return Err(XorgngBackendError::CreateFramebuffer(e)),
|
||||
Err(e) => return Err(XBackendError::CreateFramebuffer(e)),
|
||||
};
|
||||
let pixmap = {
|
||||
let pfb = Dri3PixmapFromBuffer {
|
||||
|
|
@ -351,11 +351,11 @@ impl XorgngBackendData {
|
|||
pixmap_fd: plane.fd.clone(),
|
||||
};
|
||||
if let Err(e) = self.c.call(&pfb).await {
|
||||
return Err(XorgngBackendError::ImportBuffer(e));
|
||||
return Err(XBackendError::ImportBuffer(e));
|
||||
}
|
||||
pfb.pixmap
|
||||
};
|
||||
images[i] = Some(XorgImage {
|
||||
images[i] = Some(XImage {
|
||||
pixmap: Cell::new(pixmap),
|
||||
fb: CloneCell::new(fb),
|
||||
idle: Cell::new(true),
|
||||
|
|
@ -366,7 +366,7 @@ impl XorgngBackendData {
|
|||
Ok([images[0].take().unwrap(), images[1].take().unwrap()])
|
||||
}
|
||||
|
||||
async fn add_output(self: &Rc<Self>) -> Result<(), XorgngBackendError> {
|
||||
async fn add_output(self: &Rc<Self>) -> Result<(), XBackendError> {
|
||||
const WIDTH: i32 = 800;
|
||||
const HEIGHT: i32 = 600;
|
||||
let window_id = {
|
||||
|
|
@ -384,12 +384,12 @@ impl XorgngBackendData {
|
|||
values: Default::default(),
|
||||
};
|
||||
if let Err(e) = self.c.call(&cw).await {
|
||||
return Err(XorgngBackendError::CreateWindow(e));
|
||||
return Err(XBackendError::CreateWindow(e));
|
||||
}
|
||||
cw.wid
|
||||
};
|
||||
let images = self.create_images(window_id, WIDTH, HEIGHT).await?;
|
||||
let output = Rc::new(XorgOutput {
|
||||
let output = Rc::new(XOutput {
|
||||
id: self.state.output_ids.next(),
|
||||
_backend: self.clone(),
|
||||
window: window_id,
|
||||
|
|
@ -413,7 +413,7 @@ impl XorgngBackendData {
|
|||
data: class.as_bytes(),
|
||||
};
|
||||
if let Err(e) = self.c.call(&cp).await {
|
||||
return Err(XorgngBackendError::WmClass(e));
|
||||
return Err(XBackendError::WmClass(e));
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -430,11 +430,11 @@ impl XorgngBackendData {
|
|||
},
|
||||
};
|
||||
if let Err(e) = self.c.call(&cwa).await {
|
||||
return Err(XorgngBackendError::WindowEvents(e));
|
||||
return Err(XBackendError::WindowEvents(e));
|
||||
}
|
||||
}
|
||||
if let Err(e) = self.c.call(&MapWindow { window: window_id }).await {
|
||||
return Err(XorgngBackendError::MapWindow(e));
|
||||
return Err(XBackendError::MapWindow(e));
|
||||
}
|
||||
{
|
||||
let mask = 0
|
||||
|
|
@ -459,7 +459,7 @@ impl XorgngBackendData {
|
|||
masks: Cow::Borrowed(&mask[..]),
|
||||
};
|
||||
if let Err(e) = self.c.call(&xs).await {
|
||||
return Err(XorgngBackendError::CannotSelectInputEvents(e));
|
||||
return Err(XBackendError::CannotSelectInputEvents(e));
|
||||
}
|
||||
}
|
||||
{
|
||||
|
|
@ -470,7 +470,7 @@ impl XorgngBackendData {
|
|||
event_mask: mask,
|
||||
};
|
||||
if let Err(e) = self.c.call(&si).await {
|
||||
return Err(XorgngBackendError::CannotSelectPresentEvents(e));
|
||||
return Err(XBackendError::CannotSelectPresentEvents(e));
|
||||
}
|
||||
}
|
||||
self.outputs.set(window_id, output.clone());
|
||||
|
|
@ -481,10 +481,10 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn query_devices(self: &Rc<Self>, deviceid: u16) -> Result<(), XorgngBackendError> {
|
||||
async fn query_devices(self: &Rc<Self>, deviceid: u16) -> Result<(), XBackendError> {
|
||||
let reply = match self.c.call(&XiQueryDevice { deviceid }).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => return Err(XorgngBackendError::QueryDevice(e)),
|
||||
Err(e) => return Err(XBackendError::QueryDevice(e)),
|
||||
};
|
||||
for dev in reply.get().infos.iter() {
|
||||
self.handle_input_device(dev).await;
|
||||
|
|
@ -517,7 +517,7 @@ impl XorgngBackendData {
|
|||
ErrorFmt(e),
|
||||
);
|
||||
}
|
||||
let seat = Rc::new(XorgSeat {
|
||||
let seat = Rc::new(XSeat {
|
||||
kb_id: self.state.input_device_ids.next(),
|
||||
mouse_id: self.state.input_device_ids.next(),
|
||||
backend: self.clone(),
|
||||
|
|
@ -535,17 +535,17 @@ impl XorgngBackendData {
|
|||
self.mouse_seats.set(info.attachment, seat.clone());
|
||||
self.state
|
||||
.backend_events
|
||||
.push(BackendEvent::NewInputDevice(Rc::new(XorgSeatMouse(
|
||||
.push(BackendEvent::NewInputDevice(Rc::new(XSeatMouse(
|
||||
seat.clone(),
|
||||
))));
|
||||
self.state
|
||||
.backend_events
|
||||
.push(BackendEvent::NewInputDevice(Rc::new(XorgSeatKeyboard(
|
||||
.push(BackendEvent::NewInputDevice(Rc::new(XSeatKeyboard(
|
||||
seat.clone(),
|
||||
))));
|
||||
}
|
||||
|
||||
async fn handle_event(self: &Rc<Self>, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
async fn handle_event(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
|
||||
match event.ext() {
|
||||
Some(ext) => self.handle_ext_event(ext, event).await,
|
||||
_ => self.handle_core_event(event).await,
|
||||
|
|
@ -556,7 +556,7 @@ impl XorgngBackendData {
|
|||
self: &Rc<Self>,
|
||||
ext: Extension,
|
||||
event: &Event,
|
||||
) -> Result<(), XorgngBackendError> {
|
||||
) -> Result<(), XBackendError> {
|
||||
match ext {
|
||||
Extension::Present => self.handle_present_event(event),
|
||||
Extension::XInputExtension => self.handle_input_event(event).await,
|
||||
|
|
@ -564,7 +564,7 @@ impl XorgngBackendData {
|
|||
}
|
||||
}
|
||||
|
||||
async fn handle_core_event(self: &Rc<Self>, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
async fn handle_core_event(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
|
||||
match event.code() {
|
||||
ConfigureNotify::OPCODE => self.handle_configure(event).await,
|
||||
DestroyNotify::OPCODE => self.handle_destroy(event),
|
||||
|
|
@ -572,7 +572,7 @@ impl XorgngBackendData {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_present_event(self: &Rc<Self>, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
fn handle_present_event(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
|
||||
match event.code() {
|
||||
PresentCompleteNotify::OPCODE => self.handle_present_complete(event)?,
|
||||
PresentIdleNotify::OPCODE => self.handle_present_idle(event)?,
|
||||
|
|
@ -581,7 +581,7 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_present_complete(self: &Rc<Self>, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
fn handle_present_complete(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
|
||||
let event: PresentCompleteNotify = event.parse()?;
|
||||
let window = event.window;
|
||||
let output = match self.outputs.get(&window) {
|
||||
|
|
@ -598,7 +598,7 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_present_idle(self: &Rc<Self>, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
fn handle_present_idle(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
|
||||
let event: PresentIdleNotify = event.parse()?;
|
||||
let output = match self.outputs.get(&event.window) {
|
||||
Some(o) => o,
|
||||
|
|
@ -615,11 +615,11 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn schedule_present(&self, output: &Rc<XorgOutput>) {
|
||||
fn schedule_present(&self, output: &Rc<XOutput>) {
|
||||
self.scheduled_present.push(output.clone());
|
||||
}
|
||||
|
||||
async fn present(&self, output: &Rc<XorgOutput>) {
|
||||
async fn present(&self, output: &Rc<XOutput>) {
|
||||
if output.removed.get() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -657,7 +657,7 @@ impl XorgngBackendData {
|
|||
image.last_serial.set(serial);
|
||||
}
|
||||
|
||||
async fn handle_input_event(self: &Rc<Self>, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
async fn handle_input_event(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
|
||||
match event.code() {
|
||||
XiMotion::OPCODE => self.handle_input_motion(event),
|
||||
XiEnter::OPCODE => self.handle_input_enter(event),
|
||||
|
|
@ -674,7 +674,7 @@ impl XorgngBackendData {
|
|||
self: &Rc<Self>,
|
||||
event: &Event,
|
||||
state: KeyState,
|
||||
) -> Result<(), XorgngBackendError> {
|
||||
) -> Result<(), XBackendError> {
|
||||
let event: XiButtonPress = event.parse()?;
|
||||
if let Some(seat) = self.mouse_seats.get(&event.deviceid) {
|
||||
let button = event.detail;
|
||||
|
|
@ -712,7 +712,7 @@ impl XorgngBackendData {
|
|||
self: &Rc<Self>,
|
||||
event: &Event,
|
||||
state: KeyState,
|
||||
) -> Result<(), XorgngBackendError> {
|
||||
) -> Result<(), XBackendError> {
|
||||
let event: XiKeyPress = event.parse()?;
|
||||
if let Some(seat) = self.seats.get(&event.deviceid) {
|
||||
seat.kb_event(InputEvent::Key(event.detail - 8, state));
|
||||
|
|
@ -720,15 +720,12 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_input_hierarchy(
|
||||
self: &Rc<Self>,
|
||||
event: &Event,
|
||||
) -> Result<(), XorgngBackendError> {
|
||||
async fn handle_input_hierarchy(self: &Rc<Self>, event: &Event) -> Result<(), XBackendError> {
|
||||
let event: XiHierarchy = event.parse()?;
|
||||
for info in event.infos.iter() {
|
||||
if info.flags & INPUT_HIERARCHY_MASK_MASTER_ADDED != 0 {
|
||||
if let Err(e) = self.query_devices(info.deviceid).await {
|
||||
log::error!("Could not query device {}: {:#}", info.deviceid, e);
|
||||
log::error!("Could not query device {}: {}", info.deviceid, ErrorFmt(e));
|
||||
}
|
||||
} else if info.flags & INPUT_HIERARCHY_MASK_MASTER_REMOVED != 0 {
|
||||
self.mouse_seats.remove(&info.attachment);
|
||||
|
|
@ -742,7 +739,7 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_input_enter(&self, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
fn handle_input_enter(&self, event: &Event) -> Result<(), XBackendError> {
|
||||
let event: XiEnter = event.parse()?;
|
||||
if let (Some(win), Some(seat)) = (
|
||||
self.outputs.get(&event.event),
|
||||
|
|
@ -757,7 +754,7 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_input_motion(&self, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
fn handle_input_motion(&self, event: &Event) -> Result<(), XBackendError> {
|
||||
let event: XiMotion = event.parse()?;
|
||||
let (win, seat) = match (
|
||||
self.outputs.get(&event.event),
|
||||
|
|
@ -774,7 +771,7 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_destroy(&self, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
fn handle_destroy(&self, event: &Event) -> Result<(), XBackendError> {
|
||||
self.state.el.stop();
|
||||
let event: DestroyNotify = event.parse()?;
|
||||
let output = match self.outputs.remove(&event.event) {
|
||||
|
|
@ -786,7 +783,7 @@ impl XorgngBackendData {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_configure(&self, event: &Event) -> Result<(), XorgngBackendError> {
|
||||
async fn handle_configure(&self, event: &Event) -> Result<(), XBackendError> {
|
||||
let event: ConfigureNotify = event.parse()?;
|
||||
let output = match self.outputs.get(&event.event) {
|
||||
Some(o) => o,
|
||||
|
|
@ -812,9 +809,9 @@ impl XorgngBackendData {
|
|||
}
|
||||
}
|
||||
|
||||
struct XorgOutput {
|
||||
struct XOutput {
|
||||
id: OutputId,
|
||||
_backend: Rc<XorgngBackendData>,
|
||||
_backend: Rc<XBackendData>,
|
||||
window: u32,
|
||||
removed: Cell<bool>,
|
||||
width: Cell<i32>,
|
||||
|
|
@ -822,11 +819,11 @@ struct XorgOutput {
|
|||
serial: NumCell<u32>,
|
||||
next_msc: Cell<u64>,
|
||||
next_image: NumCell<usize>,
|
||||
images: [XorgImage; 2],
|
||||
images: [XImage; 2],
|
||||
cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||
}
|
||||
|
||||
struct XorgImage {
|
||||
struct XImage {
|
||||
pixmap: Cell<u32>,
|
||||
fb: CloneCell<Rc<Framebuffer>>,
|
||||
idle: Cell<bool>,
|
||||
|
|
@ -834,7 +831,7 @@ struct XorgImage {
|
|||
last_serial: Cell<u32>,
|
||||
}
|
||||
|
||||
impl XorgOutput {
|
||||
impl XOutput {
|
||||
fn changed(&self) {
|
||||
if let Some(cb) = self.cb.get() {
|
||||
cb();
|
||||
|
|
@ -842,7 +839,7 @@ impl XorgOutput {
|
|||
}
|
||||
}
|
||||
|
||||
impl Output for XorgOutput {
|
||||
impl Output for XOutput {
|
||||
fn id(&self) -> OutputId {
|
||||
self.id
|
||||
}
|
||||
|
|
@ -864,10 +861,10 @@ impl Output for XorgOutput {
|
|||
}
|
||||
}
|
||||
|
||||
struct XorgSeat {
|
||||
struct XSeat {
|
||||
kb_id: InputDeviceId,
|
||||
mouse_id: InputDeviceId,
|
||||
backend: Rc<XorgngBackendData>,
|
||||
backend: Rc<XBackendData>,
|
||||
kb: u16,
|
||||
mouse: u16,
|
||||
removed: Cell<bool>,
|
||||
|
|
@ -878,11 +875,11 @@ struct XorgSeat {
|
|||
button_map: CopyHashMap<u32, u32>,
|
||||
}
|
||||
|
||||
struct XorgSeatKeyboard(Rc<XorgSeat>);
|
||||
struct XSeatKeyboard(Rc<XSeat>);
|
||||
|
||||
struct XorgSeatMouse(Rc<XorgSeat>);
|
||||
struct XSeatMouse(Rc<XSeat>);
|
||||
|
||||
impl XorgSeat {
|
||||
impl XSeat {
|
||||
fn kb_changed(&self) {
|
||||
if let Some(cb) = self.kb_cb.get() {
|
||||
cb();
|
||||
|
|
@ -927,7 +924,7 @@ impl XorgSeat {
|
|||
}
|
||||
}
|
||||
|
||||
impl InputDevice for XorgSeatKeyboard {
|
||||
impl InputDevice for XSeatKeyboard {
|
||||
fn id(&self) -> InputDeviceId {
|
||||
self.0.kb_id
|
||||
}
|
||||
|
|
@ -949,7 +946,7 @@ impl InputDevice for XorgSeatKeyboard {
|
|||
}
|
||||
}
|
||||
|
||||
impl InputDevice for XorgSeatMouse {
|
||||
impl InputDevice for XSeatMouse {
|
||||
fn id(&self) -> InputDeviceId {
|
||||
self.0.mouse_id
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ use crate::object::ObjectId;
|
|||
use crate::utils::buffd::{BufFdIn, BufFdOut, MsgParser};
|
||||
use crate::utils::vec_ext::VecExt;
|
||||
use crate::{ErrorFmt, Phase};
|
||||
use futures::{select, FutureExt};
|
||||
use futures_util::{select, FutureExt};
|
||||
use std::collections::VecDeque;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ impl ServerCursors {
|
|||
|
||||
pub struct ServerCursorTemplate {
|
||||
var: ServerCursorTemplateVariant,
|
||||
pub xcursor: Vec<XCursorImage>,
|
||||
}
|
||||
|
||||
enum ServerCursorTemplateVariant {
|
||||
|
|
@ -100,18 +101,19 @@ impl ServerCursorTemplate {
|
|||
ctx: &Rc<RenderContext>,
|
||||
) -> Result<Self, CursorError> {
|
||||
match open_cursor(name, theme, size, paths) {
|
||||
Ok(c) => {
|
||||
if c.len() == 1 {
|
||||
let c = &c[0];
|
||||
Ok(cs) => {
|
||||
if cs.len() == 1 {
|
||||
let c = &cs[0];
|
||||
let cursor = CursorImage::from_bytes(
|
||||
ctx, &c.pixels, 0, c.width, c.height, c.xhot, c.yhot,
|
||||
)?;
|
||||
Ok(ServerCursorTemplate {
|
||||
var: ServerCursorTemplateVariant::Static(Rc::new(cursor)),
|
||||
xcursor: cs,
|
||||
})
|
||||
} else {
|
||||
let mut images = vec![];
|
||||
for c in c {
|
||||
for c in &cs {
|
||||
let img = CursorImage::from_bytes(
|
||||
ctx,
|
||||
&c.pixels,
|
||||
|
|
@ -125,6 +127,7 @@ impl ServerCursorTemplate {
|
|||
}
|
||||
Ok(ServerCursorTemplate {
|
||||
var: ServerCursorTemplateVariant::Animated(Rc::new(images)),
|
||||
xcursor: cs,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -134,6 +137,7 @@ impl ServerCursorTemplate {
|
|||
let cursor = CursorImage::from_bytes(ctx, &empty, 0, 1, 1, 0, 0)?;
|
||||
Ok(ServerCursorTemplate {
|
||||
var: ServerCursorTemplateVariant::Static(Rc::new(cursor)),
|
||||
xcursor: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -427,13 +431,13 @@ pub enum CursorError {
|
|||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
struct XCursorImage {
|
||||
width: i32,
|
||||
height: i32,
|
||||
xhot: i32,
|
||||
yhot: i32,
|
||||
delay: u32,
|
||||
pixels: Vec<Cell<u8>>,
|
||||
pub struct XCursorImage {
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub xhot: i32,
|
||||
pub yhot: i32,
|
||||
pub delay: u32,
|
||||
pub pixels: Vec<Cell<u8>>,
|
||||
}
|
||||
|
||||
impl Debug for XCursorImage {
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ impl ForkerProxy {
|
|||
waiter: Cell::new(None),
|
||||
});
|
||||
self.pending_pidfds.set(id, Rc::downgrade(&handoff));
|
||||
futures::future::poll_fn(|ctx| {
|
||||
futures_util::future::poll_fn(|ctx| {
|
||||
if let Some(pidfd) = handoff.pidfd.take() {
|
||||
Poll::Ready(pidfd)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,17 +11,17 @@ use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode};
|
|||
use crate::utils::linkedlist::LinkedNode;
|
||||
use crate::utils::smallmap::SmallMap;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::wire_xcon::CreateNotify;
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
use crate::{AsyncQueue, CloneCell, State};
|
||||
use jay_config::Direction;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use x11rb::protocol::xproto::{CreateNotifyEvent, Window};
|
||||
|
||||
pub struct XwindowData {
|
||||
pub state: Rc<State>,
|
||||
pub window_id: Window,
|
||||
pub window_id: u32,
|
||||
pub override_redirect: bool,
|
||||
pub extents: Cell<Rect>,
|
||||
pub client: Rc<Client>,
|
||||
|
|
@ -44,7 +44,7 @@ pub struct Xwindow {
|
|||
}
|
||||
|
||||
impl XwindowData {
|
||||
pub fn new(state: &Rc<State>, event: &CreateNotifyEvent, client: &Rc<Client>) -> Self {
|
||||
pub fn new(state: &Rc<State>, event: &CreateNotify, client: &Rc<Client>) -> Self {
|
||||
let extents = Rect::new_sized(
|
||||
event.x as _,
|
||||
event.y as _,
|
||||
|
|
@ -56,7 +56,7 @@ impl XwindowData {
|
|||
Self {
|
||||
state: state.clone(),
|
||||
window_id: event.window,
|
||||
override_redirect: event.override_redirect,
|
||||
override_redirect: event.override_redirect != 0,
|
||||
extents: Cell::new(extents),
|
||||
client: client.clone(),
|
||||
surface_id: Cell::new(None),
|
||||
|
|
|
|||
|
|
@ -360,3 +360,40 @@ macro_rules! assert_align_eq {
|
|||
let _ = AssertEqAlign::<$t, $u>::VAL;
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! atom_manager {
|
||||
{
|
||||
$name:ident;
|
||||
$($field_name:ident,)*
|
||||
} => {
|
||||
#[allow(non_snake_case, dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct $name {
|
||||
$(
|
||||
$field_name: u32,
|
||||
)*
|
||||
}
|
||||
|
||||
impl $name {
|
||||
fn get(
|
||||
conn: &std::rc::Rc<crate::xcon::Xcon>,
|
||||
) -> impl std::future::Future<Output = Result<Self, crate::xcon::XconError>> {
|
||||
#![allow(non_snake_case)]
|
||||
use bstr::ByteSlice;
|
||||
$(
|
||||
let $field_name = conn.call(&InternAtom {
|
||||
only_if_exists: 0,
|
||||
name: stringify!($field_name).as_bytes().as_bstr(),
|
||||
});
|
||||
)*
|
||||
async move {
|
||||
Ok(Self {
|
||||
$(
|
||||
$field_name: $field_name.await?.get().atom,
|
||||
)*
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ mod object;
|
|||
mod pixman;
|
||||
mod rect;
|
||||
mod render;
|
||||
mod servermem;
|
||||
mod sighand;
|
||||
mod state;
|
||||
mod tasks;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@ use crate::render::gl::sys::GLint;
|
|||
use crate::render::gl::texture::GlTexture;
|
||||
use crate::render::renderer::framebuffer::Framebuffer;
|
||||
use crate::render::renderer::image::Image;
|
||||
use crate::render::renderer::RENDERDOC;
|
||||
use crate::render::{RenderError, Texture};
|
||||
use ahash::AHashMap;
|
||||
use renderdoc::{RenderDoc, V100};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::Cell;
|
||||
use std::ffi::CString;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
|
@ -42,8 +40,6 @@ pub struct RenderContext {
|
|||
|
||||
pub(super) render_node: Rc<CString>,
|
||||
|
||||
pub(super) renderdoc: Option<RefCell<RenderDoc<V100>>>,
|
||||
|
||||
pub(super) tex_prog: TexProg,
|
||||
pub(super) tex_alpha_prog: TexProg,
|
||||
|
||||
|
|
@ -104,12 +100,6 @@ impl RenderContext {
|
|||
fill_prog_pos: fill_prog.get_attrib_location(ustr!("pos")),
|
||||
fill_prog_color: fill_prog.get_uniform_location(ustr!("color")),
|
||||
fill_prog,
|
||||
|
||||
renderdoc: if RENDERDOC {
|
||||
Some(RefCell::new(RenderDoc::new().unwrap()))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use crate::render::sys::{glBlendFunc, GL_ONE, GL_ONE_MINUS_SRC_ALPHA};
|
|||
use crate::tree::Node;
|
||||
use crate::State;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct Framebuffer {
|
||||
|
|
@ -38,10 +37,6 @@ impl Framebuffer {
|
|||
|
||||
pub fn render(&self, node: &dyn Node, state: &State, cursor_rect: Option<Rect>) {
|
||||
let _ = self.ctx.ctx.with_current(|| {
|
||||
if let Some(rd) = &self.ctx.renderdoc {
|
||||
rd.borrow_mut()
|
||||
.start_frame_capture(ptr::null(), ptr::null());
|
||||
}
|
||||
unsafe {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo);
|
||||
glViewport(0, 0, self.gl.width, self.gl.height);
|
||||
|
|
@ -79,9 +74,6 @@ impl Framebuffer {
|
|||
}
|
||||
}
|
||||
}
|
||||
if let Some(rd) = &self.ctx.renderdoc {
|
||||
rd.borrow_mut().end_frame_capture(ptr::null(), ptr::null());
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,5 +9,3 @@ mod framebuffer;
|
|||
mod image;
|
||||
mod renderer;
|
||||
mod texture;
|
||||
|
||||
pub const RENDERDOC: bool = false;
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::ptr;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
use thiserror::Error;
|
||||
use uapi::{c, Errno, OwnedFd};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ServerMemError {
|
||||
#[error("memfd_create failed")]
|
||||
MemfdCreate(#[source] crate::utils::oserror::OsError),
|
||||
#[error("The provided size does not fit into off_t")]
|
||||
SizeOverflow,
|
||||
#[error("ftruncate failed")]
|
||||
Ftruncate(#[source] crate::utils::oserror::OsError),
|
||||
#[error("mmap failed")]
|
||||
MmapFailed(#[source] crate::utils::oserror::OsError),
|
||||
#[error("sealing failed")]
|
||||
Seal(#[source] crate::utils::oserror::OsError),
|
||||
}
|
||||
|
||||
pub struct ServerMem {
|
||||
fd: OwnedFd,
|
||||
mem: *const [Cell<u8>],
|
||||
}
|
||||
|
||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(1);
|
||||
|
||||
impl ServerMem {
|
||||
pub fn new(size: usize) -> Result<Self, ServerMemError> {
|
||||
let name = format!("servermem-{}", NEXT_ID.fetch_add(1, Relaxed));
|
||||
let fd = match uapi::memfd_create(name, c::MFD_CLOEXEC | c::MFD_ALLOW_SEALING) {
|
||||
Ok(f) => f,
|
||||
Err(e) => return Err(ServerMemError::MemfdCreate(e.into())),
|
||||
};
|
||||
let o_size = match size.try_into() {
|
||||
Ok(s) => s,
|
||||
_ => return Err(ServerMemError::SizeOverflow),
|
||||
};
|
||||
if let Err(e) = uapi::ftruncate(fd.raw(), o_size) {
|
||||
return Err(ServerMemError::Ftruncate(e.into()));
|
||||
}
|
||||
if let Err(e) =
|
||||
uapi::fcntl_add_seals(fd.raw(), c::F_SEAL_SHRINK | c::F_SEAL_GROW | c::F_SEAL_SEAL)
|
||||
{
|
||||
return Err(ServerMemError::Seal(e.into()));
|
||||
}
|
||||
let mem = unsafe {
|
||||
let res = c::mmap64(
|
||||
ptr::null_mut(),
|
||||
size,
|
||||
c::PROT_READ | c::PROT_WRITE,
|
||||
c::MAP_SHARED,
|
||||
fd.raw(),
|
||||
0,
|
||||
);
|
||||
if res == c::MAP_FAILED {
|
||||
return Err(ServerMemError::MmapFailed(Errno::default().into()));
|
||||
}
|
||||
std::slice::from_raw_parts(res as *mut Cell<u8>, size)
|
||||
};
|
||||
Ok(Self { fd, mem })
|
||||
}
|
||||
|
||||
pub fn access<T, F: FnOnce(&[Cell<u8>]) -> T>(&self, f: F) -> T {
|
||||
unsafe { f(&*self.mem) }
|
||||
}
|
||||
|
||||
pub fn fd(&self) -> i32 {
|
||||
self.fd.raw()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ServerMem {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
c::munmap(self.mem as *const _ as _, (*self.mem).len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::backends::xorgng::XorgngBackend;
|
||||
use crate::backends::x::XBackend;
|
||||
use crate::{metal, ErrorFmt, State};
|
||||
use std::future::pending;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -12,7 +12,7 @@ pub async fn start_backend(state: Rc<State>) {
|
|||
// }
|
||||
// Err(e) => e,
|
||||
// };
|
||||
let e = match XorgngBackend::run(&state).await {
|
||||
let e = match XBackend::run(&state).await {
|
||||
Ok(_) => pending().await,
|
||||
Err(e) => e,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::async_engine::{AsyncFd, Timeout};
|
||||
use crate::utils::buffd::{BufFdError, BUF_SIZE, CMSG_BUF_SIZE};
|
||||
use futures::future::Fuse;
|
||||
use futures::{select, FutureExt};
|
||||
use futures_util::future::Fuse;
|
||||
use futures_util::{select, FutureExt};
|
||||
use std::collections::VecDeque;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::rc::Rc;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use parking_lot::{Condvar, Mutex};
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use uapi::OwnedFd;
|
||||
|
||||
pub struct FdCloser {
|
||||
|
|
@ -18,15 +17,15 @@ impl FdCloser {
|
|||
let slf2 = slf.clone();
|
||||
std::thread::spawn(move || {
|
||||
let mut fds = vec![];
|
||||
let mut lock = slf2.fds.lock();
|
||||
let mut lock = slf2.fds.lock().unwrap();
|
||||
loop {
|
||||
mem::swap(&mut *lock, &mut fds);
|
||||
if fds.len() > 0 {
|
||||
drop(lock);
|
||||
fds.clear();
|
||||
lock = slf2.fds.lock();
|
||||
lock = slf2.fds.lock().unwrap();
|
||||
} else {
|
||||
slf2.cv.wait(&mut lock);
|
||||
lock = slf2.cv.wait(lock).unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -36,7 +35,7 @@ impl FdCloser {
|
|||
pub fn close(&self, fd: Rc<OwnedFd>) {
|
||||
match Rc::try_unwrap(fd) {
|
||||
Ok(fd) => {
|
||||
self.fds.lock().push(fd);
|
||||
self.fds.lock().unwrap().push(fd);
|
||||
self.cv.notify_all();
|
||||
}
|
||||
Err(_e) => {
|
||||
|
|
|
|||
31
src/xcon.rs
31
src/xcon.rs
|
|
@ -2,8 +2,10 @@ use crate::async_engine::SpawnedFuture;
|
|||
use crate::utils::bufio::{BufIo, BufIoError, BufIoMessage};
|
||||
use crate::utils::oserror::OsError;
|
||||
use crate::wire_xcon::{
|
||||
Extension, GetInputFocus, ListExtensions, QueryExtension, Setup, EXTENSIONS,
|
||||
Extension, GetInputFocus, ListExtensions, QueryExtension, RenderQueryPictFormats, Setup,
|
||||
EXTENSIONS,
|
||||
};
|
||||
use crate::xcon::consts::RENDER_PICT_TYPE_DIRECT;
|
||||
pub use crate::xcon::formatter::Formatter;
|
||||
use crate::xcon::incoming::handle_incoming;
|
||||
use crate::xcon::outgoing::handle_outgoing;
|
||||
|
|
@ -89,6 +91,10 @@ pub enum XconError {
|
|||
XidExhausted,
|
||||
#[error("Enum contains an unknown variant")]
|
||||
UnknownEnumVariant,
|
||||
#[error("Could not query the render pict formats")]
|
||||
QueryPictFormats(#[source] Box<XconError>),
|
||||
#[error("The server does not support the picture format for cursors")]
|
||||
CursorFormatNotSupported,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -444,6 +450,29 @@ impl Xcon {
|
|||
pub fn call<'a, T: Request<'a>>(self: &Rc<Self>, t: &T) -> AsyncReply<T::Reply> {
|
||||
self.data.call(t, &self.extensions)
|
||||
}
|
||||
|
||||
pub async fn find_cursor_format(self: &Rc<Self>) -> Result<u32, XconError> {
|
||||
let res = match self.call(&RenderQueryPictFormats {}).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => return Err(XconError::QueryPictFormats(Box::new(e))),
|
||||
};
|
||||
for format in res.get().formats.iter() {
|
||||
let valid = format.ty == RENDER_PICT_TYPE_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;
|
||||
if valid {
|
||||
return Ok(format.id);
|
||||
}
|
||||
}
|
||||
Err(XconError::CursorFormatNotSupported)
|
||||
}
|
||||
}
|
||||
|
||||
impl XconData {
|
||||
|
|
|
|||
|
|
@ -105,3 +105,9 @@ pub const GRAB_STATUS_FROZEN: u8 = 4;
|
|||
pub const IMAGE_FORMAT_XY_BITMAP: u8 = 0;
|
||||
pub const IMAGE_FORMAT_XY_PIXMAP: u8 = 1;
|
||||
pub const IMAGE_FORMAT_Z_PIXMAP: u8 = 2;
|
||||
|
||||
pub const COMPOSITE_REDIRECT_AUTOMATIC: u8 = 0;
|
||||
pub const COMPOSITE_REDIRECT_MANUAL: u8 = 1;
|
||||
|
||||
pub const RENDER_PICT_TYPE_INDEXED: u8 = 0;
|
||||
pub const RENDER_PICT_TYPE_DIRECT: u8 = 1;
|
||||
|
|
|
|||
|
|
@ -7,15 +7,16 @@ use crate::ifs::wl_surface::xwindow::Xwindow;
|
|||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::utils::tri::Try;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::xcon::XconError;
|
||||
use crate::xwayland::xsocket::allocate_socket;
|
||||
use crate::xwayland::xwm::Wm;
|
||||
use crate::{AsyncError, AsyncQueue, ErrorFmt, ForkerError, State};
|
||||
use bstr::ByteSlice;
|
||||
use std::error::Error;
|
||||
use std::num::ParseIntError;
|
||||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use uapi::{c, pipe2, Errno, OwnedFd};
|
||||
use crate::utils::oserror::OsError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum XWaylandError {
|
||||
|
|
@ -38,43 +39,39 @@ enum XWaylandError {
|
|||
#[error("The socket is already in use")]
|
||||
AlreadyInUse,
|
||||
#[error("Could not bind the socket to an address")]
|
||||
BindFailed(#[source] crate::utils::oserror::OsError),
|
||||
BindFailed(#[source] OsError),
|
||||
#[error("All X displays in the range 0..1000 are already in use")]
|
||||
AddressesInUse,
|
||||
#[error("The async engine returned an error")]
|
||||
AsyncError(#[from] AsyncError),
|
||||
#[error("pipe(2) failed")]
|
||||
Pipe(#[source] crate::utils::oserror::OsError),
|
||||
#[error("dupfd(2) failed")]
|
||||
Dupfd(#[source] crate::utils::oserror::OsError),
|
||||
Pipe(#[source] OsError),
|
||||
#[error("socketpair(2) failed")]
|
||||
Socketpair(#[source] crate::utils::oserror::OsError),
|
||||
Socketpair(#[source] OsError),
|
||||
#[error("Could not start Xwayland")]
|
||||
ExecFailed(#[source] ForkerError),
|
||||
#[error("Could not load the atoms")]
|
||||
LoadAtoms(#[source] Box<dyn Error>),
|
||||
LoadAtoms(#[source] XconError),
|
||||
#[error("Could not connect to Xwayland")]
|
||||
Connect(#[source] Box<dyn Error>),
|
||||
Connect(#[source] XconError),
|
||||
#[error("Could not create a window manager")]
|
||||
CreateWm(#[source] Box<Self>),
|
||||
#[error("Could not select the root events")]
|
||||
SelectRootEvents(#[source] Box<dyn Error>),
|
||||
SelectRootEvents(#[source] XconError),
|
||||
#[error("Could not create the WM window")]
|
||||
CreateXWindow(#[source] Box<dyn Error>),
|
||||
CreateXWindow(#[source] XconError),
|
||||
#[error("Could not acquire a selection")]
|
||||
SelectionOwner(#[source] Box<dyn Error>),
|
||||
#[error("Could not load the resource database")]
|
||||
ResourceDatabase(#[source] Box<dyn Error>),
|
||||
#[error("Could not acquire a cursor handle")]
|
||||
CursorHandle(#[source] Box<dyn Error>),
|
||||
#[error("Could not load the default cursor")]
|
||||
LoadCursor(#[source] Box<dyn Error>),
|
||||
SelectionOwner(#[source] XconError),
|
||||
#[error("Could not set the cursor of the root window")]
|
||||
SetCursor(#[source] Box<dyn Error>),
|
||||
SetCursor(#[source] XconError),
|
||||
#[error("composite_redirect_subwindows failed")]
|
||||
CompositeRedirectSubwindows(#[source] Box<dyn Error>),
|
||||
CompositeRedirectSubwindows(#[source] XconError),
|
||||
#[error("Could not spawn the Xwayland client")]
|
||||
SpawnClient(#[source] ClientError),
|
||||
#[error("Could not map a window")]
|
||||
MapWindow(#[source] XconError),
|
||||
#[error("An unspecified XconError occurred")]
|
||||
XconError(#[from] XconError),
|
||||
}
|
||||
|
||||
pub async fn manage(state: Rc<State>) {
|
||||
|
|
@ -131,7 +128,7 @@ async fn run(
|
|||
Ok(p) => p,
|
||||
Err(e) => return Err(XWaylandError::Pipe(e.into())),
|
||||
};
|
||||
let wm = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC, 0);
|
||||
let wm = uapi::socketpair(c::AF_UNIX, c::SOCK_STREAM | c::SOCK_CLOEXEC | c::SOCK_NONBLOCK, 0);
|
||||
let (wm1, wm2) = match wm {
|
||||
Ok(w) => w,
|
||||
Err(e) => return Err(XWaylandError::Socketpair(e.into())),
|
||||
|
|
@ -169,7 +166,7 @@ async fn run(
|
|||
Err(e) => return Err(XWaylandError::SpawnClient(e)),
|
||||
};
|
||||
state.eng.fd(&Rc::new(dfdread))?.readable().await?;
|
||||
let wm = match Wm::get(state, client, wm1, queue.clone()) {
|
||||
let wm = match Wm::get(state, client, wm1, queue.clone()).await {
|
||||
Ok(w) => w,
|
||||
Err(e) => return Err(XWaylandError::CreateWm(Box::new(e))),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,34 +1,32 @@
|
|||
use crate::async_engine::AsyncFd;
|
||||
use crate::client::Client;
|
||||
use crate::ifs::wl_surface::xwindow::{Xwindow, XwindowData};
|
||||
use crate::ifs::wl_surface::WlSurface;
|
||||
use crate::rect::Rect;
|
||||
use crate::wire::WlSurfaceId;
|
||||
use crate::wire_xcon::{
|
||||
ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows, ConfigureNotify,
|
||||
ConfigureRequest, ConfigureWindow, ConfigureWindowValues, CreateGC, CreateNotify, CreatePixmap,
|
||||
CreateWindow, CreateWindowValues, DestroyNotify, FreeGC, FreePixmap, InternAtom,
|
||||
MapRequest, MapWindow, PutImage, RenderCreateCursor, RenderCreatePicture,
|
||||
SetSelectionOwner,
|
||||
};
|
||||
use crate::xcon::consts::{
|
||||
COMPOSITE_REDIRECT_MANUAL, EVENT_MASK_PROPERTY_CHANGE, EVENT_MASK_SUBSTRUCTURE_NOTIFY,
|
||||
EVENT_MASK_SUBSTRUCTURE_REDIRECT, IMAGE_FORMAT_Z_PIXMAP,
|
||||
WINDOW_CLASS_INPUT_OUTPUT,
|
||||
};
|
||||
use crate::xcon::{Event, XEvent, Xcon};
|
||||
use crate::xwayland::{XWaylandError, XWaylandEvent};
|
||||
use crate::{AsyncQueue, ErrorFmt, State};
|
||||
use ahash::AHashMap;
|
||||
use futures::FutureExt;
|
||||
use std::error::Error;
|
||||
use std::os::unix::io::FromRawFd;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use futures_util::{FutureExt, select};
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use uapi::OwnedFd;
|
||||
use x11rb::atom_manager;
|
||||
use x11rb::connection::Connection;
|
||||
use x11rb::cursor::Handle;
|
||||
use x11rb::errors::ConnectionError;
|
||||
use x11rb::protocol::composite::{ConnectionExt as _, Redirect};
|
||||
use x11rb::protocol::xproto::{
|
||||
ChangeWindowAttributesAux, ClientMessageEvent, ConfigureNotifyEvent, ConfigureRequestEvent,
|
||||
ConfigureWindowAux, ConnectionExt as _, CreateNotifyEvent, CreateWindowAux, DestroyNotifyEvent,
|
||||
EventMask, MapRequestEvent, Window, WindowClass,
|
||||
};
|
||||
use x11rb::protocol::Event;
|
||||
use x11rb::resource_manager::Database;
|
||||
use x11rb::rust_connection::{DefaultStream, RustConnection};
|
||||
|
||||
atom_manager! {
|
||||
pub Atoms: AtomsCookie {
|
||||
Atoms;
|
||||
|
||||
WL_SURFACE_ID,
|
||||
WM_DELETE_WINDOW,
|
||||
WM_PROTOCOLS,
|
||||
|
|
@ -97,20 +95,16 @@ atom_manager! {
|
|||
DND_ACTION_PRIVATE,
|
||||
NET_CLIENT_LIST,
|
||||
NET_CLIENT_LIST_STACKING,
|
||||
}
|
||||
}
|
||||
|
||||
type Res<T> = Result<T, Box<dyn Error>>;
|
||||
|
||||
pub struct Wm {
|
||||
state: Rc<State>,
|
||||
c: RustConnection,
|
||||
c: Rc<Xcon>,
|
||||
atoms: Atoms,
|
||||
socket: AsyncFd,
|
||||
_root: Window,
|
||||
_xwin: Window,
|
||||
_root: u32,
|
||||
_xwin: u32,
|
||||
client: Rc<Client>,
|
||||
windows: AHashMap<Window, Rc<XwindowData>>,
|
||||
windows: AHashMap<u32, Rc<XwindowData>>,
|
||||
windows_by_surface_id: AHashMap<WlSurfaceId, Rc<XwindowData>>,
|
||||
queue: Rc<AsyncQueue<XWaylandEvent>>,
|
||||
}
|
||||
|
|
@ -126,100 +120,167 @@ impl Drop for Wm {
|
|||
}
|
||||
|
||||
impl Wm {
|
||||
pub(super) fn get(
|
||||
pub(super) async fn get(
|
||||
state: &Rc<State>,
|
||||
client: Rc<Client>,
|
||||
socket: OwnedFd,
|
||||
queue: Rc<AsyncQueue<XWaylandEvent>>,
|
||||
) -> Result<Self, XWaylandError> {
|
||||
let socket_dup = match uapi::fcntl_dupfd_cloexec(socket.raw(), 0) {
|
||||
Ok(s) => state.eng.fd(&Rc::new(s))?,
|
||||
Err(e) => return Err(XWaylandError::Dupfd(e.into())),
|
||||
};
|
||||
let c = try {
|
||||
RustConnection::connect_to_stream(
|
||||
DefaultStream::from_unix_stream(unsafe {
|
||||
UnixStream::from_raw_fd(socket.unwrap())
|
||||
})?,
|
||||
0,
|
||||
)?
|
||||
};
|
||||
let c: RustConnection = match c {
|
||||
let c = match Xcon::connect_to_fd(&state.eng, &Rc::new(socket), &[], &[]).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(XWaylandError::Connect(e)),
|
||||
};
|
||||
let atoms: Atoms = match try { Atoms::new(&c)?.reply()? } {
|
||||
let atoms = match Atoms::get(&c).await {
|
||||
Ok(a) => a,
|
||||
Err(e) => return Err(XWaylandError::LoadAtoms(e)),
|
||||
};
|
||||
let root = c.setup().roots[0].root;
|
||||
let root = c.setup().screens[0].root;
|
||||
{
|
||||
let cwa = ChangeWindowAttributesAux::new().event_mask(
|
||||
EventMask::SUBSTRUCTURE_NOTIFY
|
||||
| EventMask::SUBSTRUCTURE_REDIRECT
|
||||
| EventMask::PROPERTY_CHANGE,
|
||||
);
|
||||
let res = try { c.change_window_attributes(root, &cwa)?.check()? };
|
||||
if let Err(e) = res {
|
||||
let events = 0
|
||||
| EVENT_MASK_SUBSTRUCTURE_NOTIFY
|
||||
| EVENT_MASK_SUBSTRUCTURE_REDIRECT
|
||||
| EVENT_MASK_PROPERTY_CHANGE;
|
||||
let cwa = ChangeWindowAttributes {
|
||||
window: root,
|
||||
values: CreateWindowValues {
|
||||
event_mask: Some(events),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
if let Err(e) = c.call(&cwa).await {
|
||||
return Err(XWaylandError::SelectRootEvents(e));
|
||||
}
|
||||
}
|
||||
{
|
||||
let res = try {
|
||||
c.composite_redirect_subwindows(root, Redirect::MANUAL)?
|
||||
.check()?
|
||||
let crs = CompositeRedirectSubwindows {
|
||||
window: root,
|
||||
update: COMPOSITE_REDIRECT_MANUAL,
|
||||
};
|
||||
if let Err(e) = res {
|
||||
if let Err(e) = c.call(&crs).await {
|
||||
return Err(XWaylandError::CompositeRedirectSubwindows(e));
|
||||
}
|
||||
}
|
||||
let xwin = c.generate_id().unwrap_or(0);
|
||||
{
|
||||
let res = try {
|
||||
c.create_window(
|
||||
0,
|
||||
xwin,
|
||||
root,
|
||||
0,
|
||||
0,
|
||||
10,
|
||||
10,
|
||||
0,
|
||||
WindowClass::INPUT_OUTPUT,
|
||||
0,
|
||||
&CreateWindowAux::new(),
|
||||
)?
|
||||
.check()?;
|
||||
let xwin = {
|
||||
let cw = CreateWindow {
|
||||
depth: 0,
|
||||
wid: c.generate_id()?,
|
||||
parent: root,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 10,
|
||||
border_width: 0,
|
||||
class: WINDOW_CLASS_INPUT_OUTPUT,
|
||||
visual: 0,
|
||||
values: Default::default(),
|
||||
};
|
||||
if let Err(e) = res {
|
||||
if let Err(e) = c.call(&cw).await {
|
||||
return Err(XWaylandError::CreateXWindow(e));
|
||||
}
|
||||
}
|
||||
{
|
||||
let res = try {
|
||||
c.set_selection_owner(xwin, atoms.WM_S0, 0u32)?.check()?;
|
||||
cw.wid
|
||||
};
|
||||
if let Err(e) = res {
|
||||
{
|
||||
let sso = SetSelectionOwner {
|
||||
owner: xwin,
|
||||
selection: atoms.WM_S0,
|
||||
time: 0,
|
||||
};
|
||||
if let Err(e) = c.call(&sso).await {
|
||||
return Err(XWaylandError::SelectionOwner(e));
|
||||
}
|
||||
}
|
||||
{
|
||||
let rdb = match Database::new_from_default(&c) {
|
||||
Ok(rdb) => rdb,
|
||||
Err(e) => return Err(XWaylandError::ResourceDatabase(e.into())),
|
||||
'set_root_cursor: {
|
||||
let cursor_format = c.find_cursor_format().await?;
|
||||
let cursors = match state.cursors.get() {
|
||||
Some(g) => g,
|
||||
_ => break 'set_root_cursor,
|
||||
};
|
||||
let handle: Res<Handle> = try { Handle::new(&c, 0, &rdb)?.reply()? };
|
||||
let handle = match handle {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Err(XWaylandError::CursorHandle(e)),
|
||||
let first = match cursors.default.xcursor.first() {
|
||||
Some(f) => f,
|
||||
_ => break 'set_root_cursor,
|
||||
};
|
||||
let cursor = match handle.load_cursor(&c, "left_ptr") {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(XWaylandError::LoadCursor(e.into())),
|
||||
let pixmap = c.generate_id()?;
|
||||
let gc = c.generate_id()?;
|
||||
let picture = c.generate_id()?;
|
||||
let cursor = c.generate_id()?;
|
||||
let create_pixmap = c.call(&CreatePixmap {
|
||||
depth: 32,
|
||||
pid: pixmap,
|
||||
drawable: root,
|
||||
width: first.width as _,
|
||||
height: first.height as _,
|
||||
});
|
||||
let create_gc = c.call(&CreateGC {
|
||||
cid: gc,
|
||||
drawable: pixmap,
|
||||
values: Default::default(),
|
||||
});
|
||||
let put_image = c.call(&PutImage {
|
||||
format: IMAGE_FORMAT_Z_PIXMAP,
|
||||
drawable: pixmap,
|
||||
gc,
|
||||
width: first.width as _,
|
||||
height: first.height as _,
|
||||
dst_x: 0,
|
||||
dst_y: 0,
|
||||
left_pad: 0,
|
||||
depth: 32,
|
||||
data: unsafe { mem::transmute(&first.pixels[..]) },
|
||||
});
|
||||
c.call(&FreeGC { gc });
|
||||
let create_picture = c.call(&RenderCreatePicture {
|
||||
pid: picture,
|
||||
drawable: pixmap,
|
||||
format: cursor_format,
|
||||
values: Default::default(),
|
||||
});
|
||||
c.call(&FreePixmap { pixmap });
|
||||
let create_cursor = c.call(&RenderCreateCursor {
|
||||
cid: cursor,
|
||||
source: picture,
|
||||
x: first.xhot as _,
|
||||
y: first.yhot as _,
|
||||
});
|
||||
if let Err(e) = create_pixmap.await {
|
||||
log::warn!(
|
||||
"Could not create a pixmap for the root cursor: {}",
|
||||
ErrorFmt(e)
|
||||
);
|
||||
break 'set_root_cursor;
|
||||
}
|
||||
if let Err(e) = create_gc.await {
|
||||
log::warn!(
|
||||
"Could not create a graphics context for the root cursor: {}",
|
||||
ErrorFmt(e)
|
||||
);
|
||||
break 'set_root_cursor;
|
||||
}
|
||||
if let Err(e) = put_image.await {
|
||||
log::warn!(
|
||||
"Could not upload the image for the root cursor: {}",
|
||||
ErrorFmt(e)
|
||||
);
|
||||
break 'set_root_cursor;
|
||||
}
|
||||
if let Err(e) = create_picture.await {
|
||||
log::warn!(
|
||||
"Could not create a picture for the root cursor: {}",
|
||||
ErrorFmt(e)
|
||||
);
|
||||
break 'set_root_cursor;
|
||||
}
|
||||
if let Err(e) = create_cursor.await {
|
||||
log::warn!("Could not create the root cursor: {}", ErrorFmt(e));
|
||||
break 'set_root_cursor;
|
||||
}
|
||||
let cwa = ChangeWindowAttributes {
|
||||
window: root,
|
||||
values: CreateWindowValues {
|
||||
cursor: Some(cursor),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
let cwa = ChangeWindowAttributesAux::new().cursor(cursor);
|
||||
let res: Res<_> = try { c.change_window_attributes(root, &cwa)?.check()? };
|
||||
if let Err(e) = res {
|
||||
if let Err(e) = c.call(&cwa).await {
|
||||
return Err(XWaylandError::SetCursor(e));
|
||||
}
|
||||
}
|
||||
|
|
@ -227,7 +288,6 @@ impl Wm {
|
|||
state: state.clone(),
|
||||
c,
|
||||
atoms,
|
||||
socket: socket_dup,
|
||||
_root: root,
|
||||
_xwin: xwin,
|
||||
client,
|
||||
|
|
@ -239,52 +299,40 @@ impl Wm {
|
|||
|
||||
pub async fn run(mut self) {
|
||||
loop {
|
||||
while let Some(e) = self.queue.try_pop() {
|
||||
self.handle_xwayland_event(e);
|
||||
}
|
||||
if let Err(e) = self.handle_events() {
|
||||
log::error!("Connection failed: {}", ErrorFmt(e));
|
||||
return;
|
||||
}
|
||||
futures::select! {
|
||||
res = self.socket.readable().fuse() => {
|
||||
if let Err(e) = res {
|
||||
log::error!("Cannot wait for xwm fd to become readable: {}", ErrorFmt(e));
|
||||
return;
|
||||
}
|
||||
}
|
||||
_ = self.queue.non_empty().fuse() => { },
|
||||
select! {
|
||||
e = self.queue.pop().fuse() => self.handle_xwayland_event(e).await,
|
||||
e = self.c.event().fuse() => self.handle_event(&e).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_xwayland_event(&mut self, e: XWaylandEvent) {
|
||||
async fn handle_xwayland_event(&mut self, e: XWaylandEvent) {
|
||||
match e {
|
||||
XWaylandEvent::SurfaceCreated(event) => self.handle_xwayland_surface_created(event),
|
||||
XWaylandEvent::Configure(event) => self.handle_xwayland_configure(event),
|
||||
XWaylandEvent::Configure(event) => self.handle_xwayland_configure(event).await,
|
||||
XWaylandEvent::SurfaceDestroyed(event) => self.handle_xwayland_surface_destroyed(event),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_xwayland_configure(&mut self, window: Rc<Xwindow>) {
|
||||
self.send_configure(window);
|
||||
async fn handle_xwayland_configure(&mut self, window: Rc<Xwindow>) {
|
||||
self.send_configure(window).await;
|
||||
}
|
||||
|
||||
fn send_configure(&mut self, window: Rc<Xwindow>) {
|
||||
async fn send_configure(&mut self, window: Rc<Xwindow>) {
|
||||
let extents = window.data.extents.get();
|
||||
let cfg = ConfigureWindowAux::new()
|
||||
.x(extents.x1())
|
||||
.y(extents.y1())
|
||||
.width(extents.width() as u32)
|
||||
.height(extents.height() as u32)
|
||||
.border_width(0);
|
||||
let res: Res<()> = try {
|
||||
self.c
|
||||
.configure_window(window.data.window_id, &cfg)?
|
||||
.check()?;
|
||||
let cw = ConfigureWindow {
|
||||
window: window.data.window_id,
|
||||
values: ConfigureWindowValues {
|
||||
x: Some(extents.x1()),
|
||||
y: Some(extents.y1()),
|
||||
width: Some(extents.width() as u32),
|
||||
height: Some(extents.height() as u32),
|
||||
border_width: Some(0),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
if let Err(e) = res {
|
||||
log::error!("Could not configure window: {}", ErrorFmt(&*e));
|
||||
if let Err(e) = self.c.call(&cw).await {
|
||||
log::error!("Could not configure window: {}", ErrorFmt(e));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -319,30 +367,33 @@ impl Wm {
|
|||
self.windows_by_surface_id.remove(&surface);
|
||||
}
|
||||
|
||||
fn handle_events(&mut self) -> Result<(), ConnectionError> {
|
||||
while let Some(e) = self.c.poll_for_event()? {
|
||||
self.handle_event(e);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_event(&mut self, event: Event) {
|
||||
log::info!("{:?}", event);
|
||||
match event {
|
||||
Event::MapRequest(event) => self.handle_map_request(event),
|
||||
Event::ConfigureRequest(event) => self.handle_configure_request(event),
|
||||
Event::ConfigureNotify(event) => self.handle_configure_notify(event),
|
||||
Event::ClientMessage(event) => self.handle_client_message(event),
|
||||
Event::CreateNotify(event) => self.handle_create_notify(event),
|
||||
Event::DestroyNotify(event) => self.handle_destroy_notify(event),
|
||||
_ => {}
|
||||
async fn handle_event(&mut self, event: &Event) {
|
||||
match event.ext() {
|
||||
Some(_) => {}
|
||||
_ => self.handle_core_event(&event).await,
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_destroy_notify(&mut self, event: DestroyNotifyEvent) {
|
||||
async fn handle_core_event(&mut self, event: &Event) {
|
||||
let res = match event.code() {
|
||||
MapRequest::OPCODE => self.handle_map_request(event).await,
|
||||
ConfigureRequest::OPCODE => self.handle_configure_request(event).await,
|
||||
ConfigureNotify::OPCODE => self.handle_configure_notify(event),
|
||||
ClientMessage::OPCODE => self.handle_client_message(event),
|
||||
CreateNotify::OPCODE => self.handle_create_notify(event),
|
||||
DestroyNotify::OPCODE => self.handle_destroy_notify(event),
|
||||
_ => Ok(()),
|
||||
};
|
||||
if let Err(e) = res {
|
||||
log::warn!("Could not handle an event: {}", ErrorFmt(e));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_destroy_notify(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
||||
let event: DestroyNotify = event.parse()?;
|
||||
let data = match self.windows.remove(&event.window) {
|
||||
Some(w) => w,
|
||||
_ => return,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
if let Some(sid) = data.surface_id.take() {
|
||||
self.windows_by_surface_id.remove(&sid);
|
||||
|
|
@ -350,30 +401,40 @@ impl Wm {
|
|||
if let Some(window) = data.window.take() {
|
||||
window.destroy();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_create_notify(&mut self, event: CreateNotifyEvent) {
|
||||
fn handle_create_notify(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
||||
let event: CreateNotify = event.parse()?;
|
||||
let data = Rc::new(XwindowData::new(&self.state, &event, &self.client));
|
||||
self.windows.insert(event.window, data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_client_message(&mut self, event: ClientMessageEvent) {
|
||||
if event.type_ == self.atoms.WL_SURFACE_ID {
|
||||
self.handle_wl_surface_id(event);
|
||||
fn handle_client_message(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
||||
let event: ClientMessage = event.parse()?;
|
||||
if event.ty == self.atoms.WL_SURFACE_ID {
|
||||
self.handle_wl_surface_id(&event)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_map_request(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
||||
let event: MapRequest = event.parse()?;
|
||||
let mw = MapWindow {
|
||||
window: event.window,
|
||||
};
|
||||
match self.c.call(&mw).await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(XWaylandError::MapWindow(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_map_request(&mut self, event: MapRequestEvent) {
|
||||
let res: Res<_> = try { self.c.map_window(event.window)?.check()? };
|
||||
if let Err(e) = res {
|
||||
log::error!("Could not map window: {}", ErrorFmt(&*e));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_configure_notify(&mut self, event: ConfigureNotifyEvent) {
|
||||
fn handle_configure_notify(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
||||
let event: ConfigureNotify = event.parse()?;
|
||||
let data = match self.windows.get(&event.window) {
|
||||
Some(d) => d,
|
||||
_ => return,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
if data.override_redirect {
|
||||
let extents = Rect::new_sized(
|
||||
|
|
@ -388,33 +449,37 @@ impl Wm {
|
|||
self.state.tree_changed();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_configure_request(&mut self, event: ConfigureRequestEvent) {
|
||||
async fn handle_configure_request(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
||||
let event: ConfigureRequest = event.parse()?;
|
||||
let data = match self.windows.get(&event.window) {
|
||||
Some(d) => d,
|
||||
_ => return,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
if let Some(w) = data.window.get() {
|
||||
self.send_configure(w);
|
||||
self.send_configure(w).await;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_wl_surface_id(&mut self, event: ClientMessageEvent) {
|
||||
fn handle_wl_surface_id(&mut self, event: &ClientMessage) -> Result<(), XWaylandError> {
|
||||
let data = match self.windows.get(&event.window) {
|
||||
Some(d) => d.clone(),
|
||||
_ => return,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
if data.surface_id.get().is_some() {
|
||||
log::error!("Surface id is already set");
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
let [surface_id, ..] = event.data.as_data32();
|
||||
let surface_id = event.data[0];
|
||||
let surface_id = WlSurfaceId::from_raw(surface_id);
|
||||
data.surface_id.set(Some(surface_id));
|
||||
self.windows_by_surface_id.insert(surface_id, data.clone());
|
||||
if let Ok(surface) = self.client.lookup(surface_id) {
|
||||
self.create_window(&data, surface);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
wire-xcon/composite.txt
Normal file
7
wire-xcon/composite.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
ext "Composite"
|
||||
|
||||
request CompositeRedirectSubwindows = 2 (
|
||||
window: u32,
|
||||
update: u8,
|
||||
@pad 3,
|
||||
);
|
||||
88
wire-xcon/render.txt
Normal file
88
wire-xcon/render.txt
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
ext "RENDER"
|
||||
|
||||
struct RenderDirectFormat {
|
||||
red_shift: u16,
|
||||
red_mask: u16,
|
||||
green_shift: u16,
|
||||
green_mask: u16,
|
||||
blue_shift: u16,
|
||||
blue_mask: u16,
|
||||
alpha_shift: u16,
|
||||
alpha_mask: u16,
|
||||
}
|
||||
|
||||
struct RenderPictFormInfo {
|
||||
id: u32,
|
||||
ty: u8,
|
||||
depth: u8,
|
||||
@pad 2,
|
||||
direct: RenderDirectFormat,
|
||||
colormap: u32,
|
||||
}
|
||||
|
||||
struct RenderPictVisual {
|
||||
visual: u32,
|
||||
format: u32,
|
||||
}
|
||||
|
||||
struct RenderPictDepth {
|
||||
depth: u8,
|
||||
@pad 1,
|
||||
num_visuals: u16 = len(visuals),
|
||||
@pad 4,
|
||||
visuals: list(RenderPictVisual, field(num_visuals)),
|
||||
}
|
||||
|
||||
struct RenderPictScreen {
|
||||
num_depths: u32 = len(depths),
|
||||
fallback: u32,
|
||||
depths: list(RenderPictDepth, field(num_depths)),
|
||||
}
|
||||
|
||||
request RenderQueryPictFormats = 1 () {
|
||||
@pad 1,
|
||||
num_formats: u32 = len(formats),
|
||||
num_screens: u32 = len(screens),
|
||||
num_depths: u32,
|
||||
num_visuals: u32,
|
||||
num_subpixel: u32 = len(subpixels),
|
||||
@pad 4,
|
||||
formats: list(RenderPictFormInfo, field(num_formats)),
|
||||
screens: list(RenderPictScreen, field(num_screens)),
|
||||
subpixels: list(u32, field(num_subpixel)),
|
||||
}
|
||||
|
||||
bitmask RenderCreatePictureValues {
|
||||
repeat: u32 = 0,
|
||||
alphamap: u32 = 1,
|
||||
alphaxorigin: u32 = 2,
|
||||
alphayorigin: u32 = 3,
|
||||
clipxorigin: u32 = 4,
|
||||
clipyorigin: u32 = 5,
|
||||
clipmask: u32 = 6,
|
||||
graphicsexposure: u32 = 7,
|
||||
subwindowmode: u32 = 8,
|
||||
polyedge: u32 = 9,
|
||||
polymode: u32 = 10,
|
||||
dither: u32 = 11,
|
||||
componentalpha: u32 = 12,
|
||||
}
|
||||
|
||||
request RenderCreatePicture = 4 (
|
||||
pid: u32,
|
||||
drawable: u32,
|
||||
format: u32,
|
||||
value_mask: u32 = bitmask(values),
|
||||
values: bitmask(RenderCreatePictureValues, field(value_mask)),
|
||||
);
|
||||
|
||||
request RenderFreePicture = 7 (
|
||||
picture: u32,
|
||||
);
|
||||
|
||||
request RenderCreateCursor = 27 (
|
||||
cid: u32,
|
||||
source: u32,
|
||||
x: u16,
|
||||
y: u16,
|
||||
);
|
||||
|
|
@ -151,26 +151,6 @@ request MapWindow = 8 (
|
|||
window: u32,
|
||||
);
|
||||
|
||||
event DestroyNotify = 17 {
|
||||
@pad 1,
|
||||
event: u32,
|
||||
window: u32,
|
||||
}
|
||||
|
||||
event ConfigureNotify = 22 {
|
||||
@pad 1,
|
||||
event: u32,
|
||||
window: u32,
|
||||
above_sibling: u32,
|
||||
x: i16,
|
||||
y: i16,
|
||||
width: u16,
|
||||
height: u16,
|
||||
border_width: u16,
|
||||
override_redirect: u8,
|
||||
@pad 1,
|
||||
}
|
||||
|
||||
request CreatePixmap = 53 (
|
||||
depth: u8,
|
||||
pid: u32,
|
||||
|
|
@ -263,3 +243,98 @@ request ChangeProperty = 18 (
|
|||
data_len: u32 = div(mul(len(data), literal(8)), field(format)),
|
||||
data: list(u8, mul(field(data_len), div(field(format), literal(8)))),
|
||||
);
|
||||
|
||||
request InternAtom = 16 (
|
||||
only_if_exists: u8,
|
||||
name_len: u16 = len(name),
|
||||
@pad 2,
|
||||
name: str(field(name_len)),
|
||||
@align 4,
|
||||
) {
|
||||
@pad 1,
|
||||
atom: u32,
|
||||
}
|
||||
|
||||
request SetSelectionOwner = 22 (
|
||||
@pad 1,
|
||||
owner: u32,
|
||||
selection: u32,
|
||||
time: u32,
|
||||
);
|
||||
|
||||
bitmask ConfigureWindowValues {
|
||||
x: i32 = 0,
|
||||
y: i32 = 1,
|
||||
width: u32 = 2,
|
||||
height: u32 = 3,
|
||||
border_width: u32 = 4,
|
||||
sibling: u32 = 5,
|
||||
stack_mode: u32 = 6,
|
||||
}
|
||||
|
||||
request ConfigureWindow = 12 (
|
||||
@pad 1,
|
||||
window: u32,
|
||||
value_mask: u16 = bitmask(values),
|
||||
@pad 2,
|
||||
values: bitmask(ConfigureWindowValues, field(value_mask)),
|
||||
);
|
||||
|
||||
event CreateNotify = 16 {
|
||||
@pad 1,
|
||||
parent: u32,
|
||||
window: u32,
|
||||
x: i16,
|
||||
y: i16,
|
||||
width: u16,
|
||||
height: u16,
|
||||
border_width: u16,
|
||||
override_redirect: u8,
|
||||
@pad 1,
|
||||
}
|
||||
|
||||
event DestroyNotify = 17 {
|
||||
@pad 1,
|
||||
event: u32,
|
||||
window: u32,
|
||||
}
|
||||
|
||||
event MapRequest= 20 {
|
||||
@pad 1,
|
||||
parent: u32,
|
||||
window: u32,
|
||||
}
|
||||
|
||||
event ConfigureNotify = 22 {
|
||||
@pad 1,
|
||||
event: u32,
|
||||
window: u32,
|
||||
above_sibling: u32,
|
||||
x: i16,
|
||||
y: i16,
|
||||
width: u16,
|
||||
height: u16,
|
||||
border_width: u16,
|
||||
override_redirect: u8,
|
||||
@pad 1,
|
||||
}
|
||||
|
||||
event ConfigureRequest = 23 {
|
||||
stack_mode: u8,
|
||||
parent: u32,
|
||||
window: u32,
|
||||
sibling: u32,
|
||||
x: i16,
|
||||
y: i16,
|
||||
width: u16,
|
||||
height: u16,
|
||||
border_width: u16,
|
||||
value_mask: u16,
|
||||
}
|
||||
|
||||
event ClientMessage = 33 {
|
||||
format: u8,
|
||||
window: u32,
|
||||
ty: u32,
|
||||
data: list(u32, literal(5)),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue