├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── build.rs ├── dist ├── lock-icon.png └── shaders │ ├── blur.frag │ ├── crt.frag │ ├── desaturate_fade.frag │ ├── dissolve.frag │ ├── overlay.frag │ ├── paper_burn.frag │ └── vertical_band_slide.frag ├── examples └── screencopy.rs ├── resources ├── bg.vert ├── icon.frag └── icon.vert ├── shaderlock.daemon └── src ├── authenticator.rs ├── graphics.rs ├── graphics ├── bg.rs └── icon.rs ├── lib.rs ├── main.rs ├── screencopy.rs └── window_manager.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | *.spv 4 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "ab_glyph" 7 | version = "0.2.29" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" 10 | dependencies = [ 11 | "ab_glyph_rasterizer", 12 | "owned_ttf_parser", 13 | ] 14 | 15 | [[package]] 16 | name = "ab_glyph_rasterizer" 17 | version = "0.1.8" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" 20 | 21 | [[package]] 22 | name = "addr2line" 23 | version = "0.24.2" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 26 | dependencies = [ 27 | "gimli", 28 | ] 29 | 30 | [[package]] 31 | name = "adler2" 32 | version = "2.0.0" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 35 | 36 | [[package]] 37 | name = "ahash" 38 | version = "0.8.11" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 41 | dependencies = [ 42 | "cfg-if", 43 | "getrandom", 44 | "once_cell", 45 | "version_check", 46 | "zerocopy", 47 | ] 48 | 49 | [[package]] 50 | name = "aho-corasick" 51 | version = "1.1.3" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 54 | dependencies = [ 55 | "memchr", 56 | ] 57 | 58 | [[package]] 59 | name = "aligned-vec" 60 | version = "0.5.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" 63 | 64 | [[package]] 65 | name = "allocator-api2" 66 | version = "0.2.18" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" 69 | 70 | [[package]] 71 | name = "android-activity" 72 | version = "0.6.0" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" 75 | dependencies = [ 76 | "android-properties", 77 | "bitflags 2.6.0", 78 | "cc", 79 | "cesu8", 80 | "jni", 81 | "jni-sys", 82 | "libc", 83 | "log", 84 | "ndk", 85 | "ndk-context", 86 | "ndk-sys 0.6.0+11769913", 87 | "num_enum", 88 | "thiserror", 89 | ] 90 | 91 | [[package]] 92 | name = "android-properties" 93 | version = "0.2.2" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" 96 | 97 | [[package]] 98 | name = "android_system_properties" 99 | version = "0.1.5" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 102 | dependencies = [ 103 | "libc", 104 | ] 105 | 106 | [[package]] 107 | name = "anstream" 108 | version = "0.6.15" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 111 | dependencies = [ 112 | "anstyle", 113 | "anstyle-parse", 114 | "anstyle-query", 115 | "anstyle-wincon", 116 | "colorchoice", 117 | "is_terminal_polyfill", 118 | "utf8parse", 119 | ] 120 | 121 | [[package]] 122 | name = "anstyle" 123 | version = "1.0.8" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 126 | 127 | [[package]] 128 | name = "anstyle-parse" 129 | version = "0.2.5" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" 132 | dependencies = [ 133 | "utf8parse", 134 | ] 135 | 136 | [[package]] 137 | name = "anstyle-query" 138 | version = "1.1.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" 141 | dependencies = [ 142 | "windows-sys 0.52.0", 143 | ] 144 | 145 | [[package]] 146 | name = "anstyle-wincon" 147 | version = "3.0.4" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" 150 | dependencies = [ 151 | "anstyle", 152 | "windows-sys 0.52.0", 153 | ] 154 | 155 | [[package]] 156 | name = "anyhow" 157 | version = "1.0.90" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" 160 | 161 | [[package]] 162 | name = "approx" 163 | version = "0.4.0" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" 166 | dependencies = [ 167 | "num-traits", 168 | ] 169 | 170 | [[package]] 171 | name = "arbitrary" 172 | version = "1.4.1" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" 175 | 176 | [[package]] 177 | name = "arg_enum_proc_macro" 178 | version = "0.3.4" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" 181 | dependencies = [ 182 | "proc-macro2", 183 | "quote", 184 | "syn 2.0.80", 185 | ] 186 | 187 | [[package]] 188 | name = "arrayref" 189 | version = "0.3.9" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" 192 | 193 | [[package]] 194 | name = "arrayvec" 195 | version = "0.7.6" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 198 | 199 | [[package]] 200 | name = "as-raw-xcb-connection" 201 | version = "1.0.1" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" 204 | 205 | [[package]] 206 | name = "ash" 207 | version = "0.38.0+1.3.281" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" 210 | dependencies = [ 211 | "libloading", 212 | ] 213 | 214 | [[package]] 215 | name = "atomic-waker" 216 | version = "1.1.2" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 219 | 220 | [[package]] 221 | name = "autocfg" 222 | version = "1.4.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 225 | 226 | [[package]] 227 | name = "av1-grain" 228 | version = "0.2.3" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" 231 | dependencies = [ 232 | "anyhow", 233 | "arrayvec", 234 | "log", 235 | "nom", 236 | "num-rational", 237 | "v_frame", 238 | ] 239 | 240 | [[package]] 241 | name = "avif-serialize" 242 | version = "0.8.2" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" 245 | dependencies = [ 246 | "arrayvec", 247 | ] 248 | 249 | [[package]] 250 | name = "backtrace" 251 | version = "0.3.74" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 254 | dependencies = [ 255 | "addr2line", 256 | "cfg-if", 257 | "libc", 258 | "miniz_oxide", 259 | "object", 260 | "rustc-demangle", 261 | "windows-targets 0.52.6", 262 | ] 263 | 264 | [[package]] 265 | name = "bit-set" 266 | version = "0.6.0" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" 269 | dependencies = [ 270 | "bit-vec", 271 | ] 272 | 273 | [[package]] 274 | name = "bit-vec" 275 | version = "0.7.0" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" 278 | 279 | [[package]] 280 | name = "bit_field" 281 | version = "0.10.2" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" 284 | 285 | [[package]] 286 | name = "bitflags" 287 | version = "1.3.2" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 290 | 291 | [[package]] 292 | name = "bitflags" 293 | version = "2.6.0" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 296 | 297 | [[package]] 298 | name = "bitstream-io" 299 | version = "2.6.0" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" 302 | 303 | [[package]] 304 | name = "block" 305 | version = "0.1.6" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 308 | 309 | [[package]] 310 | name = "block2" 311 | version = "0.5.1" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" 314 | dependencies = [ 315 | "objc2", 316 | ] 317 | 318 | [[package]] 319 | name = "built" 320 | version = "0.7.5" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" 323 | 324 | [[package]] 325 | name = "bumpalo" 326 | version = "3.16.0" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 329 | 330 | [[package]] 331 | name = "bytemuck" 332 | version = "1.19.0" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" 335 | dependencies = [ 336 | "bytemuck_derive", 337 | ] 338 | 339 | [[package]] 340 | name = "bytemuck_derive" 341 | version = "1.8.0" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" 344 | dependencies = [ 345 | "proc-macro2", 346 | "quote", 347 | "syn 2.0.80", 348 | ] 349 | 350 | [[package]] 351 | name = "byteorder" 352 | version = "1.5.0" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 355 | 356 | [[package]] 357 | name = "byteorder-lite" 358 | version = "0.1.0" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" 361 | 362 | [[package]] 363 | name = "bytes" 364 | version = "1.7.2" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" 367 | 368 | [[package]] 369 | name = "calloop" 370 | version = "0.13.0" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" 373 | dependencies = [ 374 | "bitflags 2.6.0", 375 | "log", 376 | "polling", 377 | "rustix", 378 | "slab", 379 | "thiserror", 380 | ] 381 | 382 | [[package]] 383 | name = "calloop-wayland-source" 384 | version = "0.3.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" 387 | dependencies = [ 388 | "calloop", 389 | "rustix", 390 | "wayland-backend", 391 | "wayland-client", 392 | ] 393 | 394 | [[package]] 395 | name = "cc" 396 | version = "1.1.31" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" 399 | dependencies = [ 400 | "jobserver", 401 | "libc", 402 | "shlex", 403 | ] 404 | 405 | [[package]] 406 | name = "cesu8" 407 | version = "1.1.0" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 410 | 411 | [[package]] 412 | name = "cfg-expr" 413 | version = "0.15.8" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" 416 | dependencies = [ 417 | "smallvec", 418 | "target-lexicon", 419 | ] 420 | 421 | [[package]] 422 | name = "cfg-if" 423 | version = "1.0.0" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 426 | 427 | [[package]] 428 | name = "cfg_aliases" 429 | version = "0.1.1" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" 432 | 433 | [[package]] 434 | name = "cfg_aliases" 435 | version = "0.2.1" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 438 | 439 | [[package]] 440 | name = "cgmath" 441 | version = "0.18.0" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" 444 | dependencies = [ 445 | "approx", 446 | "num-traits", 447 | ] 448 | 449 | [[package]] 450 | name = "clap" 451 | version = "4.5.20" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" 454 | dependencies = [ 455 | "clap_builder", 456 | "clap_derive", 457 | ] 458 | 459 | [[package]] 460 | name = "clap_builder" 461 | version = "4.5.20" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" 464 | dependencies = [ 465 | "anstream", 466 | "anstyle", 467 | "clap_lex", 468 | "strsim", 469 | ] 470 | 471 | [[package]] 472 | name = "clap_derive" 473 | version = "4.5.18" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" 476 | dependencies = [ 477 | "heck", 478 | "proc-macro2", 479 | "quote", 480 | "syn 2.0.80", 481 | ] 482 | 483 | [[package]] 484 | name = "clap_lex" 485 | version = "0.7.2" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 488 | 489 | [[package]] 490 | name = "cmake" 491 | version = "0.1.51" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" 494 | dependencies = [ 495 | "cc", 496 | ] 497 | 498 | [[package]] 499 | name = "codespan-reporting" 500 | version = "0.11.1" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 503 | dependencies = [ 504 | "termcolor", 505 | "unicode-width", 506 | ] 507 | 508 | [[package]] 509 | name = "color_quant" 510 | version = "1.1.0" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 513 | 514 | [[package]] 515 | name = "colorchoice" 516 | version = "1.0.2" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 519 | 520 | [[package]] 521 | name = "com" 522 | version = "0.6.0" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" 525 | dependencies = [ 526 | "com_macros", 527 | ] 528 | 529 | [[package]] 530 | name = "com_macros" 531 | version = "0.6.0" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" 534 | dependencies = [ 535 | "com_macros_support", 536 | "proc-macro2", 537 | "syn 1.0.109", 538 | ] 539 | 540 | [[package]] 541 | name = "com_macros_support" 542 | version = "0.6.0" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" 545 | dependencies = [ 546 | "proc-macro2", 547 | "quote", 548 | "syn 1.0.109", 549 | ] 550 | 551 | [[package]] 552 | name = "combine" 553 | version = "4.6.7" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" 556 | dependencies = [ 557 | "bytes", 558 | "memchr", 559 | ] 560 | 561 | [[package]] 562 | name = "concurrent-queue" 563 | version = "2.5.0" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 566 | dependencies = [ 567 | "crossbeam-utils", 568 | ] 569 | 570 | [[package]] 571 | name = "core-foundation" 572 | version = "0.9.4" 573 | source = "registry+https://github.com/rust-lang/crates.io-index" 574 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 575 | dependencies = [ 576 | "core-foundation-sys", 577 | "libc", 578 | ] 579 | 580 | [[package]] 581 | name = "core-foundation-sys" 582 | version = "0.8.7" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 585 | 586 | [[package]] 587 | name = "core-graphics" 588 | version = "0.23.2" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" 591 | dependencies = [ 592 | "bitflags 1.3.2", 593 | "core-foundation", 594 | "core-graphics-types", 595 | "foreign-types", 596 | "libc", 597 | ] 598 | 599 | [[package]] 600 | name = "core-graphics-types" 601 | version = "0.1.3" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" 604 | dependencies = [ 605 | "bitflags 1.3.2", 606 | "core-foundation", 607 | "libc", 608 | ] 609 | 610 | [[package]] 611 | name = "crc32fast" 612 | version = "1.4.2" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 615 | dependencies = [ 616 | "cfg-if", 617 | ] 618 | 619 | [[package]] 620 | name = "crossbeam-deque" 621 | version = "0.8.5" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 624 | dependencies = [ 625 | "crossbeam-epoch", 626 | "crossbeam-utils", 627 | ] 628 | 629 | [[package]] 630 | name = "crossbeam-epoch" 631 | version = "0.9.18" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 634 | dependencies = [ 635 | "crossbeam-utils", 636 | ] 637 | 638 | [[package]] 639 | name = "crossbeam-utils" 640 | version = "0.8.20" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 643 | 644 | [[package]] 645 | name = "crunchy" 646 | version = "0.2.2" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 649 | 650 | [[package]] 651 | name = "cursor-icon" 652 | version = "1.1.0" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" 655 | 656 | [[package]] 657 | name = "d3d12" 658 | version = "22.0.0" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "bdbd1f579714e3c809ebd822c81ef148b1ceaeb3d535352afc73fd0c4c6a0017" 661 | dependencies = [ 662 | "bitflags 2.6.0", 663 | "libloading", 664 | "winapi", 665 | ] 666 | 667 | [[package]] 668 | name = "dashmap" 669 | version = "6.1.0" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" 672 | dependencies = [ 673 | "cfg-if", 674 | "crossbeam-utils", 675 | "hashbrown 0.14.5", 676 | "lock_api", 677 | "once_cell", 678 | "parking_lot_core", 679 | ] 680 | 681 | [[package]] 682 | name = "dispatch" 683 | version = "0.2.0" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" 686 | 687 | [[package]] 688 | name = "dlib" 689 | version = "0.5.2" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" 692 | dependencies = [ 693 | "libloading", 694 | ] 695 | 696 | [[package]] 697 | name = "document-features" 698 | version = "0.2.10" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" 701 | dependencies = [ 702 | "litrs", 703 | ] 704 | 705 | [[package]] 706 | name = "downcast-rs" 707 | version = "1.2.1" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" 710 | 711 | [[package]] 712 | name = "dpi" 713 | version = "0.1.1" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" 716 | 717 | [[package]] 718 | name = "either" 719 | version = "1.13.0" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 722 | 723 | [[package]] 724 | name = "env_filter" 725 | version = "0.1.2" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" 728 | dependencies = [ 729 | "log", 730 | "regex", 731 | ] 732 | 733 | [[package]] 734 | name = "env_logger" 735 | version = "0.11.5" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" 738 | dependencies = [ 739 | "anstream", 740 | "anstyle", 741 | "env_filter", 742 | "humantime", 743 | "log", 744 | ] 745 | 746 | [[package]] 747 | name = "equivalent" 748 | version = "1.0.1" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 751 | 752 | [[package]] 753 | name = "errno" 754 | version = "0.3.9" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 757 | dependencies = [ 758 | "libc", 759 | "windows-sys 0.52.0", 760 | ] 761 | 762 | [[package]] 763 | name = "exr" 764 | version = "1.73.0" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" 767 | dependencies = [ 768 | "bit_field", 769 | "half", 770 | "lebe", 771 | "miniz_oxide", 772 | "rayon-core", 773 | "smallvec", 774 | "zune-inflate", 775 | ] 776 | 777 | [[package]] 778 | name = "fdeflate" 779 | version = "0.3.6" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" 782 | dependencies = [ 783 | "simd-adler32", 784 | ] 785 | 786 | [[package]] 787 | name = "fixedbitset" 788 | version = "0.4.2" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 791 | 792 | [[package]] 793 | name = "flate2" 794 | version = "1.0.35" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" 797 | dependencies = [ 798 | "crc32fast", 799 | "miniz_oxide", 800 | ] 801 | 802 | [[package]] 803 | name = "foreign-types" 804 | version = "0.5.0" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" 807 | dependencies = [ 808 | "foreign-types-macros", 809 | "foreign-types-shared", 810 | ] 811 | 812 | [[package]] 813 | name = "foreign-types-macros" 814 | version = "0.2.3" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" 817 | dependencies = [ 818 | "proc-macro2", 819 | "quote", 820 | "syn 2.0.80", 821 | ] 822 | 823 | [[package]] 824 | name = "foreign-types-shared" 825 | version = "0.3.1" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" 828 | 829 | [[package]] 830 | name = "futures" 831 | version = "0.3.31" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 834 | dependencies = [ 835 | "futures-channel", 836 | "futures-core", 837 | "futures-executor", 838 | "futures-io", 839 | "futures-sink", 840 | "futures-task", 841 | "futures-util", 842 | ] 843 | 844 | [[package]] 845 | name = "futures-channel" 846 | version = "0.3.31" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 849 | dependencies = [ 850 | "futures-core", 851 | "futures-sink", 852 | ] 853 | 854 | [[package]] 855 | name = "futures-core" 856 | version = "0.3.31" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 859 | 860 | [[package]] 861 | name = "futures-executor" 862 | version = "0.3.31" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 865 | dependencies = [ 866 | "futures-core", 867 | "futures-task", 868 | "futures-util", 869 | ] 870 | 871 | [[package]] 872 | name = "futures-io" 873 | version = "0.3.31" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 876 | 877 | [[package]] 878 | name = "futures-macro" 879 | version = "0.3.31" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 882 | dependencies = [ 883 | "proc-macro2", 884 | "quote", 885 | "syn 2.0.80", 886 | ] 887 | 888 | [[package]] 889 | name = "futures-sink" 890 | version = "0.3.31" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 893 | 894 | [[package]] 895 | name = "futures-task" 896 | version = "0.3.31" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 899 | 900 | [[package]] 901 | name = "futures-util" 902 | version = "0.3.31" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 905 | dependencies = [ 906 | "futures-channel", 907 | "futures-core", 908 | "futures-io", 909 | "futures-macro", 910 | "futures-sink", 911 | "futures-task", 912 | "memchr", 913 | "pin-project-lite", 914 | "pin-utils", 915 | "slab", 916 | ] 917 | 918 | [[package]] 919 | name = "gethostname" 920 | version = "0.4.3" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" 923 | dependencies = [ 924 | "libc", 925 | "windows-targets 0.48.5", 926 | ] 927 | 928 | [[package]] 929 | name = "getrandom" 930 | version = "0.2.15" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 933 | dependencies = [ 934 | "cfg-if", 935 | "libc", 936 | "wasi", 937 | ] 938 | 939 | [[package]] 940 | name = "gif" 941 | version = "0.13.1" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" 944 | dependencies = [ 945 | "color_quant", 946 | "weezl", 947 | ] 948 | 949 | [[package]] 950 | name = "gimli" 951 | version = "0.31.1" 952 | source = "registry+https://github.com/rust-lang/crates.io-index" 953 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 954 | 955 | [[package]] 956 | name = "gl_generator" 957 | version = "0.14.0" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" 960 | dependencies = [ 961 | "khronos_api", 962 | "log", 963 | "xml-rs", 964 | ] 965 | 966 | [[package]] 967 | name = "glob" 968 | version = "0.3.1" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 971 | 972 | [[package]] 973 | name = "glow" 974 | version = "0.13.1" 975 | source = "registry+https://github.com/rust-lang/crates.io-index" 976 | checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" 977 | dependencies = [ 978 | "js-sys", 979 | "slotmap", 980 | "wasm-bindgen", 981 | "web-sys", 982 | ] 983 | 984 | [[package]] 985 | name = "glutin_wgl_sys" 986 | version = "0.6.0" 987 | source = "registry+https://github.com/rust-lang/crates.io-index" 988 | checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" 989 | dependencies = [ 990 | "gl_generator", 991 | ] 992 | 993 | [[package]] 994 | name = "gpu-alloc" 995 | version = "0.6.0" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" 998 | dependencies = [ 999 | "bitflags 2.6.0", 1000 | "gpu-alloc-types", 1001 | ] 1002 | 1003 | [[package]] 1004 | name = "gpu-alloc-types" 1005 | version = "0.3.0" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" 1008 | dependencies = [ 1009 | "bitflags 2.6.0", 1010 | ] 1011 | 1012 | [[package]] 1013 | name = "gpu-allocator" 1014 | version = "0.26.0" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" 1017 | dependencies = [ 1018 | "log", 1019 | "presser", 1020 | "thiserror", 1021 | "winapi", 1022 | "windows", 1023 | ] 1024 | 1025 | [[package]] 1026 | name = "gpu-descriptor" 1027 | version = "0.3.0" 1028 | source = "registry+https://github.com/rust-lang/crates.io-index" 1029 | checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" 1030 | dependencies = [ 1031 | "bitflags 2.6.0", 1032 | "gpu-descriptor-types", 1033 | "hashbrown 0.14.5", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "gpu-descriptor-types" 1038 | version = "0.2.0" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" 1041 | dependencies = [ 1042 | "bitflags 2.6.0", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "half" 1047 | version = "2.4.1" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" 1050 | dependencies = [ 1051 | "cfg-if", 1052 | "crunchy", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "hashbrown" 1057 | version = "0.12.3" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 1060 | 1061 | [[package]] 1062 | name = "hashbrown" 1063 | version = "0.14.5" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1066 | dependencies = [ 1067 | "ahash", 1068 | "allocator-api2", 1069 | ] 1070 | 1071 | [[package]] 1072 | name = "hashbrown" 1073 | version = "0.15.0" 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" 1075 | checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" 1076 | 1077 | [[package]] 1078 | name = "hassle-rs" 1079 | version = "0.11.0" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" 1082 | dependencies = [ 1083 | "bitflags 2.6.0", 1084 | "com", 1085 | "libc", 1086 | "libloading", 1087 | "thiserror", 1088 | "widestring", 1089 | "winapi", 1090 | ] 1091 | 1092 | [[package]] 1093 | name = "heck" 1094 | version = "0.5.0" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1097 | 1098 | [[package]] 1099 | name = "hermit-abi" 1100 | version = "0.3.9" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 1103 | 1104 | [[package]] 1105 | name = "hermit-abi" 1106 | version = "0.4.0" 1107 | source = "registry+https://github.com/rust-lang/crates.io-index" 1108 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 1109 | 1110 | [[package]] 1111 | name = "hexf-parse" 1112 | version = "0.2.1" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" 1115 | 1116 | [[package]] 1117 | name = "humantime" 1118 | version = "2.1.0" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 1121 | 1122 | [[package]] 1123 | name = "image" 1124 | version = "0.25.5" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" 1127 | dependencies = [ 1128 | "bytemuck", 1129 | "byteorder-lite", 1130 | "color_quant", 1131 | "exr", 1132 | "gif", 1133 | "image-webp", 1134 | "num-traits", 1135 | "png", 1136 | "qoi", 1137 | "ravif", 1138 | "rayon", 1139 | "rgb", 1140 | "tiff", 1141 | "zune-core", 1142 | "zune-jpeg", 1143 | ] 1144 | 1145 | [[package]] 1146 | name = "image-webp" 1147 | version = "0.2.0" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" 1150 | dependencies = [ 1151 | "byteorder-lite", 1152 | "quick-error", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "imgref" 1157 | version = "1.11.0" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" 1160 | 1161 | [[package]] 1162 | name = "indexmap" 1163 | version = "1.9.3" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 1166 | dependencies = [ 1167 | "autocfg", 1168 | "hashbrown 0.12.3", 1169 | ] 1170 | 1171 | [[package]] 1172 | name = "indexmap" 1173 | version = "2.6.0" 1174 | source = "registry+https://github.com/rust-lang/crates.io-index" 1175 | checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" 1176 | dependencies = [ 1177 | "equivalent", 1178 | "hashbrown 0.15.0", 1179 | ] 1180 | 1181 | [[package]] 1182 | name = "interpolate_name" 1183 | version = "0.2.4" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" 1186 | dependencies = [ 1187 | "proc-macro2", 1188 | "quote", 1189 | "syn 2.0.80", 1190 | ] 1191 | 1192 | [[package]] 1193 | name = "is_terminal_polyfill" 1194 | version = "1.70.1" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1197 | 1198 | [[package]] 1199 | name = "itertools" 1200 | version = "0.12.1" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 1203 | dependencies = [ 1204 | "either", 1205 | ] 1206 | 1207 | [[package]] 1208 | name = "jni" 1209 | version = "0.21.1" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" 1212 | dependencies = [ 1213 | "cesu8", 1214 | "cfg-if", 1215 | "combine", 1216 | "jni-sys", 1217 | "log", 1218 | "thiserror", 1219 | "walkdir", 1220 | "windows-sys 0.45.0", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "jni-sys" 1225 | version = "0.3.0" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1228 | 1229 | [[package]] 1230 | name = "jobserver" 1231 | version = "0.1.32" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 1234 | dependencies = [ 1235 | "libc", 1236 | ] 1237 | 1238 | [[package]] 1239 | name = "jpeg-decoder" 1240 | version = "0.3.1" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" 1243 | 1244 | [[package]] 1245 | name = "js-sys" 1246 | version = "0.3.72" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" 1249 | dependencies = [ 1250 | "wasm-bindgen", 1251 | ] 1252 | 1253 | [[package]] 1254 | name = "khronos-egl" 1255 | version = "6.0.0" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" 1258 | dependencies = [ 1259 | "libc", 1260 | "libloading", 1261 | "pkg-config", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "khronos_api" 1266 | version = "3.1.0" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" 1269 | 1270 | [[package]] 1271 | name = "lebe" 1272 | version = "0.5.2" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" 1275 | 1276 | [[package]] 1277 | name = "libc" 1278 | version = "0.2.161" 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" 1280 | checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" 1281 | 1282 | [[package]] 1283 | name = "libfuzzer-sys" 1284 | version = "0.4.8" 1285 | source = "registry+https://github.com/rust-lang/crates.io-index" 1286 | checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" 1287 | dependencies = [ 1288 | "arbitrary", 1289 | "cc", 1290 | ] 1291 | 1292 | [[package]] 1293 | name = "libloading" 1294 | version = "0.8.5" 1295 | source = "registry+https://github.com/rust-lang/crates.io-index" 1296 | checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" 1297 | dependencies = [ 1298 | "cfg-if", 1299 | "windows-targets 0.52.6", 1300 | ] 1301 | 1302 | [[package]] 1303 | name = "libredox" 1304 | version = "0.1.3" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 1307 | dependencies = [ 1308 | "bitflags 2.6.0", 1309 | "libc", 1310 | "redox_syscall 0.5.7", 1311 | ] 1312 | 1313 | [[package]] 1314 | name = "linux-raw-sys" 1315 | version = "0.4.14" 1316 | source = "registry+https://github.com/rust-lang/crates.io-index" 1317 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 1318 | 1319 | [[package]] 1320 | name = "litrs" 1321 | version = "0.4.1" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 1324 | 1325 | [[package]] 1326 | name = "lock_api" 1327 | version = "0.4.12" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1330 | dependencies = [ 1331 | "autocfg", 1332 | "scopeguard", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "log" 1337 | version = "0.4.22" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1340 | 1341 | [[package]] 1342 | name = "loop9" 1343 | version = "0.1.5" 1344 | source = "registry+https://github.com/rust-lang/crates.io-index" 1345 | checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" 1346 | dependencies = [ 1347 | "imgref", 1348 | ] 1349 | 1350 | [[package]] 1351 | name = "malloc_buf" 1352 | version = "0.0.6" 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" 1354 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1355 | dependencies = [ 1356 | "libc", 1357 | ] 1358 | 1359 | [[package]] 1360 | name = "maybe-rayon" 1361 | version = "0.1.1" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" 1364 | dependencies = [ 1365 | "cfg-if", 1366 | "rayon", 1367 | ] 1368 | 1369 | [[package]] 1370 | name = "memchr" 1371 | version = "2.7.4" 1372 | source = "registry+https://github.com/rust-lang/crates.io-index" 1373 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1374 | 1375 | [[package]] 1376 | name = "memmap2" 1377 | version = "0.8.0" 1378 | source = "registry+https://github.com/rust-lang/crates.io-index" 1379 | checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed" 1380 | dependencies = [ 1381 | "libc", 1382 | ] 1383 | 1384 | [[package]] 1385 | name = "memmap2" 1386 | version = "0.9.5" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" 1389 | dependencies = [ 1390 | "libc", 1391 | ] 1392 | 1393 | [[package]] 1394 | name = "metal" 1395 | version = "0.29.0" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" 1398 | dependencies = [ 1399 | "bitflags 2.6.0", 1400 | "block", 1401 | "core-graphics-types", 1402 | "foreign-types", 1403 | "log", 1404 | "objc", 1405 | "paste", 1406 | ] 1407 | 1408 | [[package]] 1409 | name = "minimal-lexical" 1410 | version = "0.2.1" 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" 1412 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1413 | 1414 | [[package]] 1415 | name = "miniz_oxide" 1416 | version = "0.8.0" 1417 | source = "registry+https://github.com/rust-lang/crates.io-index" 1418 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 1419 | dependencies = [ 1420 | "adler2", 1421 | "simd-adler32", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "mio" 1426 | version = "1.0.2" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 1429 | dependencies = [ 1430 | "hermit-abi 0.3.9", 1431 | "libc", 1432 | "wasi", 1433 | "windows-sys 0.52.0", 1434 | ] 1435 | 1436 | [[package]] 1437 | name = "naga" 1438 | version = "22.1.0" 1439 | source = "registry+https://github.com/rust-lang/crates.io-index" 1440 | checksum = "8bd5a652b6faf21496f2cfd88fc49989c8db0825d1f6746b1a71a6ede24a63ad" 1441 | dependencies = [ 1442 | "arrayvec", 1443 | "bit-set", 1444 | "bitflags 2.6.0", 1445 | "cfg_aliases 0.1.1", 1446 | "codespan-reporting", 1447 | "hexf-parse", 1448 | "indexmap 2.6.0", 1449 | "log", 1450 | "petgraph", 1451 | "rustc-hash", 1452 | "spirv", 1453 | "termcolor", 1454 | "thiserror", 1455 | "unicode-xid", 1456 | ] 1457 | 1458 | [[package]] 1459 | name = "ndk" 1460 | version = "0.9.0" 1461 | source = "registry+https://github.com/rust-lang/crates.io-index" 1462 | checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" 1463 | dependencies = [ 1464 | "bitflags 2.6.0", 1465 | "jni-sys", 1466 | "log", 1467 | "ndk-sys 0.6.0+11769913", 1468 | "num_enum", 1469 | "raw-window-handle", 1470 | "thiserror", 1471 | ] 1472 | 1473 | [[package]] 1474 | name = "ndk-context" 1475 | version = "0.1.1" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 1478 | 1479 | [[package]] 1480 | name = "ndk-sys" 1481 | version = "0.5.0+25.2.9519653" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" 1484 | dependencies = [ 1485 | "jni-sys", 1486 | ] 1487 | 1488 | [[package]] 1489 | name = "ndk-sys" 1490 | version = "0.6.0+11769913" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" 1493 | dependencies = [ 1494 | "jni-sys", 1495 | ] 1496 | 1497 | [[package]] 1498 | name = "new_debug_unreachable" 1499 | version = "1.0.6" 1500 | source = "registry+https://github.com/rust-lang/crates.io-index" 1501 | checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" 1502 | 1503 | [[package]] 1504 | name = "nom" 1505 | version = "7.1.3" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1508 | dependencies = [ 1509 | "memchr", 1510 | "minimal-lexical", 1511 | ] 1512 | 1513 | [[package]] 1514 | name = "noop_proc_macro" 1515 | version = "0.3.0" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" 1518 | 1519 | [[package]] 1520 | name = "num-bigint" 1521 | version = "0.4.6" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 1524 | dependencies = [ 1525 | "num-integer", 1526 | "num-traits", 1527 | ] 1528 | 1529 | [[package]] 1530 | name = "num-derive" 1531 | version = "0.4.2" 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" 1533 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 1534 | dependencies = [ 1535 | "proc-macro2", 1536 | "quote", 1537 | "syn 2.0.80", 1538 | ] 1539 | 1540 | [[package]] 1541 | name = "num-integer" 1542 | version = "0.1.46" 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" 1544 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1545 | dependencies = [ 1546 | "num-traits", 1547 | ] 1548 | 1549 | [[package]] 1550 | name = "num-rational" 1551 | version = "0.4.2" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" 1554 | dependencies = [ 1555 | "num-bigint", 1556 | "num-integer", 1557 | "num-traits", 1558 | ] 1559 | 1560 | [[package]] 1561 | name = "num-traits" 1562 | version = "0.2.19" 1563 | source = "registry+https://github.com/rust-lang/crates.io-index" 1564 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1565 | dependencies = [ 1566 | "autocfg", 1567 | ] 1568 | 1569 | [[package]] 1570 | name = "num_enum" 1571 | version = "0.7.3" 1572 | source = "registry+https://github.com/rust-lang/crates.io-index" 1573 | checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" 1574 | dependencies = [ 1575 | "num_enum_derive", 1576 | ] 1577 | 1578 | [[package]] 1579 | name = "num_enum_derive" 1580 | version = "0.7.3" 1581 | source = "registry+https://github.com/rust-lang/crates.io-index" 1582 | checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" 1583 | dependencies = [ 1584 | "proc-macro-crate", 1585 | "proc-macro2", 1586 | "quote", 1587 | "syn 2.0.80", 1588 | ] 1589 | 1590 | [[package]] 1591 | name = "objc" 1592 | version = "0.2.7" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1595 | dependencies = [ 1596 | "malloc_buf", 1597 | ] 1598 | 1599 | [[package]] 1600 | name = "objc-sys" 1601 | version = "0.3.5" 1602 | source = "registry+https://github.com/rust-lang/crates.io-index" 1603 | checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" 1604 | 1605 | [[package]] 1606 | name = "objc2" 1607 | version = "0.5.2" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" 1610 | dependencies = [ 1611 | "objc-sys", 1612 | "objc2-encode", 1613 | ] 1614 | 1615 | [[package]] 1616 | name = "objc2-app-kit" 1617 | version = "0.2.2" 1618 | source = "registry+https://github.com/rust-lang/crates.io-index" 1619 | checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" 1620 | dependencies = [ 1621 | "bitflags 2.6.0", 1622 | "block2", 1623 | "libc", 1624 | "objc2", 1625 | "objc2-core-data", 1626 | "objc2-core-image", 1627 | "objc2-foundation", 1628 | "objc2-quartz-core", 1629 | ] 1630 | 1631 | [[package]] 1632 | name = "objc2-cloud-kit" 1633 | version = "0.2.2" 1634 | source = "registry+https://github.com/rust-lang/crates.io-index" 1635 | checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" 1636 | dependencies = [ 1637 | "bitflags 2.6.0", 1638 | "block2", 1639 | "objc2", 1640 | "objc2-core-location", 1641 | "objc2-foundation", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "objc2-contacts" 1646 | version = "0.2.2" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" 1649 | dependencies = [ 1650 | "block2", 1651 | "objc2", 1652 | "objc2-foundation", 1653 | ] 1654 | 1655 | [[package]] 1656 | name = "objc2-core-data" 1657 | version = "0.2.2" 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" 1659 | checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" 1660 | dependencies = [ 1661 | "bitflags 2.6.0", 1662 | "block2", 1663 | "objc2", 1664 | "objc2-foundation", 1665 | ] 1666 | 1667 | [[package]] 1668 | name = "objc2-core-image" 1669 | version = "0.2.2" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" 1672 | dependencies = [ 1673 | "block2", 1674 | "objc2", 1675 | "objc2-foundation", 1676 | "objc2-metal", 1677 | ] 1678 | 1679 | [[package]] 1680 | name = "objc2-core-location" 1681 | version = "0.2.2" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" 1684 | dependencies = [ 1685 | "block2", 1686 | "objc2", 1687 | "objc2-contacts", 1688 | "objc2-foundation", 1689 | ] 1690 | 1691 | [[package]] 1692 | name = "objc2-encode" 1693 | version = "4.0.3" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" 1696 | 1697 | [[package]] 1698 | name = "objc2-foundation" 1699 | version = "0.2.2" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" 1702 | dependencies = [ 1703 | "bitflags 2.6.0", 1704 | "block2", 1705 | "dispatch", 1706 | "libc", 1707 | "objc2", 1708 | ] 1709 | 1710 | [[package]] 1711 | name = "objc2-link-presentation" 1712 | version = "0.2.2" 1713 | source = "registry+https://github.com/rust-lang/crates.io-index" 1714 | checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" 1715 | dependencies = [ 1716 | "block2", 1717 | "objc2", 1718 | "objc2-app-kit", 1719 | "objc2-foundation", 1720 | ] 1721 | 1722 | [[package]] 1723 | name = "objc2-metal" 1724 | version = "0.2.2" 1725 | source = "registry+https://github.com/rust-lang/crates.io-index" 1726 | checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" 1727 | dependencies = [ 1728 | "bitflags 2.6.0", 1729 | "block2", 1730 | "objc2", 1731 | "objc2-foundation", 1732 | ] 1733 | 1734 | [[package]] 1735 | name = "objc2-quartz-core" 1736 | version = "0.2.2" 1737 | source = "registry+https://github.com/rust-lang/crates.io-index" 1738 | checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" 1739 | dependencies = [ 1740 | "bitflags 2.6.0", 1741 | "block2", 1742 | "objc2", 1743 | "objc2-foundation", 1744 | "objc2-metal", 1745 | ] 1746 | 1747 | [[package]] 1748 | name = "objc2-symbols" 1749 | version = "0.2.2" 1750 | source = "registry+https://github.com/rust-lang/crates.io-index" 1751 | checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" 1752 | dependencies = [ 1753 | "objc2", 1754 | "objc2-foundation", 1755 | ] 1756 | 1757 | [[package]] 1758 | name = "objc2-ui-kit" 1759 | version = "0.2.2" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" 1762 | dependencies = [ 1763 | "bitflags 2.6.0", 1764 | "block2", 1765 | "objc2", 1766 | "objc2-cloud-kit", 1767 | "objc2-core-data", 1768 | "objc2-core-image", 1769 | "objc2-core-location", 1770 | "objc2-foundation", 1771 | "objc2-link-presentation", 1772 | "objc2-quartz-core", 1773 | "objc2-symbols", 1774 | "objc2-uniform-type-identifiers", 1775 | "objc2-user-notifications", 1776 | ] 1777 | 1778 | [[package]] 1779 | name = "objc2-uniform-type-identifiers" 1780 | version = "0.2.2" 1781 | source = "registry+https://github.com/rust-lang/crates.io-index" 1782 | checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" 1783 | dependencies = [ 1784 | "block2", 1785 | "objc2", 1786 | "objc2-foundation", 1787 | ] 1788 | 1789 | [[package]] 1790 | name = "objc2-user-notifications" 1791 | version = "0.2.2" 1792 | source = "registry+https://github.com/rust-lang/crates.io-index" 1793 | checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" 1794 | dependencies = [ 1795 | "bitflags 2.6.0", 1796 | "block2", 1797 | "objc2", 1798 | "objc2-core-location", 1799 | "objc2-foundation", 1800 | ] 1801 | 1802 | [[package]] 1803 | name = "object" 1804 | version = "0.36.5" 1805 | source = "registry+https://github.com/rust-lang/crates.io-index" 1806 | checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" 1807 | dependencies = [ 1808 | "memchr", 1809 | ] 1810 | 1811 | [[package]] 1812 | name = "once_cell" 1813 | version = "1.20.2" 1814 | source = "registry+https://github.com/rust-lang/crates.io-index" 1815 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 1816 | 1817 | [[package]] 1818 | name = "orbclient" 1819 | version = "0.3.48" 1820 | source = "registry+https://github.com/rust-lang/crates.io-index" 1821 | checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" 1822 | dependencies = [ 1823 | "libredox", 1824 | ] 1825 | 1826 | [[package]] 1827 | name = "owned_ttf_parser" 1828 | version = "0.25.0" 1829 | source = "registry+https://github.com/rust-lang/crates.io-index" 1830 | checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" 1831 | dependencies = [ 1832 | "ttf-parser", 1833 | ] 1834 | 1835 | [[package]] 1836 | name = "pam" 1837 | version = "0.7.0" 1838 | source = "registry+https://github.com/rust-lang/crates.io-index" 1839 | checksum = "fa2bdc959c201c047004a1420a92aaa1dd1a6b64d5ef333aa3a4ac764fb93097" 1840 | dependencies = [ 1841 | "libc", 1842 | "pam-sys", 1843 | "users 0.8.1", 1844 | ] 1845 | 1846 | [[package]] 1847 | name = "pam-sys" 1848 | version = "0.5.6" 1849 | source = "registry+https://github.com/rust-lang/crates.io-index" 1850 | checksum = "cd4858311a097f01a0006ef7d0cd50bca81ec430c949d7bf95cbefd202282434" 1851 | dependencies = [ 1852 | "libc", 1853 | ] 1854 | 1855 | [[package]] 1856 | name = "parking_lot" 1857 | version = "0.12.3" 1858 | source = "registry+https://github.com/rust-lang/crates.io-index" 1859 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1860 | dependencies = [ 1861 | "lock_api", 1862 | "parking_lot_core", 1863 | ] 1864 | 1865 | [[package]] 1866 | name = "parking_lot_core" 1867 | version = "0.9.10" 1868 | source = "registry+https://github.com/rust-lang/crates.io-index" 1869 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1870 | dependencies = [ 1871 | "cfg-if", 1872 | "libc", 1873 | "redox_syscall 0.5.7", 1874 | "smallvec", 1875 | "windows-targets 0.52.6", 1876 | ] 1877 | 1878 | [[package]] 1879 | name = "paste" 1880 | version = "1.0.15" 1881 | source = "registry+https://github.com/rust-lang/crates.io-index" 1882 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 1883 | 1884 | [[package]] 1885 | name = "percent-encoding" 1886 | version = "2.3.1" 1887 | source = "registry+https://github.com/rust-lang/crates.io-index" 1888 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1889 | 1890 | [[package]] 1891 | name = "petgraph" 1892 | version = "0.6.3" 1893 | source = "registry+https://github.com/rust-lang/crates.io-index" 1894 | checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" 1895 | dependencies = [ 1896 | "fixedbitset", 1897 | "indexmap 1.9.3", 1898 | ] 1899 | 1900 | [[package]] 1901 | name = "pin-project" 1902 | version = "1.1.7" 1903 | source = "registry+https://github.com/rust-lang/crates.io-index" 1904 | checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" 1905 | dependencies = [ 1906 | "pin-project-internal", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "pin-project-internal" 1911 | version = "1.1.7" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" 1914 | dependencies = [ 1915 | "proc-macro2", 1916 | "quote", 1917 | "syn 2.0.80", 1918 | ] 1919 | 1920 | [[package]] 1921 | name = "pin-project-lite" 1922 | version = "0.2.14" 1923 | source = "registry+https://github.com/rust-lang/crates.io-index" 1924 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 1925 | 1926 | [[package]] 1927 | name = "pin-utils" 1928 | version = "0.1.0" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1931 | 1932 | [[package]] 1933 | name = "pkg-config" 1934 | version = "0.3.31" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 1937 | 1938 | [[package]] 1939 | name = "png" 1940 | version = "0.17.14" 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" 1942 | checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" 1943 | dependencies = [ 1944 | "bitflags 1.3.2", 1945 | "crc32fast", 1946 | "fdeflate", 1947 | "flate2", 1948 | "miniz_oxide", 1949 | ] 1950 | 1951 | [[package]] 1952 | name = "polling" 1953 | version = "3.7.3" 1954 | source = "registry+https://github.com/rust-lang/crates.io-index" 1955 | checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" 1956 | dependencies = [ 1957 | "cfg-if", 1958 | "concurrent-queue", 1959 | "hermit-abi 0.4.0", 1960 | "pin-project-lite", 1961 | "rustix", 1962 | "tracing", 1963 | "windows-sys 0.59.0", 1964 | ] 1965 | 1966 | [[package]] 1967 | name = "pollster" 1968 | version = "0.4.0" 1969 | source = "registry+https://github.com/rust-lang/crates.io-index" 1970 | checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" 1971 | 1972 | [[package]] 1973 | name = "ppv-lite86" 1974 | version = "0.2.20" 1975 | source = "registry+https://github.com/rust-lang/crates.io-index" 1976 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1977 | dependencies = [ 1978 | "zerocopy", 1979 | ] 1980 | 1981 | [[package]] 1982 | name = "presser" 1983 | version = "0.3.1" 1984 | source = "registry+https://github.com/rust-lang/crates.io-index" 1985 | checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" 1986 | 1987 | [[package]] 1988 | name = "proc-macro-crate" 1989 | version = "1.3.1" 1990 | source = "registry+https://github.com/rust-lang/crates.io-index" 1991 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 1992 | dependencies = [ 1993 | "once_cell", 1994 | "toml_edit 0.19.15", 1995 | ] 1996 | 1997 | [[package]] 1998 | name = "proc-macro2" 1999 | version = "1.0.88" 2000 | source = "registry+https://github.com/rust-lang/crates.io-index" 2001 | checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" 2002 | dependencies = [ 2003 | "unicode-ident", 2004 | ] 2005 | 2006 | [[package]] 2007 | name = "profiling" 2008 | version = "1.0.16" 2009 | source = "registry+https://github.com/rust-lang/crates.io-index" 2010 | checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" 2011 | dependencies = [ 2012 | "profiling-procmacros", 2013 | ] 2014 | 2015 | [[package]] 2016 | name = "profiling-procmacros" 2017 | version = "1.0.16" 2018 | source = "registry+https://github.com/rust-lang/crates.io-index" 2019 | checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" 2020 | dependencies = [ 2021 | "quote", 2022 | "syn 2.0.80", 2023 | ] 2024 | 2025 | [[package]] 2026 | name = "qoi" 2027 | version = "0.4.1" 2028 | source = "registry+https://github.com/rust-lang/crates.io-index" 2029 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" 2030 | dependencies = [ 2031 | "bytemuck", 2032 | ] 2033 | 2034 | [[package]] 2035 | name = "quick-error" 2036 | version = "2.0.1" 2037 | source = "registry+https://github.com/rust-lang/crates.io-index" 2038 | checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" 2039 | 2040 | [[package]] 2041 | name = "quick-xml" 2042 | version = "0.36.2" 2043 | source = "registry+https://github.com/rust-lang/crates.io-index" 2044 | checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" 2045 | dependencies = [ 2046 | "memchr", 2047 | ] 2048 | 2049 | [[package]] 2050 | name = "quote" 2051 | version = "1.0.37" 2052 | source = "registry+https://github.com/rust-lang/crates.io-index" 2053 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 2054 | dependencies = [ 2055 | "proc-macro2", 2056 | ] 2057 | 2058 | [[package]] 2059 | name = "rand" 2060 | version = "0.8.5" 2061 | source = "registry+https://github.com/rust-lang/crates.io-index" 2062 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 2063 | dependencies = [ 2064 | "libc", 2065 | "rand_chacha", 2066 | "rand_core", 2067 | ] 2068 | 2069 | [[package]] 2070 | name = "rand_chacha" 2071 | version = "0.3.1" 2072 | source = "registry+https://github.com/rust-lang/crates.io-index" 2073 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 2074 | dependencies = [ 2075 | "ppv-lite86", 2076 | "rand_core", 2077 | ] 2078 | 2079 | [[package]] 2080 | name = "rand_core" 2081 | version = "0.6.4" 2082 | source = "registry+https://github.com/rust-lang/crates.io-index" 2083 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 2084 | dependencies = [ 2085 | "getrandom", 2086 | ] 2087 | 2088 | [[package]] 2089 | name = "range-alloc" 2090 | version = "0.1.3" 2091 | source = "registry+https://github.com/rust-lang/crates.io-index" 2092 | checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" 2093 | 2094 | [[package]] 2095 | name = "rav1e" 2096 | version = "0.7.1" 2097 | source = "registry+https://github.com/rust-lang/crates.io-index" 2098 | checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" 2099 | dependencies = [ 2100 | "arbitrary", 2101 | "arg_enum_proc_macro", 2102 | "arrayvec", 2103 | "av1-grain", 2104 | "bitstream-io", 2105 | "built", 2106 | "cfg-if", 2107 | "interpolate_name", 2108 | "itertools", 2109 | "libc", 2110 | "libfuzzer-sys", 2111 | "log", 2112 | "maybe-rayon", 2113 | "new_debug_unreachable", 2114 | "noop_proc_macro", 2115 | "num-derive", 2116 | "num-traits", 2117 | "once_cell", 2118 | "paste", 2119 | "profiling", 2120 | "rand", 2121 | "rand_chacha", 2122 | "simd_helpers", 2123 | "system-deps", 2124 | "thiserror", 2125 | "v_frame", 2126 | "wasm-bindgen", 2127 | ] 2128 | 2129 | [[package]] 2130 | name = "ravif" 2131 | version = "0.11.11" 2132 | source = "registry+https://github.com/rust-lang/crates.io-index" 2133 | checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" 2134 | dependencies = [ 2135 | "avif-serialize", 2136 | "imgref", 2137 | "loop9", 2138 | "quick-error", 2139 | "rav1e", 2140 | "rayon", 2141 | "rgb", 2142 | ] 2143 | 2144 | [[package]] 2145 | name = "raw-window-handle" 2146 | version = "0.6.2" 2147 | source = "registry+https://github.com/rust-lang/crates.io-index" 2148 | checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" 2149 | 2150 | [[package]] 2151 | name = "rayon" 2152 | version = "1.10.0" 2153 | source = "registry+https://github.com/rust-lang/crates.io-index" 2154 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 2155 | dependencies = [ 2156 | "either", 2157 | "rayon-core", 2158 | ] 2159 | 2160 | [[package]] 2161 | name = "rayon-core" 2162 | version = "1.12.1" 2163 | source = "registry+https://github.com/rust-lang/crates.io-index" 2164 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 2165 | dependencies = [ 2166 | "crossbeam-deque", 2167 | "crossbeam-utils", 2168 | ] 2169 | 2170 | [[package]] 2171 | name = "redox_syscall" 2172 | version = "0.4.1" 2173 | source = "registry+https://github.com/rust-lang/crates.io-index" 2174 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 2175 | dependencies = [ 2176 | "bitflags 1.3.2", 2177 | ] 2178 | 2179 | [[package]] 2180 | name = "redox_syscall" 2181 | version = "0.5.7" 2182 | source = "registry+https://github.com/rust-lang/crates.io-index" 2183 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" 2184 | dependencies = [ 2185 | "bitflags 2.6.0", 2186 | ] 2187 | 2188 | [[package]] 2189 | name = "regex" 2190 | version = "1.11.0" 2191 | source = "registry+https://github.com/rust-lang/crates.io-index" 2192 | checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" 2193 | dependencies = [ 2194 | "aho-corasick", 2195 | "memchr", 2196 | "regex-automata", 2197 | "regex-syntax", 2198 | ] 2199 | 2200 | [[package]] 2201 | name = "regex-automata" 2202 | version = "0.4.8" 2203 | source = "registry+https://github.com/rust-lang/crates.io-index" 2204 | checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" 2205 | dependencies = [ 2206 | "aho-corasick", 2207 | "memchr", 2208 | "regex-syntax", 2209 | ] 2210 | 2211 | [[package]] 2212 | name = "regex-syntax" 2213 | version = "0.8.5" 2214 | source = "registry+https://github.com/rust-lang/crates.io-index" 2215 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 2216 | 2217 | [[package]] 2218 | name = "renderdoc-sys" 2219 | version = "1.1.0" 2220 | source = "registry+https://github.com/rust-lang/crates.io-index" 2221 | checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" 2222 | 2223 | [[package]] 2224 | name = "rgb" 2225 | version = "0.8.50" 2226 | source = "registry+https://github.com/rust-lang/crates.io-index" 2227 | checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" 2228 | 2229 | [[package]] 2230 | name = "roxmltree" 2231 | version = "0.14.1" 2232 | source = "registry+https://github.com/rust-lang/crates.io-index" 2233 | checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" 2234 | dependencies = [ 2235 | "xmlparser", 2236 | ] 2237 | 2238 | [[package]] 2239 | name = "rustc-demangle" 2240 | version = "0.1.24" 2241 | source = "registry+https://github.com/rust-lang/crates.io-index" 2242 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 2243 | 2244 | [[package]] 2245 | name = "rustc-hash" 2246 | version = "1.1.0" 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" 2248 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 2249 | 2250 | [[package]] 2251 | name = "rustix" 2252 | version = "0.38.37" 2253 | source = "registry+https://github.com/rust-lang/crates.io-index" 2254 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 2255 | dependencies = [ 2256 | "bitflags 2.6.0", 2257 | "errno", 2258 | "libc", 2259 | "linux-raw-sys", 2260 | "windows-sys 0.52.0", 2261 | ] 2262 | 2263 | [[package]] 2264 | name = "same-file" 2265 | version = "1.0.6" 2266 | source = "registry+https://github.com/rust-lang/crates.io-index" 2267 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 2268 | dependencies = [ 2269 | "winapi-util", 2270 | ] 2271 | 2272 | [[package]] 2273 | name = "scoped-tls" 2274 | version = "1.0.1" 2275 | source = "registry+https://github.com/rust-lang/crates.io-index" 2276 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 2277 | 2278 | [[package]] 2279 | name = "scopeguard" 2280 | version = "1.2.0" 2281 | source = "registry+https://github.com/rust-lang/crates.io-index" 2282 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 2283 | 2284 | [[package]] 2285 | name = "sctk-adwaita" 2286 | version = "0.10.1" 2287 | source = "registry+https://github.com/rust-lang/crates.io-index" 2288 | checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" 2289 | dependencies = [ 2290 | "ab_glyph", 2291 | "log", 2292 | "memmap2 0.9.5", 2293 | "smithay-client-toolkit", 2294 | "tiny-skia", 2295 | ] 2296 | 2297 | [[package]] 2298 | name = "sd-notify" 2299 | version = "0.4.3" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "1be20c5f7f393ee700f8b2f28ea35812e4e212f40774b550cd2a93ea91684451" 2302 | 2303 | [[package]] 2304 | name = "serde" 2305 | version = "1.0.210" 2306 | source = "registry+https://github.com/rust-lang/crates.io-index" 2307 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 2308 | dependencies = [ 2309 | "serde_derive", 2310 | ] 2311 | 2312 | [[package]] 2313 | name = "serde_derive" 2314 | version = "1.0.210" 2315 | source = "registry+https://github.com/rust-lang/crates.io-index" 2316 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 2317 | dependencies = [ 2318 | "proc-macro2", 2319 | "quote", 2320 | "syn 2.0.80", 2321 | ] 2322 | 2323 | [[package]] 2324 | name = "serde_spanned" 2325 | version = "0.6.8" 2326 | source = "registry+https://github.com/rust-lang/crates.io-index" 2327 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 2328 | dependencies = [ 2329 | "serde", 2330 | ] 2331 | 2332 | [[package]] 2333 | name = "shaderc" 2334 | version = "0.8.3" 2335 | source = "registry+https://github.com/rust-lang/crates.io-index" 2336 | checksum = "27e07913ada18607bb60d12431cbe3358d3bbebbe95948e1618851dc01e63b7b" 2337 | dependencies = [ 2338 | "libc", 2339 | "shaderc-sys", 2340 | ] 2341 | 2342 | [[package]] 2343 | name = "shaderc-sys" 2344 | version = "0.8.3" 2345 | source = "registry+https://github.com/rust-lang/crates.io-index" 2346 | checksum = "73120d240fe22196300f39ca8547ca2d014960f27b19b47b21288b396272f7f7" 2347 | dependencies = [ 2348 | "cmake", 2349 | "libc", 2350 | "roxmltree", 2351 | ] 2352 | 2353 | [[package]] 2354 | name = "shaderlock" 2355 | version = "0.3.0" 2356 | dependencies = [ 2357 | "anyhow", 2358 | "arrayvec", 2359 | "bytemuck", 2360 | "cgmath", 2361 | "clap", 2362 | "dashmap", 2363 | "either", 2364 | "env_logger", 2365 | "futures", 2366 | "glob", 2367 | "image", 2368 | "log", 2369 | "pam", 2370 | "pollster", 2371 | "rand", 2372 | "sd-notify", 2373 | "shaderc", 2374 | "smithay-client-toolkit", 2375 | "tokio", 2376 | "users 0.11.0", 2377 | "wgpu", 2378 | "winit", 2379 | ] 2380 | 2381 | [[package]] 2382 | name = "shlex" 2383 | version = "1.3.0" 2384 | source = "registry+https://github.com/rust-lang/crates.io-index" 2385 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 2386 | 2387 | [[package]] 2388 | name = "signal-hook-registry" 2389 | version = "1.4.2" 2390 | source = "registry+https://github.com/rust-lang/crates.io-index" 2391 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 2392 | dependencies = [ 2393 | "libc", 2394 | ] 2395 | 2396 | [[package]] 2397 | name = "simd-adler32" 2398 | version = "0.3.7" 2399 | source = "registry+https://github.com/rust-lang/crates.io-index" 2400 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 2401 | 2402 | [[package]] 2403 | name = "simd_helpers" 2404 | version = "0.1.0" 2405 | source = "registry+https://github.com/rust-lang/crates.io-index" 2406 | checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" 2407 | dependencies = [ 2408 | "quote", 2409 | ] 2410 | 2411 | [[package]] 2412 | name = "slab" 2413 | version = "0.4.9" 2414 | source = "registry+https://github.com/rust-lang/crates.io-index" 2415 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 2416 | dependencies = [ 2417 | "autocfg", 2418 | ] 2419 | 2420 | [[package]] 2421 | name = "slotmap" 2422 | version = "1.0.7" 2423 | source = "registry+https://github.com/rust-lang/crates.io-index" 2424 | checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" 2425 | dependencies = [ 2426 | "version_check", 2427 | ] 2428 | 2429 | [[package]] 2430 | name = "smallvec" 2431 | version = "1.13.2" 2432 | source = "registry+https://github.com/rust-lang/crates.io-index" 2433 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 2434 | 2435 | [[package]] 2436 | name = "smithay-client-toolkit" 2437 | version = "0.19.2" 2438 | source = "registry+https://github.com/rust-lang/crates.io-index" 2439 | checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" 2440 | dependencies = [ 2441 | "bitflags 2.6.0", 2442 | "bytemuck", 2443 | "calloop", 2444 | "calloop-wayland-source", 2445 | "cursor-icon", 2446 | "libc", 2447 | "log", 2448 | "memmap2 0.9.5", 2449 | "pkg-config", 2450 | "rustix", 2451 | "thiserror", 2452 | "wayland-backend", 2453 | "wayland-client", 2454 | "wayland-csd-frame", 2455 | "wayland-cursor", 2456 | "wayland-protocols", 2457 | "wayland-protocols-wlr", 2458 | "wayland-scanner", 2459 | "xkbcommon", 2460 | "xkeysym", 2461 | ] 2462 | 2463 | [[package]] 2464 | name = "smol_str" 2465 | version = "0.2.2" 2466 | source = "registry+https://github.com/rust-lang/crates.io-index" 2467 | checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" 2468 | dependencies = [ 2469 | "serde", 2470 | ] 2471 | 2472 | [[package]] 2473 | name = "socket2" 2474 | version = "0.5.7" 2475 | source = "registry+https://github.com/rust-lang/crates.io-index" 2476 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 2477 | dependencies = [ 2478 | "libc", 2479 | "windows-sys 0.52.0", 2480 | ] 2481 | 2482 | [[package]] 2483 | name = "spirv" 2484 | version = "0.3.0+sdk-1.3.268.0" 2485 | source = "registry+https://github.com/rust-lang/crates.io-index" 2486 | checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" 2487 | dependencies = [ 2488 | "bitflags 2.6.0", 2489 | ] 2490 | 2491 | [[package]] 2492 | name = "static_assertions" 2493 | version = "1.1.0" 2494 | source = "registry+https://github.com/rust-lang/crates.io-index" 2495 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 2496 | 2497 | [[package]] 2498 | name = "strict-num" 2499 | version = "0.1.1" 2500 | source = "registry+https://github.com/rust-lang/crates.io-index" 2501 | checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" 2502 | 2503 | [[package]] 2504 | name = "strsim" 2505 | version = "0.11.1" 2506 | source = "registry+https://github.com/rust-lang/crates.io-index" 2507 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 2508 | 2509 | [[package]] 2510 | name = "syn" 2511 | version = "1.0.109" 2512 | source = "registry+https://github.com/rust-lang/crates.io-index" 2513 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2514 | dependencies = [ 2515 | "proc-macro2", 2516 | "quote", 2517 | "unicode-ident", 2518 | ] 2519 | 2520 | [[package]] 2521 | name = "syn" 2522 | version = "2.0.80" 2523 | source = "registry+https://github.com/rust-lang/crates.io-index" 2524 | checksum = "e6e185e337f816bc8da115b8afcb3324006ccc82eeaddf35113888d3bd8e44ac" 2525 | dependencies = [ 2526 | "proc-macro2", 2527 | "quote", 2528 | "unicode-ident", 2529 | ] 2530 | 2531 | [[package]] 2532 | name = "system-deps" 2533 | version = "6.2.2" 2534 | source = "registry+https://github.com/rust-lang/crates.io-index" 2535 | checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" 2536 | dependencies = [ 2537 | "cfg-expr", 2538 | "heck", 2539 | "pkg-config", 2540 | "toml", 2541 | "version-compare", 2542 | ] 2543 | 2544 | [[package]] 2545 | name = "target-lexicon" 2546 | version = "0.12.16" 2547 | source = "registry+https://github.com/rust-lang/crates.io-index" 2548 | checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" 2549 | 2550 | [[package]] 2551 | name = "termcolor" 2552 | version = "1.4.1" 2553 | source = "registry+https://github.com/rust-lang/crates.io-index" 2554 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 2555 | dependencies = [ 2556 | "winapi-util", 2557 | ] 2558 | 2559 | [[package]] 2560 | name = "thiserror" 2561 | version = "1.0.64" 2562 | source = "registry+https://github.com/rust-lang/crates.io-index" 2563 | checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" 2564 | dependencies = [ 2565 | "thiserror-impl", 2566 | ] 2567 | 2568 | [[package]] 2569 | name = "thiserror-impl" 2570 | version = "1.0.64" 2571 | source = "registry+https://github.com/rust-lang/crates.io-index" 2572 | checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" 2573 | dependencies = [ 2574 | "proc-macro2", 2575 | "quote", 2576 | "syn 2.0.80", 2577 | ] 2578 | 2579 | [[package]] 2580 | name = "tiff" 2581 | version = "0.9.1" 2582 | source = "registry+https://github.com/rust-lang/crates.io-index" 2583 | checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" 2584 | dependencies = [ 2585 | "flate2", 2586 | "jpeg-decoder", 2587 | "weezl", 2588 | ] 2589 | 2590 | [[package]] 2591 | name = "tiny-skia" 2592 | version = "0.11.4" 2593 | source = "registry+https://github.com/rust-lang/crates.io-index" 2594 | checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" 2595 | dependencies = [ 2596 | "arrayref", 2597 | "arrayvec", 2598 | "bytemuck", 2599 | "cfg-if", 2600 | "log", 2601 | "tiny-skia-path", 2602 | ] 2603 | 2604 | [[package]] 2605 | name = "tiny-skia-path" 2606 | version = "0.11.4" 2607 | source = "registry+https://github.com/rust-lang/crates.io-index" 2608 | checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" 2609 | dependencies = [ 2610 | "arrayref", 2611 | "bytemuck", 2612 | "strict-num", 2613 | ] 2614 | 2615 | [[package]] 2616 | name = "tokio" 2617 | version = "1.40.0" 2618 | source = "registry+https://github.com/rust-lang/crates.io-index" 2619 | checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" 2620 | dependencies = [ 2621 | "backtrace", 2622 | "bytes", 2623 | "libc", 2624 | "mio", 2625 | "parking_lot", 2626 | "pin-project-lite", 2627 | "signal-hook-registry", 2628 | "socket2", 2629 | "tokio-macros", 2630 | "windows-sys 0.52.0", 2631 | ] 2632 | 2633 | [[package]] 2634 | name = "tokio-macros" 2635 | version = "2.4.0" 2636 | source = "registry+https://github.com/rust-lang/crates.io-index" 2637 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 2638 | dependencies = [ 2639 | "proc-macro2", 2640 | "quote", 2641 | "syn 2.0.80", 2642 | ] 2643 | 2644 | [[package]] 2645 | name = "toml" 2646 | version = "0.8.19" 2647 | source = "registry+https://github.com/rust-lang/crates.io-index" 2648 | checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" 2649 | dependencies = [ 2650 | "serde", 2651 | "serde_spanned", 2652 | "toml_datetime", 2653 | "toml_edit 0.22.22", 2654 | ] 2655 | 2656 | [[package]] 2657 | name = "toml_datetime" 2658 | version = "0.6.8" 2659 | source = "registry+https://github.com/rust-lang/crates.io-index" 2660 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 2661 | dependencies = [ 2662 | "serde", 2663 | ] 2664 | 2665 | [[package]] 2666 | name = "toml_edit" 2667 | version = "0.19.15" 2668 | source = "registry+https://github.com/rust-lang/crates.io-index" 2669 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 2670 | dependencies = [ 2671 | "indexmap 2.6.0", 2672 | "toml_datetime", 2673 | "winnow 0.5.40", 2674 | ] 2675 | 2676 | [[package]] 2677 | name = "toml_edit" 2678 | version = "0.22.22" 2679 | source = "registry+https://github.com/rust-lang/crates.io-index" 2680 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" 2681 | dependencies = [ 2682 | "indexmap 2.6.0", 2683 | "serde", 2684 | "serde_spanned", 2685 | "toml_datetime", 2686 | "winnow 0.6.20", 2687 | ] 2688 | 2689 | [[package]] 2690 | name = "tracing" 2691 | version = "0.1.40" 2692 | source = "registry+https://github.com/rust-lang/crates.io-index" 2693 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 2694 | dependencies = [ 2695 | "pin-project-lite", 2696 | "tracing-core", 2697 | ] 2698 | 2699 | [[package]] 2700 | name = "tracing-core" 2701 | version = "0.1.32" 2702 | source = "registry+https://github.com/rust-lang/crates.io-index" 2703 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 2704 | 2705 | [[package]] 2706 | name = "ttf-parser" 2707 | version = "0.25.0" 2708 | source = "registry+https://github.com/rust-lang/crates.io-index" 2709 | checksum = "5902c5d130972a0000f60860bfbf46f7ca3db5391eddfedd1b8728bd9dc96c0e" 2710 | 2711 | [[package]] 2712 | name = "unicode-ident" 2713 | version = "1.0.13" 2714 | source = "registry+https://github.com/rust-lang/crates.io-index" 2715 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 2716 | 2717 | [[package]] 2718 | name = "unicode-segmentation" 2719 | version = "1.12.0" 2720 | source = "registry+https://github.com/rust-lang/crates.io-index" 2721 | checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 2722 | 2723 | [[package]] 2724 | name = "unicode-width" 2725 | version = "0.1.14" 2726 | source = "registry+https://github.com/rust-lang/crates.io-index" 2727 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 2728 | 2729 | [[package]] 2730 | name = "unicode-xid" 2731 | version = "0.2.6" 2732 | source = "registry+https://github.com/rust-lang/crates.io-index" 2733 | checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 2734 | 2735 | [[package]] 2736 | name = "users" 2737 | version = "0.8.1" 2738 | source = "registry+https://github.com/rust-lang/crates.io-index" 2739 | checksum = "7fed7d0912567d35f88010c23dbaf865e9da8b5227295e8dc0f2fdd109155ab7" 2740 | dependencies = [ 2741 | "libc", 2742 | ] 2743 | 2744 | [[package]] 2745 | name = "users" 2746 | version = "0.11.0" 2747 | source = "registry+https://github.com/rust-lang/crates.io-index" 2748 | checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" 2749 | dependencies = [ 2750 | "libc", 2751 | "log", 2752 | ] 2753 | 2754 | [[package]] 2755 | name = "utf8parse" 2756 | version = "0.2.2" 2757 | source = "registry+https://github.com/rust-lang/crates.io-index" 2758 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2759 | 2760 | [[package]] 2761 | name = "v_frame" 2762 | version = "0.3.8" 2763 | source = "registry+https://github.com/rust-lang/crates.io-index" 2764 | checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" 2765 | dependencies = [ 2766 | "aligned-vec", 2767 | "num-traits", 2768 | "wasm-bindgen", 2769 | ] 2770 | 2771 | [[package]] 2772 | name = "version-compare" 2773 | version = "0.2.0" 2774 | source = "registry+https://github.com/rust-lang/crates.io-index" 2775 | checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" 2776 | 2777 | [[package]] 2778 | name = "version_check" 2779 | version = "0.9.5" 2780 | source = "registry+https://github.com/rust-lang/crates.io-index" 2781 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2782 | 2783 | [[package]] 2784 | name = "walkdir" 2785 | version = "2.5.0" 2786 | source = "registry+https://github.com/rust-lang/crates.io-index" 2787 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 2788 | dependencies = [ 2789 | "same-file", 2790 | "winapi-util", 2791 | ] 2792 | 2793 | [[package]] 2794 | name = "wasi" 2795 | version = "0.11.0+wasi-snapshot-preview1" 2796 | source = "registry+https://github.com/rust-lang/crates.io-index" 2797 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2798 | 2799 | [[package]] 2800 | name = "wasm-bindgen" 2801 | version = "0.2.95" 2802 | source = "registry+https://github.com/rust-lang/crates.io-index" 2803 | checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" 2804 | dependencies = [ 2805 | "cfg-if", 2806 | "once_cell", 2807 | "wasm-bindgen-macro", 2808 | ] 2809 | 2810 | [[package]] 2811 | name = "wasm-bindgen-backend" 2812 | version = "0.2.95" 2813 | source = "registry+https://github.com/rust-lang/crates.io-index" 2814 | checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" 2815 | dependencies = [ 2816 | "bumpalo", 2817 | "log", 2818 | "once_cell", 2819 | "proc-macro2", 2820 | "quote", 2821 | "syn 2.0.80", 2822 | "wasm-bindgen-shared", 2823 | ] 2824 | 2825 | [[package]] 2826 | name = "wasm-bindgen-futures" 2827 | version = "0.4.45" 2828 | source = "registry+https://github.com/rust-lang/crates.io-index" 2829 | checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" 2830 | dependencies = [ 2831 | "cfg-if", 2832 | "js-sys", 2833 | "wasm-bindgen", 2834 | "web-sys", 2835 | ] 2836 | 2837 | [[package]] 2838 | name = "wasm-bindgen-macro" 2839 | version = "0.2.95" 2840 | source = "registry+https://github.com/rust-lang/crates.io-index" 2841 | checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" 2842 | dependencies = [ 2843 | "quote", 2844 | "wasm-bindgen-macro-support", 2845 | ] 2846 | 2847 | [[package]] 2848 | name = "wasm-bindgen-macro-support" 2849 | version = "0.2.95" 2850 | source = "registry+https://github.com/rust-lang/crates.io-index" 2851 | checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" 2852 | dependencies = [ 2853 | "proc-macro2", 2854 | "quote", 2855 | "syn 2.0.80", 2856 | "wasm-bindgen-backend", 2857 | "wasm-bindgen-shared", 2858 | ] 2859 | 2860 | [[package]] 2861 | name = "wasm-bindgen-shared" 2862 | version = "0.2.95" 2863 | source = "registry+https://github.com/rust-lang/crates.io-index" 2864 | checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" 2865 | 2866 | [[package]] 2867 | name = "wayland-backend" 2868 | version = "0.3.7" 2869 | source = "registry+https://github.com/rust-lang/crates.io-index" 2870 | checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" 2871 | dependencies = [ 2872 | "cc", 2873 | "downcast-rs", 2874 | "rustix", 2875 | "scoped-tls", 2876 | "smallvec", 2877 | "wayland-sys", 2878 | ] 2879 | 2880 | [[package]] 2881 | name = "wayland-client" 2882 | version = "0.31.7" 2883 | source = "registry+https://github.com/rust-lang/crates.io-index" 2884 | checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" 2885 | dependencies = [ 2886 | "bitflags 2.6.0", 2887 | "rustix", 2888 | "wayland-backend", 2889 | "wayland-scanner", 2890 | ] 2891 | 2892 | [[package]] 2893 | name = "wayland-csd-frame" 2894 | version = "0.3.0" 2895 | source = "registry+https://github.com/rust-lang/crates.io-index" 2896 | checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" 2897 | dependencies = [ 2898 | "bitflags 2.6.0", 2899 | "cursor-icon", 2900 | "wayland-backend", 2901 | ] 2902 | 2903 | [[package]] 2904 | name = "wayland-cursor" 2905 | version = "0.31.7" 2906 | source = "registry+https://github.com/rust-lang/crates.io-index" 2907 | checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" 2908 | dependencies = [ 2909 | "rustix", 2910 | "wayland-client", 2911 | "xcursor", 2912 | ] 2913 | 2914 | [[package]] 2915 | name = "wayland-protocols" 2916 | version = "0.32.5" 2917 | source = "registry+https://github.com/rust-lang/crates.io-index" 2918 | checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" 2919 | dependencies = [ 2920 | "bitflags 2.6.0", 2921 | "wayland-backend", 2922 | "wayland-client", 2923 | "wayland-scanner", 2924 | ] 2925 | 2926 | [[package]] 2927 | name = "wayland-protocols-plasma" 2928 | version = "0.3.5" 2929 | source = "registry+https://github.com/rust-lang/crates.io-index" 2930 | checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" 2931 | dependencies = [ 2932 | "bitflags 2.6.0", 2933 | "wayland-backend", 2934 | "wayland-client", 2935 | "wayland-protocols", 2936 | "wayland-scanner", 2937 | ] 2938 | 2939 | [[package]] 2940 | name = "wayland-protocols-wlr" 2941 | version = "0.3.5" 2942 | source = "registry+https://github.com/rust-lang/crates.io-index" 2943 | checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" 2944 | dependencies = [ 2945 | "bitflags 2.6.0", 2946 | "wayland-backend", 2947 | "wayland-client", 2948 | "wayland-protocols", 2949 | "wayland-scanner", 2950 | ] 2951 | 2952 | [[package]] 2953 | name = "wayland-scanner" 2954 | version = "0.31.5" 2955 | source = "registry+https://github.com/rust-lang/crates.io-index" 2956 | checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" 2957 | dependencies = [ 2958 | "proc-macro2", 2959 | "quick-xml", 2960 | "quote", 2961 | ] 2962 | 2963 | [[package]] 2964 | name = "wayland-sys" 2965 | version = "0.31.5" 2966 | source = "registry+https://github.com/rust-lang/crates.io-index" 2967 | checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" 2968 | dependencies = [ 2969 | "dlib", 2970 | "log", 2971 | "once_cell", 2972 | "pkg-config", 2973 | ] 2974 | 2975 | [[package]] 2976 | name = "web-sys" 2977 | version = "0.3.72" 2978 | source = "registry+https://github.com/rust-lang/crates.io-index" 2979 | checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" 2980 | dependencies = [ 2981 | "js-sys", 2982 | "wasm-bindgen", 2983 | ] 2984 | 2985 | [[package]] 2986 | name = "web-time" 2987 | version = "1.1.0" 2988 | source = "registry+https://github.com/rust-lang/crates.io-index" 2989 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2990 | dependencies = [ 2991 | "js-sys", 2992 | "wasm-bindgen", 2993 | ] 2994 | 2995 | [[package]] 2996 | name = "weezl" 2997 | version = "0.1.8" 2998 | source = "registry+https://github.com/rust-lang/crates.io-index" 2999 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" 3000 | 3001 | [[package]] 3002 | name = "wgpu" 3003 | version = "22.1.0" 3004 | source = "registry+https://github.com/rust-lang/crates.io-index" 3005 | checksum = "e1d1c4ba43f80542cf63a0a6ed3134629ae73e8ab51e4b765a67f3aa062eb433" 3006 | dependencies = [ 3007 | "arrayvec", 3008 | "cfg_aliases 0.1.1", 3009 | "document-features", 3010 | "js-sys", 3011 | "log", 3012 | "naga", 3013 | "parking_lot", 3014 | "profiling", 3015 | "raw-window-handle", 3016 | "smallvec", 3017 | "static_assertions", 3018 | "wasm-bindgen", 3019 | "wasm-bindgen-futures", 3020 | "web-sys", 3021 | "wgpu-core", 3022 | "wgpu-hal", 3023 | "wgpu-types", 3024 | ] 3025 | 3026 | [[package]] 3027 | name = "wgpu-core" 3028 | version = "22.1.0" 3029 | source = "registry+https://github.com/rust-lang/crates.io-index" 3030 | checksum = "0348c840d1051b8e86c3bcd31206080c5e71e5933dabd79be1ce732b0b2f089a" 3031 | dependencies = [ 3032 | "arrayvec", 3033 | "bit-vec", 3034 | "bitflags 2.6.0", 3035 | "bytemuck", 3036 | "cfg_aliases 0.1.1", 3037 | "document-features", 3038 | "indexmap 2.6.0", 3039 | "log", 3040 | "naga", 3041 | "once_cell", 3042 | "parking_lot", 3043 | "profiling", 3044 | "raw-window-handle", 3045 | "rustc-hash", 3046 | "smallvec", 3047 | "thiserror", 3048 | "wgpu-hal", 3049 | "wgpu-types", 3050 | ] 3051 | 3052 | [[package]] 3053 | name = "wgpu-hal" 3054 | version = "22.0.0" 3055 | source = "registry+https://github.com/rust-lang/crates.io-index" 3056 | checksum = "f6bbf4b4de8b2a83c0401d9e5ae0080a2792055f25859a02bf9be97952bbed4f" 3057 | dependencies = [ 3058 | "android_system_properties", 3059 | "arrayvec", 3060 | "ash", 3061 | "bit-set", 3062 | "bitflags 2.6.0", 3063 | "block", 3064 | "cfg_aliases 0.1.1", 3065 | "core-graphics-types", 3066 | "d3d12", 3067 | "glow", 3068 | "glutin_wgl_sys", 3069 | "gpu-alloc", 3070 | "gpu-allocator", 3071 | "gpu-descriptor", 3072 | "hassle-rs", 3073 | "js-sys", 3074 | "khronos-egl", 3075 | "libc", 3076 | "libloading", 3077 | "log", 3078 | "metal", 3079 | "naga", 3080 | "ndk-sys 0.5.0+25.2.9519653", 3081 | "objc", 3082 | "once_cell", 3083 | "parking_lot", 3084 | "profiling", 3085 | "range-alloc", 3086 | "raw-window-handle", 3087 | "renderdoc-sys", 3088 | "rustc-hash", 3089 | "smallvec", 3090 | "thiserror", 3091 | "wasm-bindgen", 3092 | "web-sys", 3093 | "wgpu-types", 3094 | "winapi", 3095 | ] 3096 | 3097 | [[package]] 3098 | name = "wgpu-types" 3099 | version = "22.0.0" 3100 | source = "registry+https://github.com/rust-lang/crates.io-index" 3101 | checksum = "bc9d91f0e2c4b51434dfa6db77846f2793149d8e73f800fa2e41f52b8eac3c5d" 3102 | dependencies = [ 3103 | "bitflags 2.6.0", 3104 | "js-sys", 3105 | "web-sys", 3106 | ] 3107 | 3108 | [[package]] 3109 | name = "widestring" 3110 | version = "1.1.0" 3111 | source = "registry+https://github.com/rust-lang/crates.io-index" 3112 | checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" 3113 | 3114 | [[package]] 3115 | name = "winapi" 3116 | version = "0.3.9" 3117 | source = "registry+https://github.com/rust-lang/crates.io-index" 3118 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 3119 | dependencies = [ 3120 | "winapi-i686-pc-windows-gnu", 3121 | "winapi-x86_64-pc-windows-gnu", 3122 | ] 3123 | 3124 | [[package]] 3125 | name = "winapi-i686-pc-windows-gnu" 3126 | version = "0.4.0" 3127 | source = "registry+https://github.com/rust-lang/crates.io-index" 3128 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 3129 | 3130 | [[package]] 3131 | name = "winapi-util" 3132 | version = "0.1.9" 3133 | source = "registry+https://github.com/rust-lang/crates.io-index" 3134 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 3135 | dependencies = [ 3136 | "windows-sys 0.59.0", 3137 | ] 3138 | 3139 | [[package]] 3140 | name = "winapi-x86_64-pc-windows-gnu" 3141 | version = "0.4.0" 3142 | source = "registry+https://github.com/rust-lang/crates.io-index" 3143 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 3144 | 3145 | [[package]] 3146 | name = "windows" 3147 | version = "0.52.0" 3148 | source = "registry+https://github.com/rust-lang/crates.io-index" 3149 | checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" 3150 | dependencies = [ 3151 | "windows-core", 3152 | "windows-targets 0.52.6", 3153 | ] 3154 | 3155 | [[package]] 3156 | name = "windows-core" 3157 | version = "0.52.0" 3158 | source = "registry+https://github.com/rust-lang/crates.io-index" 3159 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 3160 | dependencies = [ 3161 | "windows-targets 0.52.6", 3162 | ] 3163 | 3164 | [[package]] 3165 | name = "windows-sys" 3166 | version = "0.45.0" 3167 | source = "registry+https://github.com/rust-lang/crates.io-index" 3168 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 3169 | dependencies = [ 3170 | "windows-targets 0.42.2", 3171 | ] 3172 | 3173 | [[package]] 3174 | name = "windows-sys" 3175 | version = "0.52.0" 3176 | source = "registry+https://github.com/rust-lang/crates.io-index" 3177 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 3178 | dependencies = [ 3179 | "windows-targets 0.52.6", 3180 | ] 3181 | 3182 | [[package]] 3183 | name = "windows-sys" 3184 | version = "0.59.0" 3185 | source = "registry+https://github.com/rust-lang/crates.io-index" 3186 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 3187 | dependencies = [ 3188 | "windows-targets 0.52.6", 3189 | ] 3190 | 3191 | [[package]] 3192 | name = "windows-targets" 3193 | version = "0.42.2" 3194 | source = "registry+https://github.com/rust-lang/crates.io-index" 3195 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 3196 | dependencies = [ 3197 | "windows_aarch64_gnullvm 0.42.2", 3198 | "windows_aarch64_msvc 0.42.2", 3199 | "windows_i686_gnu 0.42.2", 3200 | "windows_i686_msvc 0.42.2", 3201 | "windows_x86_64_gnu 0.42.2", 3202 | "windows_x86_64_gnullvm 0.42.2", 3203 | "windows_x86_64_msvc 0.42.2", 3204 | ] 3205 | 3206 | [[package]] 3207 | name = "windows-targets" 3208 | version = "0.48.5" 3209 | source = "registry+https://github.com/rust-lang/crates.io-index" 3210 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 3211 | dependencies = [ 3212 | "windows_aarch64_gnullvm 0.48.5", 3213 | "windows_aarch64_msvc 0.48.5", 3214 | "windows_i686_gnu 0.48.5", 3215 | "windows_i686_msvc 0.48.5", 3216 | "windows_x86_64_gnu 0.48.5", 3217 | "windows_x86_64_gnullvm 0.48.5", 3218 | "windows_x86_64_msvc 0.48.5", 3219 | ] 3220 | 3221 | [[package]] 3222 | name = "windows-targets" 3223 | version = "0.52.6" 3224 | source = "registry+https://github.com/rust-lang/crates.io-index" 3225 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 3226 | dependencies = [ 3227 | "windows_aarch64_gnullvm 0.52.6", 3228 | "windows_aarch64_msvc 0.52.6", 3229 | "windows_i686_gnu 0.52.6", 3230 | "windows_i686_gnullvm", 3231 | "windows_i686_msvc 0.52.6", 3232 | "windows_x86_64_gnu 0.52.6", 3233 | "windows_x86_64_gnullvm 0.52.6", 3234 | "windows_x86_64_msvc 0.52.6", 3235 | ] 3236 | 3237 | [[package]] 3238 | name = "windows_aarch64_gnullvm" 3239 | version = "0.42.2" 3240 | source = "registry+https://github.com/rust-lang/crates.io-index" 3241 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 3242 | 3243 | [[package]] 3244 | name = "windows_aarch64_gnullvm" 3245 | version = "0.48.5" 3246 | source = "registry+https://github.com/rust-lang/crates.io-index" 3247 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 3248 | 3249 | [[package]] 3250 | name = "windows_aarch64_gnullvm" 3251 | version = "0.52.6" 3252 | source = "registry+https://github.com/rust-lang/crates.io-index" 3253 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 3254 | 3255 | [[package]] 3256 | name = "windows_aarch64_msvc" 3257 | version = "0.42.2" 3258 | source = "registry+https://github.com/rust-lang/crates.io-index" 3259 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 3260 | 3261 | [[package]] 3262 | name = "windows_aarch64_msvc" 3263 | version = "0.48.5" 3264 | source = "registry+https://github.com/rust-lang/crates.io-index" 3265 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 3266 | 3267 | [[package]] 3268 | name = "windows_aarch64_msvc" 3269 | version = "0.52.6" 3270 | source = "registry+https://github.com/rust-lang/crates.io-index" 3271 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 3272 | 3273 | [[package]] 3274 | name = "windows_i686_gnu" 3275 | version = "0.42.2" 3276 | source = "registry+https://github.com/rust-lang/crates.io-index" 3277 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 3278 | 3279 | [[package]] 3280 | name = "windows_i686_gnu" 3281 | version = "0.48.5" 3282 | source = "registry+https://github.com/rust-lang/crates.io-index" 3283 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 3284 | 3285 | [[package]] 3286 | name = "windows_i686_gnu" 3287 | version = "0.52.6" 3288 | source = "registry+https://github.com/rust-lang/crates.io-index" 3289 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 3290 | 3291 | [[package]] 3292 | name = "windows_i686_gnullvm" 3293 | version = "0.52.6" 3294 | source = "registry+https://github.com/rust-lang/crates.io-index" 3295 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 3296 | 3297 | [[package]] 3298 | name = "windows_i686_msvc" 3299 | version = "0.42.2" 3300 | source = "registry+https://github.com/rust-lang/crates.io-index" 3301 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 3302 | 3303 | [[package]] 3304 | name = "windows_i686_msvc" 3305 | version = "0.48.5" 3306 | source = "registry+https://github.com/rust-lang/crates.io-index" 3307 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 3308 | 3309 | [[package]] 3310 | name = "windows_i686_msvc" 3311 | version = "0.52.6" 3312 | source = "registry+https://github.com/rust-lang/crates.io-index" 3313 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 3314 | 3315 | [[package]] 3316 | name = "windows_x86_64_gnu" 3317 | version = "0.42.2" 3318 | source = "registry+https://github.com/rust-lang/crates.io-index" 3319 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 3320 | 3321 | [[package]] 3322 | name = "windows_x86_64_gnu" 3323 | version = "0.48.5" 3324 | source = "registry+https://github.com/rust-lang/crates.io-index" 3325 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 3326 | 3327 | [[package]] 3328 | name = "windows_x86_64_gnu" 3329 | version = "0.52.6" 3330 | source = "registry+https://github.com/rust-lang/crates.io-index" 3331 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 3332 | 3333 | [[package]] 3334 | name = "windows_x86_64_gnullvm" 3335 | version = "0.42.2" 3336 | source = "registry+https://github.com/rust-lang/crates.io-index" 3337 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 3338 | 3339 | [[package]] 3340 | name = "windows_x86_64_gnullvm" 3341 | version = "0.48.5" 3342 | source = "registry+https://github.com/rust-lang/crates.io-index" 3343 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 3344 | 3345 | [[package]] 3346 | name = "windows_x86_64_gnullvm" 3347 | version = "0.52.6" 3348 | source = "registry+https://github.com/rust-lang/crates.io-index" 3349 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 3350 | 3351 | [[package]] 3352 | name = "windows_x86_64_msvc" 3353 | version = "0.42.2" 3354 | source = "registry+https://github.com/rust-lang/crates.io-index" 3355 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 3356 | 3357 | [[package]] 3358 | name = "windows_x86_64_msvc" 3359 | version = "0.48.5" 3360 | source = "registry+https://github.com/rust-lang/crates.io-index" 3361 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 3362 | 3363 | [[package]] 3364 | name = "windows_x86_64_msvc" 3365 | version = "0.52.6" 3366 | source = "registry+https://github.com/rust-lang/crates.io-index" 3367 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 3368 | 3369 | [[package]] 3370 | name = "winit" 3371 | version = "0.30.5" 3372 | source = "registry+https://github.com/rust-lang/crates.io-index" 3373 | checksum = "0be9e76a1f1077e04a411f0b989cbd3c93339e1771cb41e71ac4aee95bfd2c67" 3374 | dependencies = [ 3375 | "ahash", 3376 | "android-activity", 3377 | "atomic-waker", 3378 | "bitflags 2.6.0", 3379 | "block2", 3380 | "bytemuck", 3381 | "calloop", 3382 | "cfg_aliases 0.2.1", 3383 | "concurrent-queue", 3384 | "core-foundation", 3385 | "core-graphics", 3386 | "cursor-icon", 3387 | "dpi", 3388 | "js-sys", 3389 | "libc", 3390 | "memmap2 0.9.5", 3391 | "ndk", 3392 | "objc2", 3393 | "objc2-app-kit", 3394 | "objc2-foundation", 3395 | "objc2-ui-kit", 3396 | "orbclient", 3397 | "percent-encoding", 3398 | "pin-project", 3399 | "raw-window-handle", 3400 | "redox_syscall 0.4.1", 3401 | "rustix", 3402 | "sctk-adwaita", 3403 | "smithay-client-toolkit", 3404 | "smol_str", 3405 | "tracing", 3406 | "unicode-segmentation", 3407 | "wasm-bindgen", 3408 | "wasm-bindgen-futures", 3409 | "wayland-backend", 3410 | "wayland-client", 3411 | "wayland-protocols", 3412 | "wayland-protocols-plasma", 3413 | "web-sys", 3414 | "web-time", 3415 | "windows-sys 0.52.0", 3416 | "x11-dl", 3417 | "x11rb", 3418 | "xkbcommon-dl", 3419 | ] 3420 | 3421 | [[package]] 3422 | name = "winnow" 3423 | version = "0.5.40" 3424 | source = "registry+https://github.com/rust-lang/crates.io-index" 3425 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 3426 | dependencies = [ 3427 | "memchr", 3428 | ] 3429 | 3430 | [[package]] 3431 | name = "winnow" 3432 | version = "0.6.20" 3433 | source = "registry+https://github.com/rust-lang/crates.io-index" 3434 | checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" 3435 | dependencies = [ 3436 | "memchr", 3437 | ] 3438 | 3439 | [[package]] 3440 | name = "x11-dl" 3441 | version = "2.21.0" 3442 | source = "registry+https://github.com/rust-lang/crates.io-index" 3443 | checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" 3444 | dependencies = [ 3445 | "libc", 3446 | "once_cell", 3447 | "pkg-config", 3448 | ] 3449 | 3450 | [[package]] 3451 | name = "x11rb" 3452 | version = "0.13.1" 3453 | source = "registry+https://github.com/rust-lang/crates.io-index" 3454 | checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" 3455 | dependencies = [ 3456 | "as-raw-xcb-connection", 3457 | "gethostname", 3458 | "libc", 3459 | "libloading", 3460 | "once_cell", 3461 | "rustix", 3462 | "x11rb-protocol", 3463 | ] 3464 | 3465 | [[package]] 3466 | name = "x11rb-protocol" 3467 | version = "0.13.1" 3468 | source = "registry+https://github.com/rust-lang/crates.io-index" 3469 | checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" 3470 | 3471 | [[package]] 3472 | name = "xcursor" 3473 | version = "0.3.8" 3474 | source = "registry+https://github.com/rust-lang/crates.io-index" 3475 | checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" 3476 | 3477 | [[package]] 3478 | name = "xkbcommon" 3479 | version = "0.7.0" 3480 | source = "registry+https://github.com/rust-lang/crates.io-index" 3481 | checksum = "13867d259930edc7091a6c41b4ce6eee464328c6ff9659b7e4c668ca20d4c91e" 3482 | dependencies = [ 3483 | "libc", 3484 | "memmap2 0.8.0", 3485 | "xkeysym", 3486 | ] 3487 | 3488 | [[package]] 3489 | name = "xkbcommon-dl" 3490 | version = "0.4.2" 3491 | source = "registry+https://github.com/rust-lang/crates.io-index" 3492 | checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" 3493 | dependencies = [ 3494 | "bitflags 2.6.0", 3495 | "dlib", 3496 | "log", 3497 | "once_cell", 3498 | "xkeysym", 3499 | ] 3500 | 3501 | [[package]] 3502 | name = "xkeysym" 3503 | version = "0.2.1" 3504 | source = "registry+https://github.com/rust-lang/crates.io-index" 3505 | checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" 3506 | dependencies = [ 3507 | "bytemuck", 3508 | ] 3509 | 3510 | [[package]] 3511 | name = "xml-rs" 3512 | version = "0.8.22" 3513 | source = "registry+https://github.com/rust-lang/crates.io-index" 3514 | checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" 3515 | 3516 | [[package]] 3517 | name = "xmlparser" 3518 | version = "0.13.6" 3519 | source = "registry+https://github.com/rust-lang/crates.io-index" 3520 | checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" 3521 | 3522 | [[package]] 3523 | name = "zerocopy" 3524 | version = "0.7.35" 3525 | source = "registry+https://github.com/rust-lang/crates.io-index" 3526 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 3527 | dependencies = [ 3528 | "byteorder", 3529 | "zerocopy-derive", 3530 | ] 3531 | 3532 | [[package]] 3533 | name = "zerocopy-derive" 3534 | version = "0.7.35" 3535 | source = "registry+https://github.com/rust-lang/crates.io-index" 3536 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 3537 | dependencies = [ 3538 | "proc-macro2", 3539 | "quote", 3540 | "syn 2.0.80", 3541 | ] 3542 | 3543 | [[package]] 3544 | name = "zune-core" 3545 | version = "0.4.12" 3546 | source = "registry+https://github.com/rust-lang/crates.io-index" 3547 | checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" 3548 | 3549 | [[package]] 3550 | name = "zune-inflate" 3551 | version = "0.2.54" 3552 | source = "registry+https://github.com/rust-lang/crates.io-index" 3553 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" 3554 | dependencies = [ 3555 | "simd-adler32", 3556 | ] 3557 | 3558 | [[package]] 3559 | name = "zune-jpeg" 3560 | version = "0.4.13" 3561 | source = "registry+https://github.com/rust-lang/crates.io-index" 3562 | checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" 3563 | dependencies = [ 3564 | "zune-core", 3565 | ] 3566 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "shaderlock" 3 | description = "Wayland (wlroots) screenlocker with GPU shaders" 4 | version = "0.3.0" 5 | authors = ["Robin McCorkell "] 6 | license = "MIT" 7 | edition = "2018" 8 | 9 | [dependencies] 10 | winit = "0.30.5" 11 | env_logger = "0.11.5" 12 | log = "0.4.11" 13 | wgpu = { version = "22.1.0", features = ["spirv"] } 14 | futures = "0.3.8" 15 | sctk = { package = "smithay-client-toolkit", version = "0.19.2" } 16 | cgmath = "0.18.0" 17 | bytemuck = "1.4.1" 18 | shaderc = "0.8.0" 19 | glob = "0.3.0" 20 | rand = "0.8.4" 21 | anyhow = "1.0.34" 22 | pam = "0.7.0" 23 | users = "0.11.0" 24 | arrayvec = "0.7.2" 25 | sd-notify = "0.4.1" 26 | clap = { version = "4.5.20", features = ["derive"] } 27 | tokio = { version = "1.9.0", features = ["full"] } 28 | pollster = "0.4.0" 29 | dashmap = "6.1.0" 30 | either = "1.13.0" 31 | image = "0.25.5" 32 | 33 | [build-dependencies] 34 | shaderc = "0.8.0" 35 | glob = "0.3.0" 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Robin McCorkell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX = $(HOME)/.local 2 | BINDIR = $(PREFIX)/bin 3 | export DATADIR = $(PREFIX)/share/shaderlock 4 | export PAM_SERVICE = system-auth 5 | 6 | all: shaderlock.daemon dist 7 | cargo build --release 8 | 9 | install: all 10 | install -D -t $(BINDIR) target/release/shaderlock shaderlock.daemon 11 | install -d $(DATADIR) 12 | cp -a -t $(DATADIR) dist/* 13 | 14 | clean: 15 | cargo clean 16 | 17 | .PHONY: all install clean 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shaderlock - Wayland (wlroots) screenlocker with GPU shaders 2 | 3 | ## Integrating 4 | 5 | A shell script helper to launch Shaderlock as a daemon using systemd is provided 6 | as `shaderlock.daemon`. This lets Shaderlock integrate with lock-signalling 7 | systems like `swayidle`: 8 | 9 | ```shell 10 | swayidle -w lock shaderlock.daemon before-sleep shaderlock.daemon 11 | ``` 12 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::fs::{read_to_string, write}; 2 | 3 | const ENV_WITH_DEFAULT: &[(&str, &str)] = &[("DATADIR", "dist"), ("PAM_SERVICE", "system-auth")]; 4 | 5 | const RESOURCES: &str = "resources"; 6 | const VERTEX_SHADER_GLOB: &str = "*.vert"; 7 | const VERTEX_SPIRV_EXTENSION: &str = "vert.spv"; 8 | const FRAGMENT_SHADER_GLOB: &str = "*.frag"; 9 | const FRAGMENT_SPIRV_EXTENSION: &str = "frag.spv"; 10 | 11 | fn vertex_shader_files() -> impl Iterator { 12 | glob::glob(&format!("{}/{}", RESOURCES, VERTEX_SHADER_GLOB)) 13 | .expect("Failed to parse shader file glob") 14 | .map(|r| r.expect("Failed to read path")) 15 | } 16 | 17 | fn fragment_shader_files() -> impl Iterator { 18 | glob::glob(&format!("{}/{}", RESOURCES, FRAGMENT_SHADER_GLOB)) 19 | .expect("Failed to parse shader file glob") 20 | .map(|r| r.expect("Failed to read path")) 21 | } 22 | 23 | fn compile(compiler: &mut shaderc::Compiler, file: &std::path::Path, kind: shaderc::ShaderKind) { 24 | println!("cargo:rerun-if-changed={:?}", file); 25 | 26 | let data = read_to_string(file).expect("Failed to read shader"); 27 | let compiled = compiler 28 | .compile_into_spirv(&data, kind, &file.to_string_lossy(), "main", None) 29 | .expect("Failed to compile shader"); 30 | 31 | let output = match kind { 32 | shaderc::ShaderKind::Vertex => file.with_extension(VERTEX_SPIRV_EXTENSION), 33 | shaderc::ShaderKind::Fragment => file.with_extension(FRAGMENT_SPIRV_EXTENSION), 34 | _ => unreachable!(), 35 | }; 36 | write(output, compiled.as_binary_u8()).expect("Failed to write Spirv"); 37 | } 38 | 39 | fn main() { 40 | let mut compiler = shaderc::Compiler::new().expect("Failed to create compiler"); 41 | for file in vertex_shader_files() { 42 | compile(&mut compiler, &file, shaderc::ShaderKind::Vertex); 43 | } 44 | for file in fragment_shader_files() { 45 | compile(&mut compiler, &file, shaderc::ShaderKind::Fragment); 46 | } 47 | 48 | if std::env::var("PROFILE").unwrap() != "release" { 49 | for (var, default) in ENV_WITH_DEFAULT { 50 | println!("cargo:rustc-env={}={}", var, default); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /dist/lock-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinMcCorkell/shaderlock/58863ae5516b66d66af02304f2355158fa6ea2e8/dist/lock-icon.png -------------------------------------------------------------------------------- /dist/shaders/blur.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) out vec4 f_color; 4 | 5 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 6 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 7 | layout(set = 0, binding = 2) uniform Uniforms { 8 | mat4 iTransform; 9 | }; 10 | 11 | layout(push_constant) uniform FrameUniforms { 12 | float iTime; 13 | float iFadeAmount; 14 | }; 15 | 16 | const float AMOUNT = 4.0; 17 | const float SPEED = 0.1; 18 | const float ACCEL = 1.5; 19 | 20 | void main() { 21 | float lod_bias = AMOUNT * clamp(pow(SPEED * iTime, ACCEL), 0.0, 1.0); 22 | 23 | vec4 ouv = iTransform * vec4(gl_FragCoord.xy, 0.0, 1.0); 24 | vec2 uv = ouv.xy / ouv.w; 25 | 26 | f_color = texture(sampler2D(t_screenshot, s_screenshot), uv, lod_bias); 27 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 1.0), iFadeAmount); 28 | } 29 | -------------------------------------------------------------------------------- /dist/shaders/crt.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) out vec4 f_color; 4 | 5 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 6 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 7 | layout(set = 0, binding = 2) uniform Uniforms { 8 | mat4 iTransform; 9 | }; 10 | 11 | layout(push_constant) uniform FrameUniforms { 12 | float iTime; 13 | float iFadeAmount; 14 | }; 15 | 16 | const float BULGE_AMOUNT = 0.2; 17 | 18 | const float ROLL_FACTOR = 12.0; 19 | const float ROLL_AMOUNT = 3.0; 20 | const float ROLL_PERIOD = 6.0; 21 | 22 | const float ABBERATION_FACTOR = 1.5; 23 | const float ABBERATION_AMOUNT = 0.02; 24 | 25 | const float VIGNETTE_SCALE = 2.2; 26 | const float VIGNETTE_FACTOR = 5.0; 27 | const float VIGNETTE_AMOUNT = 0.9; 28 | 29 | const float SCAN_LINE_COUNT = 700.0; 30 | const float SCAN_LINE_AMOUNT = 0.25; 31 | const float SCAN_LINE_FACTOR = 2.2; 32 | const float SCAN_LINE_DRIFT = 0.002; 33 | 34 | const float DOWNSCALE_RESOLUTION = 300.0; 35 | 36 | vec2 downscale(vec2 v) { 37 | return floor(v * DOWNSCALE_RESOLUTION) / DOWNSCALE_RESOLUTION; 38 | } 39 | 40 | float get_center_distance(vec2 p) { 41 | return distance(p, vec2(0.5)) * 2.0; 42 | } 43 | 44 | vec2 bulge_coords(vec2 p, float amount) { 45 | float d = get_center_distance(p); 46 | p -= vec2(0.5); 47 | p *= 1.0 + d * amount; 48 | p *= 1.0 - amount; 49 | p += vec2(0.5); 50 | return p; 51 | } 52 | 53 | vec2 roll_coords(vec2 p) { 54 | float progress = fract(iTime / ROLL_PERIOD); 55 | float amount = ROLL_AMOUNT * clamp(ROLL_FACTOR * progress, 0.0, 1.0); 56 | p.y -= amount; 57 | return fract(p); 58 | } 59 | 60 | vec4 sample_abberation(vec2 p_fb, vec2 p) { 61 | float d = pow(get_center_distance(p), ABBERATION_FACTOR); 62 | 63 | float r = texture(sampler2D(t_screenshot, s_screenshot), downscale(p_fb)).r; 64 | float g = texture(sampler2D(t_screenshot, s_screenshot), downscale(p_fb * (1.0 + d * ABBERATION_AMOUNT))).g; 65 | float b = texture(sampler2D(t_screenshot, s_screenshot), downscale(p_fb * (1.0 - d * ABBERATION_AMOUNT))).b; 66 | 67 | return vec4(r, g, b, 1.0); 68 | } 69 | 70 | vec4 vignette(vec4 c, vec2 p) { 71 | float f = VIGNETTE_AMOUNT * min(1.0, pow(get_center_distance(p) / VIGNETTE_SCALE, VIGNETTE_FACTOR)); 72 | c.rgb -= f; 73 | return c; 74 | } 75 | 76 | vec4 scan_lines(vec4 c, vec2 p) { 77 | p.y += iTime * SCAN_LINE_DRIFT; 78 | float f = SCAN_LINE_AMOUNT * pow(0.5 + 0.5 * cos(p.y * 6.28 * SCAN_LINE_COUNT), SCAN_LINE_FACTOR); 79 | c.rgb -= f; 80 | return c; 81 | } 82 | 83 | void main() { 84 | vec4 ouv = iTransform * vec4(gl_FragCoord.xy, 0.0, 1.0); 85 | vec2 uv = ouv.xy / ouv.w; 86 | 87 | vec2 uv_monitor = bulge_coords(uv, BULGE_AMOUNT); 88 | vec2 uv_fb = roll_coords(uv_monitor); 89 | 90 | vec4 c = sample_abberation(uv_fb, uv_monitor); 91 | c = vignette(c, uv_monitor); 92 | c = scan_lines(c, uv_monitor); 93 | 94 | f_color = c; 95 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 1.0), iFadeAmount); 96 | } 97 | -------------------------------------------------------------------------------- /dist/shaders/desaturate_fade.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) out vec4 f_color; 4 | 5 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 6 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 7 | layout(set = 0, binding = 2) uniform Uniforms { 8 | mat4 iTransform; 9 | }; 10 | 11 | layout(push_constant) uniform FrameUniforms { 12 | float iTime; 13 | float iFadeAmount; 14 | }; 15 | 16 | const vec3 LUMIN = vec3(0.299, 0.587, 0.114); 17 | const vec4 CLEAR_COLOR = vec4(0.0, 0.0, 0.0, 1.0); 18 | 19 | const float DESATURATE_SPEED = 0.2; 20 | const float DESATURATE_ACCEL = 2.2; 21 | const float FADE_SPEED = 0.2; 22 | const float FADE_ACCEL = 1.0; 23 | 24 | vec4 desaturate(vec4 color, float desaturation) { 25 | vec3 gray = vec3(dot(LUMIN, vec3(color))); 26 | return vec4(mix(vec3(color), gray, desaturation), 1.0); 27 | } 28 | 29 | 30 | void main() { 31 | float desaturation = clamp(pow(DESATURATE_SPEED * iTime, DESATURATE_ACCEL), 0.0, 1.0); 32 | float fade = clamp(pow(FADE_SPEED * (iTime - 1.0/DESATURATE_SPEED), FADE_ACCEL), 0.0, 1.0); 33 | 34 | vec4 ouv = iTransform * vec4(gl_FragCoord.xy, 0.0, 1.0); 35 | vec2 uv = ouv.xy / ouv.w; 36 | 37 | vec4 desaturated = desaturate(texture(sampler2D(t_screenshot, s_screenshot), uv), desaturation); 38 | f_color = mix(desaturated, CLEAR_COLOR, fade); 39 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 1.0), iFadeAmount); 40 | } 41 | -------------------------------------------------------------------------------- /dist/shaders/dissolve.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) out vec4 f_color; 4 | 5 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 6 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 7 | layout(set = 0, binding = 2) uniform Uniforms { 8 | mat4 iTransform; 9 | }; 10 | 11 | layout(push_constant) uniform FrameUniforms { 12 | float iTime; 13 | float iFadeAmount; 14 | }; 15 | 16 | const float DISSOLVE_SPEED = 200; 17 | const float FALL_ACCEL = 800.0; 18 | const float RANDOM_AMOUNT = 0.15; 19 | const float RANDOM_SIZE = 60.0; 20 | 21 | const vec4 CLEAR_COLOR = vec4(0.0, 0.0, 0.0, 1.0); 22 | 23 | // -------------------------------------------------------------- 24 | // hash() and noise() are from https://www.shadertoy.com/view/Msf3WH: 25 | 26 | // The MIT License 27 | // Copyright © 2013 Inigo Quilez 28 | // 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. 29 | // https://www.youtube.com/c/InigoQuilez 30 | // https://iquilezles.org 31 | vec2 hash( vec2 p ) { 32 | p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) ); 33 | return -1.0 + 2.0*fract(sin(p)*43758.5453123); 34 | } 35 | 36 | float noise( in vec2 p ) { 37 | const float K1 = 0.366025404; // (sqrt(3)-1)/2; 38 | const float K2 = 0.211324865; // (3-sqrt(3))/6; 39 | 40 | vec2 i = floor( p + (p.x+p.y)*K1 ); 41 | vec2 a = p - i + (i.x+i.y)*K2; 42 | float m = step(a.y,a.x); 43 | vec2 o = vec2(m,1.0-m); 44 | vec2 b = a - o + K2; 45 | vec2 c = a - 1.0 + 2.0*K2; 46 | vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 ); 47 | vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))); 48 | return dot( n, vec3(70.0) ); 49 | } 50 | // -------------------------------------------------------------- 51 | 52 | float dissolve(float y, float time) { 53 | float t = max(0.0, time - y / DISSOLVE_SPEED); 54 | // s = 1/2 a (t - s/v)^2 55 | float dissolve_t = ( 56 | t 57 | + DISSOLVE_SPEED / FALL_ACCEL 58 | - sqrt(DISSOLVE_SPEED * DISSOLVE_SPEED + 2.0 * t * DISSOLVE_SPEED * FALL_ACCEL) / FALL_ACCEL 59 | ); 60 | float dissolve_y = DISSOLVE_SPEED * dissolve_t; 61 | return y + dissolve_y; 62 | } 63 | 64 | bool is_closer_rounded(float x, float other) { 65 | float x_round = round(x); 66 | float x_err = abs(x - x_round); 67 | 68 | float other_round = round(other); 69 | float other_err = abs(other - other_round); 70 | 71 | bool is_same = abs(other_round - x_round) < 0.1; 72 | return is_same && other_err < x_err; 73 | } 74 | 75 | void main() { 76 | float rand = RANDOM_AMOUNT * noise(vec2(gl_FragCoord.x/RANDOM_SIZE, 0.0)); 77 | float t = iTime * (1.0 + rand); 78 | float y = dissolve(gl_FragCoord.y, t); 79 | 80 | vec4 ouv = iTransform * vec4(gl_FragCoord.x, round(y), 0.0, 1.0); 81 | vec2 uv = ouv.xy / ouv.w; 82 | 83 | float prev_y = dissolve(gl_FragCoord.y - 1, t); 84 | float next_y = dissolve(gl_FragCoord.y + 1, t); 85 | 86 | bool is_blank = is_closer_rounded(y, prev_y) || is_closer_rounded(y, next_y); 87 | 88 | if (is_blank || uv.y > 1.0) { 89 | f_color = CLEAR_COLOR; 90 | } else { 91 | f_color = texture(sampler2D(t_screenshot, s_screenshot), uv); 92 | } 93 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 1.0), iFadeAmount); 94 | } 95 | -------------------------------------------------------------------------------- /dist/shaders/overlay.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) out vec4 f_color; 4 | 5 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 6 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 7 | layout(set = 0, binding = 2) uniform Uniforms { 8 | mat4 iTransform; 9 | }; 10 | 11 | layout(push_constant) uniform FrameUniforms { 12 | float iTime; 13 | float iFadeAmount; 14 | }; 15 | 16 | const float PI = 3.141529; 17 | const float SPEED = 0.3; 18 | const float DIRECTIONS = 3.0; 19 | const float OFFSET_FRACT = 0.1; 20 | const float LOD_BIAS = 3.0; 21 | 22 | vec4 overlay(vec2 uv, float amount) { 23 | vec4 color = vec4(0.0); 24 | for (float d = OFFSET_FRACT*PI/DIRECTIONS; d < PI; d += PI/DIRECTIONS) { 25 | color += texture(sampler2D(t_screenshot, s_screenshot), uv + vec2(cos(d), sin(d)) * amount, LOD_BIAS); 26 | } 27 | return color / DIRECTIONS; 28 | } 29 | 30 | void main() { 31 | float amount = SPEED * iTime; 32 | 33 | vec4 ouv = iTransform * vec4(gl_FragCoord.xy, 0.0, 1.0); 34 | vec2 uv = ouv.xy / ouv.w; 35 | 36 | f_color = overlay(uv, amount); 37 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 1.0), iFadeAmount); 38 | } 39 | -------------------------------------------------------------------------------- /dist/shaders/paper_burn.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) out vec4 f_color; 4 | 5 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 6 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 7 | layout(set = 0, binding = 2) uniform Uniforms { 8 | mat4 iTransform; 9 | }; 10 | 11 | layout(push_constant) uniform FrameUniforms { 12 | float iTime; 13 | float iFadeAmount; 14 | }; 15 | 16 | const float NOISE_FREQ = 12.0; 17 | const float SPEED = 0.25; 18 | const float DISTANCE_FACTOR = 3.0; 19 | const vec2 START_POINT = vec2(1.0, 1.0); 20 | 21 | const vec4 SCORCH_COLOR = vec4(0.0, 0.0, 0.0, 1.0); 22 | const float SCORCH_BAND_SIZE = 0.4; 23 | const float SCORCH_MAX = 0.8; 24 | 25 | const vec4 BURN_COLOR = vec4(0.93, 0.35, 0.02, 1.0); 26 | const float BURN_BAND_SIZE = 0.1; 27 | const float BURN_MAX = 0.5; 28 | 29 | 30 | // -------------------------------------------------------------- 31 | // hash() and noise() are from https://www.shadertoy.com/view/Msf3WH: 32 | 33 | // The MIT License 34 | // Copyright © 2013 Inigo Quilez 35 | // 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. 36 | // https://www.youtube.com/c/InigoQuilez 37 | // https://iquilezles.org 38 | vec2 hash( vec2 p ) { 39 | p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) ); 40 | return -1.0 + 2.0*fract(sin(p)*43758.5453123); 41 | } 42 | 43 | float noise( in vec2 p ) { 44 | const float K1 = 0.366025404; // (sqrt(3)-1)/2; 45 | const float K2 = 0.211324865; // (3-sqrt(3))/6; 46 | 47 | vec2 i = floor( p + (p.x+p.y)*K1 ); 48 | vec2 a = p - i + (i.x+i.y)*K2; 49 | float m = step(a.y,a.x); 50 | vec2 o = vec2(m,1.0-m); 51 | vec2 b = a - o + K2; 52 | vec2 c = a - 1.0 + 2.0*K2; 53 | vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 ); 54 | vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0))); 55 | return dot( n, vec3(70.0) ); 56 | } 57 | 58 | // -------------------------------------------------------------- 59 | 60 | void main() { 61 | vec4 ouv = iTransform * vec4(gl_FragCoord.xy, 0.0, 1.0); 62 | vec2 uv = ouv.xy / ouv.w; 63 | 64 | float d = distance(uv, START_POINT); 65 | 66 | float v = noise(NOISE_FREQ * uv); 67 | v = 0.5 + 0.5*v; 68 | v += d*DISTANCE_FACTOR; 69 | 70 | float f = (SPEED * iTime) - v; 71 | 72 | float scorch = smoothstep(0.0, 1.0, f/SCORCH_BAND_SIZE); 73 | float burn = smoothstep(0.0, 1.0, (f-SCORCH_BAND_SIZE)/BURN_BAND_SIZE); 74 | float alpha = smoothstep(0.0, 1.0, (f-SCORCH_BAND_SIZE-BURN_BAND_SIZE)*1000.0); 75 | 76 | f_color = texture(sampler2D(t_screenshot, s_screenshot), uv); 77 | f_color = mix(f_color, SCORCH_COLOR, scorch*SCORCH_MAX); 78 | f_color = mix(f_color, BURN_COLOR, burn*BURN_MAX); 79 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 0.0), alpha); 80 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 1.0), iFadeAmount); 81 | } 82 | -------------------------------------------------------------------------------- /dist/shaders/vertical_band_slide.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) out vec4 f_color; 4 | 5 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 6 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 7 | layout(set = 0, binding = 2) uniform Uniforms { 8 | mat4 iTransform; 9 | }; 10 | 11 | layout(push_constant) uniform FrameUniforms { 12 | float iTime; 13 | float iFadeAmount; 14 | }; 15 | 16 | const vec4 CLEAR_COLOR = vec4(0.0, 0.0, 0.0, 1.0); 17 | 18 | const int BAND_SIZE = 64; 19 | const int BORDER = 1; 20 | const float SPEED = 0.8; 21 | const float ACCEL = 5.0; 22 | 23 | void main() { 24 | vec2 offset; 25 | vec4 coord = gl_FragCoord; 26 | int double_band_coord = int(mod(coord.x, 2*BAND_SIZE)); 27 | int band_coord = int(mod(double_band_coord, BAND_SIZE)); 28 | if (band_coord < BORDER) { 29 | f_color = CLEAR_COLOR; 30 | return; 31 | } else if (double_band_coord < BAND_SIZE) { 32 | offset = vec2(0.0, 1.0); 33 | } else { 34 | offset = vec2(0.0, -1.0); 35 | } 36 | coord.xy += offset * pow(SPEED * iTime, ACCEL); 37 | 38 | vec4 ouv = iTransform * coord; 39 | vec2 uv = ouv.xy / ouv.w; 40 | 41 | if (uv.x > 1.0 || uv.x < 0.0 || uv.y > 1.0 || uv.y < 0.0) { 42 | f_color = CLEAR_COLOR; 43 | } else { 44 | f_color = texture(sampler2D(t_screenshot, s_screenshot), uv); 45 | } 46 | f_color = mix(f_color, vec4(0.0, 0.0, 0.0, 1.0), iFadeAmount); 47 | } 48 | -------------------------------------------------------------------------------- /examples/screencopy.rs: -------------------------------------------------------------------------------- 1 | use anyhow::*; 2 | use futures::StreamExt; 3 | #[allow(unused_imports)] 4 | use log::{debug, error, info, warn}; 5 | use shaderlock::{ 6 | screencopy::ScreencopyHandler, 7 | window_manager::{Event, WindowManager}, 8 | }; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<()> { 12 | env_logger::init(); 13 | let mut wm = WindowManager::new()?; 14 | wm.run(|conn, qh, mut state, events| async move { 15 | debug!("awaiting events"); 16 | let event = events.next().await.context("events stream was closed")?; 17 | debug!("got event: {:?}", event); 18 | match event { 19 | Event::NewOutput(output) => { 20 | let frame_handle = state 21 | .access(|s| { 22 | debug!("capture frame on output: {:?}", output); 23 | let res = s.screencopy_state().capture_output(&output, &qh); 24 | conn.flush()?; 25 | res 26 | })? 27 | .await??; 28 | debug!("capture complete, getting buffer data"); 29 | let frame = state.access(|s| s.get_buffer_data(frame_handle)); 30 | debug!("got buffer data"); 31 | drop(frame); 32 | Ok(()) 33 | } 34 | _ => unimplemented!(), 35 | } 36 | }) 37 | .await 38 | } 39 | -------------------------------------------------------------------------------- /resources/bg.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | const vec2 positions[4] = vec2[4]( 4 | vec2(-1.0, -1.0), 5 | vec2(-1.0, 1.0), 6 | vec2(1.0, -1.0), 7 | vec2(1.0, 1.0) 8 | ); 9 | 10 | void main() { 11 | gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /resources/icon.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location=0) in vec2 v_tex_coords; 4 | layout(location=0) out vec4 f_color; 5 | 6 | layout(set = 0, binding = 0) uniform texture2D t_screenshot; 7 | layout(set = 0, binding = 1) uniform sampler s_screenshot; 8 | 9 | void main() { 10 | f_color = texture(sampler2D(t_screenshot, s_screenshot), v_tex_coords); 11 | } 12 | -------------------------------------------------------------------------------- /resources/icon.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | const vec2 positions[4] = vec2[4]( 4 | vec2(-1.0, -1.0), 5 | vec2(-1.0, 1.0), 6 | vec2(1.0, -1.0), 7 | vec2(1.0, 1.0) 8 | ); 9 | 10 | const vec2 tex_positions[4] = vec2[4]( 11 | vec2(0.0, 1.0), 12 | vec2(0.0, 0.0), 13 | vec2(1.0, 1.0), 14 | vec2(1.0, 0.0) 15 | ); 16 | 17 | const float SCALE = 1.0; 18 | 19 | layout(location=0) out vec2 v_tex_coords; 20 | 21 | layout(set = 0, binding = 2) uniform Uniforms { 22 | mat4 iTransform; 23 | }; 24 | 25 | void main() { 26 | gl_Position = SCALE * iTransform * vec4(positions[gl_VertexIndex], 0.0, 1.0); 27 | v_tex_coords = tex_positions[gl_VertexIndex]; 28 | } 29 | -------------------------------------------------------------------------------- /shaderlock.daemon: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec systemd-run --user --collect -u shaderlock --service-type=notify shaderlock "$@" 4 | -------------------------------------------------------------------------------- /src/authenticator.rs: -------------------------------------------------------------------------------- 1 | use anyhow::*; 2 | #[allow(unused_imports)] 3 | use log::{debug, error, info, warn}; 4 | 5 | const PAM_SERVICE: &str = env!("PAM_SERVICE"); 6 | const PASSWORD_SIZE: usize = 256; 7 | 8 | pub trait AuthenticatorBackend { 9 | fn authenticate(&mut self, password: &str) -> Result<()>; 10 | } 11 | 12 | pub struct PamAuthenticatorBackend { 13 | username: String, 14 | auth: pam::Authenticator<'static, pam::PasswordConv>, 15 | } 16 | 17 | impl PamAuthenticatorBackend { 18 | pub fn new() -> Result { 19 | let username = users::get_current_username() 20 | .context("Failed to get username")? 21 | .into_string() 22 | .map_err(|oss| anyhow!("Failed to parse username {:?}", oss))?; 23 | info!("My username: {}", username); 24 | 25 | let auth = 26 | pam::Authenticator::with_password(PAM_SERVICE).context("Failed to initialize PAM")?; 27 | 28 | Ok(Self { username, auth }) 29 | } 30 | } 31 | 32 | impl AuthenticatorBackend for PamAuthenticatorBackend { 33 | fn authenticate(&mut self, password: &str) -> Result<()> { 34 | self.auth 35 | .get_handler() 36 | .set_credentials(&self.username, password); 37 | self.auth.authenticate().context("PAM auth failed") 38 | } 39 | } 40 | 41 | pub struct NullAuthenticatorBackend; 42 | 43 | impl NullAuthenticatorBackend { 44 | pub fn new() -> Self { 45 | Self 46 | } 47 | } 48 | 49 | impl Default for NullAuthenticatorBackend { 50 | fn default() -> Self { 51 | Self::new() 52 | } 53 | } 54 | 55 | impl AuthenticatorBackend for NullAuthenticatorBackend { 56 | fn authenticate(&mut self, _: &str) -> Result<()> { 57 | warn!("null authentication = success"); 58 | Ok(()) 59 | } 60 | } 61 | 62 | pub struct Authenticator<'a> { 63 | backend: &'a mut dyn AuthenticatorBackend, 64 | password: arrayvec::ArrayString<{ PASSWORD_SIZE }>, 65 | } 66 | 67 | impl<'a> Authenticator<'a> { 68 | pub fn new(backend: &'a mut dyn AuthenticatorBackend) -> Result { 69 | Ok(Self { 70 | backend, 71 | password: arrayvec::ArrayString::new(), 72 | }) 73 | } 74 | 75 | pub fn push(&mut self, c: char) { 76 | self.password 77 | .try_push(c) 78 | .unwrap_or_else(|_| error!("Overflowed password field")) 79 | } 80 | 81 | pub fn pop(&mut self) -> Option { 82 | self.password.pop() 83 | } 84 | 85 | pub fn clear(&mut self) { 86 | debug!("Clearing password buffer"); 87 | self.password.clear() 88 | } 89 | 90 | pub fn authenticate(&mut self) -> Result<()> { 91 | debug!("Beginning authentication"); 92 | let result = self.backend.authenticate(&self.password); 93 | self.clear(); 94 | info!("Authentication result: {:?}", result); 95 | result 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/graphics.rs: -------------------------------------------------------------------------------- 1 | mod bg; 2 | mod icon; 3 | 4 | use std::time::Duration; 5 | 6 | use anyhow::*; 7 | #[allow(unused_imports)] 8 | use log::{debug, error, info, warn}; 9 | use wgpu::SurfaceTarget; 10 | 11 | pub struct Manager { 12 | instance: wgpu::Instance, 13 | shader: wgpu::ShaderSource<'static>, 14 | icon: image::RgbaImage, 15 | } 16 | 17 | impl Manager { 18 | pub fn new(shader_file: &std::path::Path, icon_file: &std::path::Path) -> Result { 19 | let shader_source = 20 | std::fs::read_to_string(shader_file).context("Failed to read shader")?; 21 | let compiler = shaderc::Compiler::new().context("Failed to create shader compiler")?; 22 | let spirv = compiler 23 | .compile_into_spirv( 24 | &shader_source, 25 | shaderc::ShaderKind::Fragment, 26 | &shader_file.to_string_lossy(), 27 | bg::FS_MAIN, 28 | None, 29 | ) 30 | .context("Failed to compile shader")?; 31 | 32 | let data = Vec::from(spirv.as_binary()); 33 | let shader = wgpu::ShaderSource::SpirV(data.into()); 34 | 35 | let icon = image::open(icon_file).context("Failed to read icon file")?; 36 | 37 | Ok(Manager { 38 | instance: wgpu::Instance::new(wgpu::InstanceDescriptor { 39 | backends: wgpu::Backends::PRIMARY, 40 | ..Default::default() 41 | }), 42 | shader, 43 | icon: icon.into_rgba8(), 44 | }) 45 | } 46 | 47 | pub async fn init_window<'window>( 48 | &self, 49 | window: impl Into>, 50 | screenshot: crate::screencopy::ScreencopyBuffer, 51 | (width, height): (u32, u32), 52 | ) -> Result> { 53 | let surface = self 54 | .instance 55 | .create_surface(window) 56 | .context("Failed to create surface")?; 57 | debug!("requesting adapter"); 58 | let adapter = self 59 | .instance 60 | .request_adapter(&wgpu::RequestAdapterOptions { 61 | power_preference: wgpu::PowerPreference::LowPower, 62 | compatible_surface: Some(&surface), 63 | force_fallback_adapter: false, 64 | }) 65 | .await 66 | .context("Failed to get graphics adapter")?; 67 | 68 | debug!("requesting device"); 69 | let (device, queue) = adapter 70 | .request_device( 71 | &wgpu::DeviceDescriptor { 72 | label: None, 73 | required_features: wgpu::Features::PUSH_CONSTANTS, 74 | required_limits: wgpu::Limits { 75 | max_push_constant_size: self::bg::PUSH_CONSTANTS_SIZE, 76 | ..wgpu::Limits::default() 77 | }, 78 | memory_hints: Default::default(), 79 | }, 80 | None, // Trace path 81 | ) 82 | .await 83 | .context("Failed to get device")?; 84 | 85 | let surface_config = wgpu::SurfaceConfiguration { 86 | usage: wgpu::TextureUsages::RENDER_ATTACHMENT, 87 | format: wgpu::TextureFormat::Bgra8UnormSrgb, 88 | width, 89 | height, 90 | present_mode: wgpu::PresentMode::Fifo, 91 | alpha_mode: wgpu::CompositeAlphaMode::Auto, 92 | view_formats: vec![], 93 | desired_maximum_frame_latency: 2, 94 | }; 95 | 96 | let bg = self::bg::State::new( 97 | &device, 98 | &queue, 99 | surface_config.format, 100 | self.shader.clone(), 101 | screenshot, 102 | )?; 103 | let icon = self::icon::State::new(&device, &queue, surface_config.format, &self.icon)?; 104 | 105 | let mut me = State { 106 | surface, 107 | device, 108 | queue, 109 | surface_config, 110 | 111 | bg, 112 | icon, 113 | }; 114 | 115 | me.resize((width, height)); 116 | Ok(me) 117 | } 118 | } 119 | pub struct State<'window> { 120 | surface: wgpu::Surface<'window>, 121 | device: wgpu::Device, 122 | queue: wgpu::Queue, 123 | surface_config: wgpu::SurfaceConfiguration, 124 | 125 | bg: self::bg::State, 126 | icon: self::icon::State, 127 | } 128 | 129 | impl State<'_> { 130 | pub fn resize(&mut self, (width, height): (u32, u32)) { 131 | self.surface_config.width = width; 132 | self.surface_config.height = height; 133 | self.surface.configure(&self.device, &self.surface_config); 134 | 135 | let resolution_transform = 136 | cgmath::Matrix4::from_nonuniform_scale(1.0 / width as f32, 1.0 / height as f32, 1.0); 137 | 138 | self.bg.resize(&self.queue, resolution_transform); 139 | self.icon.resize(&self.queue, resolution_transform); 140 | } 141 | 142 | pub fn render(&mut self, ctx: RenderContext) -> wgpu::SurfaceTexture { 143 | let frame = self 144 | .surface 145 | .get_current_texture() 146 | .expect("Timeout getting texture"); 147 | let view = frame 148 | .texture 149 | .create_view(&wgpu::TextureViewDescriptor::default()); 150 | 151 | let mut encoder = self 152 | .device 153 | .create_command_encoder(&wgpu::CommandEncoderDescriptor { 154 | label: Some("Render Encoder"), 155 | }); 156 | 157 | self.bg.render(&mut encoder, &view, ctx); 158 | self.icon.render(&mut encoder, &view); 159 | 160 | // submit will accept anything that implements IntoIter 161 | self.queue.submit(std::iter::once(encoder.finish())); 162 | 163 | frame 164 | } 165 | } 166 | 167 | pub struct RenderContext { 168 | pub elapsed: Duration, 169 | pub fade_amount: f32, 170 | } 171 | -------------------------------------------------------------------------------- /src/graphics/bg.rs: -------------------------------------------------------------------------------- 1 | use anyhow::*; 2 | #[allow(unused_imports)] 3 | use log::{debug, error, info, warn}; 4 | 5 | use sctk::reexports::client::protocol::wl_shm::Format; 6 | use wgpu::util::DeviceExt; 7 | 8 | use crate::screencopy::ScreencopyBuffer; 9 | 10 | use super::RenderContext; 11 | 12 | pub const VS_MAIN: &str = "main"; 13 | pub const FS_MAIN: &str = "main"; 14 | 15 | #[repr(C)] 16 | #[derive(Debug, Copy, Clone)] 17 | struct Uniforms { 18 | transform: cgmath::Matrix4, 19 | } 20 | unsafe impl bytemuck::Pod for Uniforms {} 21 | unsafe impl bytemuck::Zeroable for Uniforms {} 22 | 23 | struct UniformsHandle { 24 | data: Uniforms, 25 | texture_transform: cgmath::Matrix4, 26 | buffer: wgpu::Buffer, 27 | } 28 | 29 | #[repr(C)] 30 | #[derive(Debug, Copy, Clone)] 31 | struct FrameUniforms { 32 | elapsed: f32, 33 | fade_amount: f32, 34 | } 35 | unsafe impl bytemuck::Pod for FrameUniforms {} 36 | unsafe impl bytemuck::Zeroable for FrameUniforms {} 37 | 38 | impl From for FrameUniforms { 39 | fn from(ctx: RenderContext) -> Self { 40 | Self { 41 | elapsed: ctx.elapsed.as_secs_f32(), 42 | fade_amount: ctx.fade_amount, 43 | } 44 | } 45 | } 46 | 47 | pub const PUSH_CONSTANTS_SIZE: u32 = std::mem::size_of::() as u32; 48 | 49 | pub struct State { 50 | pipeline: wgpu::RenderPipeline, 51 | bind_group: wgpu::BindGroup, 52 | uniforms_handle: UniformsHandle, 53 | } 54 | 55 | impl State { 56 | pub fn new<'buffer>( 57 | device: &wgpu::Device, 58 | queue: &wgpu::Queue, 59 | swapchain_format: wgpu::TextureFormat, 60 | shader: wgpu::ShaderSource, 61 | screenshot: ScreencopyBuffer, 62 | ) -> Result { 63 | let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { 64 | entries: &[ 65 | wgpu::BindGroupLayoutEntry { 66 | binding: 0, 67 | visibility: wgpu::ShaderStages::FRAGMENT, 68 | ty: wgpu::BindingType::Texture { 69 | sample_type: wgpu::TextureSampleType::Float { filterable: true }, 70 | view_dimension: wgpu::TextureViewDimension::D2, 71 | multisampled: false, 72 | }, 73 | count: None, 74 | }, 75 | wgpu::BindGroupLayoutEntry { 76 | binding: 1, 77 | visibility: wgpu::ShaderStages::FRAGMENT, 78 | ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), 79 | count: None, 80 | }, 81 | wgpu::BindGroupLayoutEntry { 82 | binding: 2, 83 | visibility: wgpu::ShaderStages::FRAGMENT, 84 | ty: wgpu::BindingType::Buffer { 85 | ty: wgpu::BufferBindingType::Uniform, 86 | has_dynamic_offset: false, 87 | min_binding_size: None, 88 | }, 89 | count: None, 90 | }, 91 | ], 92 | label: Some("bind_group_layout"), 93 | }); 94 | 95 | let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { 96 | label: Some("BG Render pipeline layout"), 97 | bind_group_layouts: &[&bind_group_layout], 98 | push_constant_ranges: &[wgpu::PushConstantRange { 99 | stages: wgpu::ShaderStages::FRAGMENT, 100 | range: 0..PUSH_CONSTANTS_SIZE, 101 | }], 102 | }); 103 | 104 | let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { 105 | label: Some("BG Render pipeline"), 106 | layout: Some(&pipeline_layout), 107 | vertex: wgpu::VertexState { 108 | module: &device 109 | .create_shader_module(wgpu::include_spirv!("../../resources/bg.vert.spv")), 110 | entry_point: VS_MAIN, 111 | buffers: &[], 112 | compilation_options: wgpu::PipelineCompilationOptions::default(), 113 | }, 114 | fragment: Some(wgpu::FragmentState { 115 | module: &device.create_shader_module(wgpu::ShaderModuleDescriptor { 116 | label: Some("shader"), 117 | source: shader, 118 | }), 119 | entry_point: FS_MAIN, 120 | targets: &[Some(wgpu::ColorTargetState { 121 | format: swapchain_format, 122 | blend: Some(wgpu::BlendState::REPLACE), 123 | write_mask: wgpu::ColorWrites::ALL, 124 | })], 125 | compilation_options: wgpu::PipelineCompilationOptions::default(), 126 | }), 127 | primitive: wgpu::PrimitiveState { 128 | topology: wgpu::PrimitiveTopology::TriangleStrip, 129 | front_face: wgpu::FrontFace::Ccw, 130 | cull_mode: None, 131 | ..Default::default() 132 | }, 133 | multisample: wgpu::MultisampleState { 134 | count: 1, 135 | mask: !0, 136 | alpha_to_coverage_enabled: false, 137 | }, 138 | depth_stencil: None, 139 | multiview: None, 140 | cache: None, 141 | }); 142 | 143 | let texture_size = wgpu::Extent3d { 144 | width: screenshot.width(), 145 | height: screenshot.height(), 146 | depth_or_array_layers: 1, 147 | }; 148 | let texture_descriptor = wgpu::TextureDescriptor { 149 | label: Some("Screenshot"), 150 | size: texture_size, 151 | mip_level_count: 1, 152 | sample_count: 1, 153 | dimension: wgpu::TextureDimension::D2, 154 | format: texture_format_from_sctk(screenshot.format()), 155 | usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, 156 | view_formats: &[], 157 | }; 158 | let texture = device.create_texture(&texture_descriptor); 159 | let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default()); 160 | let sampler = device.create_sampler(&wgpu::SamplerDescriptor { 161 | address_mode_u: wgpu::AddressMode::MirrorRepeat, 162 | address_mode_v: wgpu::AddressMode::MirrorRepeat, 163 | address_mode_w: wgpu::AddressMode::MirrorRepeat, 164 | mag_filter: wgpu::FilterMode::Linear, 165 | min_filter: wgpu::FilterMode::Linear, 166 | mipmap_filter: wgpu::FilterMode::Linear, 167 | ..Default::default() 168 | }); 169 | 170 | let stride = screenshot.stride(); 171 | let height = screenshot.height(); 172 | let width = screenshot.width(); 173 | queue.write_texture( 174 | wgpu::ImageCopyTexture { 175 | texture: &texture, 176 | mip_level: 0, 177 | origin: wgpu::Origin3d::ZERO, 178 | aspect: wgpu::TextureAspect::All, 179 | }, 180 | screenshot.bytes(), 181 | wgpu::ImageDataLayout { 182 | offset: 0, 183 | bytes_per_row: Some(stride), 184 | rows_per_image: Some(height), 185 | }, 186 | wgpu::Extent3d { 187 | width, 188 | height, 189 | depth_or_array_layers: 1, 190 | }, 191 | ); 192 | 193 | let texture_transform = 194 | cgmath::Matrix4::from_translation(cgmath::Vector3::new(0.5, 0.5, 0.0)) 195 | * screenshot.transform_matrix() 196 | * cgmath::Matrix4::from_translation(cgmath::Vector3::new(-0.5, -0.5, 0.0)); 197 | let uniforms = Uniforms { 198 | transform: texture_transform, 199 | }; 200 | 201 | let uniforms_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { 202 | label: Some("Uniforms Buffer"), 203 | contents: bytemuck::cast_slice(&[uniforms]), 204 | usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, 205 | }); 206 | 207 | let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { 208 | layout: &bind_group_layout, 209 | entries: &[ 210 | wgpu::BindGroupEntry { 211 | binding: 0, 212 | resource: wgpu::BindingResource::TextureView(&texture_view), 213 | }, 214 | wgpu::BindGroupEntry { 215 | binding: 1, 216 | resource: wgpu::BindingResource::Sampler(&sampler), 217 | }, 218 | wgpu::BindGroupEntry { 219 | binding: 2, 220 | resource: uniforms_buffer.as_entire_binding(), 221 | }, 222 | ], 223 | label: Some("bg bind group"), 224 | }); 225 | 226 | let uniforms_handle = UniformsHandle { 227 | data: uniforms, 228 | texture_transform, 229 | buffer: uniforms_buffer, 230 | }; 231 | 232 | Ok(Self { 233 | pipeline, 234 | bind_group, 235 | uniforms_handle, 236 | }) 237 | } 238 | pub fn resize(&mut self, queue: &wgpu::Queue, resolution_transform: cgmath::Matrix4) { 239 | self.uniforms_handle.data.transform = 240 | self.uniforms_handle.texture_transform * resolution_transform; 241 | queue.write_buffer( 242 | &self.uniforms_handle.buffer, 243 | 0, 244 | bytemuck::cast_slice(&[self.uniforms_handle.data]), 245 | ); 246 | } 247 | 248 | pub fn render( 249 | &mut self, 250 | encoder: &mut wgpu::CommandEncoder, 251 | view: &wgpu::TextureView, 252 | ctx: RenderContext, 253 | ) { 254 | let mut rp = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { 255 | label: Some("BG render pass"), 256 | color_attachments: &[Some(wgpu::RenderPassColorAttachment { 257 | view: &view, 258 | resolve_target: None, 259 | ops: wgpu::Operations { 260 | load: wgpu::LoadOp::Clear(wgpu::Color { 261 | r: 1.0, 262 | g: 0.0, 263 | b: 0.0, 264 | a: 1.0, 265 | }), 266 | store: wgpu::StoreOp::Store, 267 | }, 268 | })], 269 | depth_stencil_attachment: None, 270 | timestamp_writes: None, 271 | occlusion_query_set: None, 272 | }); 273 | rp.set_pipeline(&self.pipeline); 274 | rp.set_bind_group(0, &self.bind_group, &[]); // NEW! 275 | rp.set_push_constants( 276 | wgpu::ShaderStages::FRAGMENT, 277 | 0, 278 | bytemuck::cast_slice(&[FrameUniforms::from(ctx)]), 279 | ); 280 | rp.draw(0..4, 0..1); 281 | } 282 | } 283 | 284 | fn texture_format_from_sctk(f: Format) -> wgpu::TextureFormat { 285 | use wgpu::TextureFormat::*; 286 | use Format::*; 287 | match f { 288 | Argb8888 | Xrgb8888 => Bgra8UnormSrgb, 289 | Xbgr8888 | Abgr8888 => Rgba8UnormSrgb, 290 | _ => panic!("Unsupported format: {:?}", f), 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /src/graphics/icon.rs: -------------------------------------------------------------------------------- 1 | use anyhow::*; 2 | #[allow(unused_imports)] 3 | use log::{debug, error, info, warn}; 4 | 5 | use wgpu::util::DeviceExt; 6 | 7 | pub const VS_MAIN: &str = "main"; 8 | pub const FS_MAIN: &str = "main"; 9 | 10 | #[repr(C)] 11 | #[derive(Debug, Copy, Clone)] 12 | struct Uniforms { 13 | transform: cgmath::Matrix4, 14 | } 15 | unsafe impl bytemuck::Pod for Uniforms {} 16 | unsafe impl bytemuck::Zeroable for Uniforms {} 17 | 18 | struct UniformsHandle { 19 | data: Uniforms, 20 | texture_transform: cgmath::Matrix4, 21 | buffer: wgpu::Buffer, 22 | } 23 | 24 | pub struct State { 25 | pipeline: wgpu::RenderPipeline, 26 | bind_group: wgpu::BindGroup, 27 | uniforms_handle: UniformsHandle, 28 | } 29 | 30 | impl State { 31 | pub fn new( 32 | device: &wgpu::Device, 33 | queue: &wgpu::Queue, 34 | swapchain_format: wgpu::TextureFormat, 35 | icon: &image::RgbaImage, 36 | ) -> Result { 37 | let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { 38 | entries: &[ 39 | wgpu::BindGroupLayoutEntry { 40 | binding: 0, 41 | visibility: wgpu::ShaderStages::FRAGMENT, 42 | ty: wgpu::BindingType::Texture { 43 | sample_type: wgpu::TextureSampleType::Float { filterable: true }, 44 | view_dimension: wgpu::TextureViewDimension::D2, 45 | multisampled: false, 46 | }, 47 | count: None, 48 | }, 49 | wgpu::BindGroupLayoutEntry { 50 | binding: 1, 51 | visibility: wgpu::ShaderStages::FRAGMENT, 52 | ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), 53 | count: None, 54 | }, 55 | wgpu::BindGroupLayoutEntry { 56 | binding: 2, 57 | visibility: wgpu::ShaderStages::VERTEX, 58 | ty: wgpu::BindingType::Buffer { 59 | ty: wgpu::BufferBindingType::Uniform, 60 | has_dynamic_offset: false, 61 | min_binding_size: None, 62 | }, 63 | count: None, 64 | }, 65 | ], 66 | label: Some("icon bind_group_layout"), 67 | }); 68 | 69 | let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { 70 | label: Some("Icon Render pipeline layout"), 71 | bind_group_layouts: &[&bind_group_layout], 72 | push_constant_ranges: &[], 73 | }); 74 | 75 | let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { 76 | label: Some("Icon Render pipeline"), 77 | layout: Some(&pipeline_layout), 78 | vertex: wgpu::VertexState { 79 | module: &device 80 | .create_shader_module(wgpu::include_spirv!("../../resources/icon.vert.spv")), 81 | entry_point: VS_MAIN, 82 | buffers: &[], 83 | compilation_options: wgpu::PipelineCompilationOptions::default(), 84 | }, 85 | fragment: Some(wgpu::FragmentState { 86 | module: &device 87 | .create_shader_module(wgpu::include_spirv!("../../resources/icon.frag.spv")), 88 | entry_point: FS_MAIN, 89 | targets: &[Some(wgpu::ColorTargetState { 90 | format: swapchain_format, 91 | blend: Some(wgpu::BlendState::ALPHA_BLENDING), 92 | write_mask: wgpu::ColorWrites::ALL, 93 | })], 94 | compilation_options: wgpu::PipelineCompilationOptions::default(), 95 | }), 96 | primitive: wgpu::PrimitiveState { 97 | topology: wgpu::PrimitiveTopology::TriangleStrip, 98 | front_face: wgpu::FrontFace::Ccw, 99 | cull_mode: None, 100 | ..Default::default() 101 | }, 102 | multisample: wgpu::MultisampleState { 103 | count: 1, 104 | mask: !0, 105 | alpha_to_coverage_enabled: false, 106 | }, 107 | depth_stencil: None, 108 | multiview: None, 109 | cache: None, 110 | }); 111 | 112 | let texture_size = wgpu::Extent3d { 113 | width: icon.width(), 114 | height: icon.height(), 115 | depth_or_array_layers: 1, 116 | }; 117 | let texture = device.create_texture(&wgpu::TextureDescriptor { 118 | label: Some("Icon"), 119 | size: texture_size, 120 | mip_level_count: 1, 121 | sample_count: 1, 122 | dimension: wgpu::TextureDimension::D2, 123 | format: wgpu::TextureFormat::Rgba8UnormSrgb, 124 | usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, 125 | view_formats: &[], 126 | }); 127 | let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default()); 128 | let sampler = device.create_sampler(&wgpu::SamplerDescriptor { 129 | address_mode_u: wgpu::AddressMode::ClampToEdge, 130 | address_mode_v: wgpu::AddressMode::ClampToEdge, 131 | address_mode_w: wgpu::AddressMode::ClampToEdge, 132 | mag_filter: wgpu::FilterMode::Nearest, 133 | min_filter: wgpu::FilterMode::Nearest, 134 | mipmap_filter: wgpu::FilterMode::Nearest, 135 | ..Default::default() 136 | }); 137 | 138 | queue.write_texture( 139 | wgpu::ImageCopyTexture { 140 | texture: &texture, 141 | mip_level: 0, 142 | origin: wgpu::Origin3d::ZERO, 143 | aspect: wgpu::TextureAspect::All, 144 | }, 145 | icon, 146 | wgpu::ImageDataLayout { 147 | offset: 0, 148 | bytes_per_row: Some(4 * icon.width()), 149 | rows_per_image: Some(icon.height()), 150 | }, 151 | wgpu::Extent3d { 152 | width: icon.width(), 153 | height: icon.height(), 154 | depth_or_array_layers: 1, 155 | }, 156 | ); 157 | 158 | let texture_transform = 159 | cgmath::Matrix4::from_nonuniform_scale(icon.width() as f32, icon.height() as f32, 1.0); 160 | let uniforms = Uniforms { 161 | transform: texture_transform, 162 | }; 163 | 164 | let uniforms_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { 165 | label: Some("Uniforms Buffer"), 166 | contents: bytemuck::cast_slice(&[uniforms]), 167 | usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, 168 | }); 169 | 170 | let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { 171 | layout: &bind_group_layout, 172 | entries: &[ 173 | wgpu::BindGroupEntry { 174 | binding: 0, 175 | resource: wgpu::BindingResource::TextureView(&texture_view), 176 | }, 177 | wgpu::BindGroupEntry { 178 | binding: 1, 179 | resource: wgpu::BindingResource::Sampler(&sampler), 180 | }, 181 | wgpu::BindGroupEntry { 182 | binding: 2, 183 | resource: uniforms_buffer.as_entire_binding(), 184 | }, 185 | ], 186 | label: Some("icon bind group"), 187 | }); 188 | 189 | let uniforms_handle = UniformsHandle { 190 | data: uniforms, 191 | texture_transform, 192 | buffer: uniforms_buffer, 193 | }; 194 | 195 | Ok(Self { 196 | pipeline, 197 | bind_group, 198 | uniforms_handle, 199 | }) 200 | } 201 | 202 | pub fn resize(&mut self, queue: &wgpu::Queue, resolution_transform: cgmath::Matrix4) { 203 | self.uniforms_handle.data.transform = 204 | self.uniforms_handle.texture_transform * resolution_transform; 205 | queue.write_buffer( 206 | &self.uniforms_handle.buffer, 207 | 0, 208 | bytemuck::cast_slice(&[self.uniforms_handle.data]), 209 | ); 210 | } 211 | 212 | pub fn render(&mut self, encoder: &mut wgpu::CommandEncoder, view: &wgpu::TextureView) { 213 | let mut rp = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { 214 | label: Some("icon render pass"), 215 | color_attachments: &[Some(wgpu::RenderPassColorAttachment { 216 | view: &view, 217 | resolve_target: None, 218 | ops: wgpu::Operations { 219 | load: wgpu::LoadOp::Load, 220 | store: wgpu::StoreOp::Store, 221 | }, 222 | })], 223 | depth_stencil_attachment: None, 224 | timestamp_writes: None, 225 | occlusion_query_set: None, 226 | }); 227 | rp.set_pipeline(&self.pipeline); 228 | rp.set_bind_group(0, &self.bind_group, &[]); // NEW! 229 | rp.draw(0..4, 0..1); 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod authenticator; 2 | pub mod graphics; 3 | pub mod screencopy; 4 | pub mod window_manager; 5 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use anyhow::*; 4 | use either::Either; 5 | use futures::StreamExt; 6 | #[allow(unused_imports)] 7 | use log::{debug, error, info, warn}; 8 | use sctk::reexports::client::backend::ObjectId; 9 | use sctk::reexports::client::protocol::wl_output::WlOutput; 10 | use sctk::reexports::client::Proxy; 11 | use sctk::session_lock::*; 12 | use shaderlock::authenticator::{ 13 | Authenticator, AuthenticatorBackend, NullAuthenticatorBackend, PamAuthenticatorBackend, 14 | }; 15 | use shaderlock::graphics::RenderContext; 16 | use shaderlock::screencopy::ScreencopyBuffer; 17 | use shaderlock::window_manager::ExitSync; 18 | 19 | use clap::Parser; 20 | use sctk::seat::keyboard::{KeyEvent, Keysym}; 21 | use shaderlock::screencopy::ScreencopyHandler; 22 | use shaderlock::window_manager::WindowManager; 23 | use shaderlock::window_manager::{Event, Window}; 24 | use tokio::task::LocalSet; 25 | 26 | const DATADIR: &str = env!("DATADIR"); 27 | const SHADER_GLOB: &str = "shaders/*.frag"; 28 | const ICON_FILE: &str = "lock-icon.png"; 29 | const FREEZE_AFTER_INACTIVITY: std::time::Duration = std::time::Duration::from_secs(10); 30 | const FADE_BEFORE_FREEZE: std::time::Duration = std::time::Duration::from_secs(5); 31 | 32 | #[derive(Parser)] 33 | #[command(version, author, about)] 34 | struct Args { 35 | /// Authentication always succeeds, for testing. 36 | #[arg(long, default_value_t = false)] 37 | skip_auth: bool, 38 | 39 | /// Shader applied to the lock screen background. 40 | #[arg(long, short)] 41 | shader_file: Option, 42 | 43 | /// Icon to overlay on the lock screen. 44 | #[arg(long, default_value_t = format!("{}/{}", DATADIR, ICON_FILE))] 45 | icon_file: String, 46 | } 47 | 48 | fn get_shader_file() -> Result { 49 | use rand::seq::IteratorRandom; 50 | let mut rng = rand::thread_rng(); 51 | let file = glob::glob(&format!("{}/{}", DATADIR, SHADER_GLOB)) 52 | .expect("Failed to parse shader file glob") 53 | .choose(&mut rng) 54 | .context("Failed to randomly pick a shader file")? 55 | .context("Failed to get the path to the shader")?; 56 | 57 | info!("Chosen shader {}", file.to_string_lossy()); 58 | Ok(file) 59 | } 60 | 61 | #[tokio::main] 62 | async fn main() -> Result<()> { 63 | env_logger::init(); 64 | LocalSet::new() 65 | .run_until(async move { 66 | let args = Args::parse(); 67 | 68 | let shader_file = match args.shader_file { 69 | Some(s) => std::path::PathBuf::from(s), 70 | None => get_shader_file()?, 71 | }; 72 | let icon_file = std::path::PathBuf::from(args.icon_file); 73 | 74 | let graphics_manager = shaderlock::graphics::Manager::new(&shader_file, &icon_file) 75 | .context("Failed to create graphics manager")?; 76 | 77 | let mut authenticator_backend = if args.skip_auth { 78 | Either::Left(NullAuthenticatorBackend::new()) 79 | } else { 80 | Either::Right(PamAuthenticatorBackend::new()?) 81 | }; 82 | 83 | let mut auth = Authenticator::new( 84 | authenticator_backend 85 | .as_mut() 86 | .map_either( 87 | |v| v as &mut dyn AuthenticatorBackend, 88 | |v| v as &mut dyn AuthenticatorBackend, 89 | ) 90 | .into_inner(), 91 | )?; 92 | 93 | let mut wm = WindowManager::new()?; 94 | 95 | let mut keyboard = None; 96 | let init_time = std::time::Instant::now(); 97 | let mut last_keypress_time = std::time::Instant::now(); 98 | 99 | let mut output_by_surface = HashMap::::new(); 100 | let mut frame_by_output = HashMap::::new(); 101 | let mut lock_surface_by_surface = HashMap::::new(); 102 | let mut graphics_by_surface = HashMap::::new(); 103 | 104 | wm.run(|conn, qh, mut state, events| async move { 105 | let outputs: Vec<_> = state.access(|s| s.output_state.outputs().collect()); 106 | // Screenshot capture must happen before the session lock else we will just get a black screen. 107 | for output in outputs { 108 | let frame_handle = state 109 | .access(|s| { 110 | debug!("capture frame on output: {:?}", output); 111 | let res = s.screencopy_state().capture_output(&output, qh); 112 | conn.flush()?; 113 | res 114 | })? 115 | .await??; 116 | debug!("capture complete, getting buffer data"); 117 | let frame = state.access(|s| s.get_buffer_data(frame_handle)); 118 | 119 | frame_by_output.insert(output.id(), frame); 120 | } 121 | 122 | // From this point onwards, the compositor will blank the screen and inhibit input to apps. 123 | let session_lock = state.access(|s| s.session_lock_state.lock(qh))?; 124 | sd_notify::notify(true, &[sd_notify::NotifyState::Ready]) 125 | .context("Failed to notify readiness")?; 126 | 127 | loop { 128 | debug!("awaiting events"); 129 | let event = events.next().await.context("events stream was closed")?; 130 | debug!("got event: {:?}", event); 131 | match event { 132 | Event::NewOutput(output) => { 133 | let lock_surface = state.access(|s| { 134 | let surface = s.compositor_state.create_surface(qh); 135 | session_lock.create_lock_surface(surface, &output, qh) 136 | }); 137 | conn.flush()?; 138 | debug!("created lock surface: {:?}", lock_surface); 139 | output_by_surface.insert(lock_surface.wl_surface().id(), output); 140 | lock_surface_by_surface 141 | .insert(lock_surface.wl_surface().id(), lock_surface); 142 | } 143 | Event::SessionLocked => {} 144 | Event::SessionLockFinished => { 145 | error!("session lock failed!"); 146 | bail!("session lock failed!"); 147 | } 148 | Event::ConfigureLockSurface(lock_surface, (width, height)) => { 149 | let surface = lock_surface.wl_surface(); 150 | let output = output_by_surface.get(&surface.id()).unwrap(); 151 | // TODO: if a new monitor is plugged in there won't be a screenshot. 152 | let frame = frame_by_output.remove(&output.id()).unwrap(); 153 | 154 | let window = Window { 155 | display: conn.display(), 156 | surface: surface.clone(), 157 | }; 158 | 159 | debug!("initializing graphics on output: {:?}", output); 160 | let graphics = graphics_manager 161 | .init_window(window, frame, (width, height)) 162 | .await?; 163 | debug!("graphics initialized"); 164 | 165 | graphics_by_surface.insert(surface.id(), graphics); 166 | 167 | // Trigger the first draw. Requesting a frame event from Wayland doesn't seem to work, 168 | // I think that only works after the first commit. 169 | state.access(|s| s.queue_redraw(lock_surface.wl_surface().clone())); 170 | } 171 | Event::RedrawRequested(surface) => { 172 | debug!("redraw requested on surface: {:?}", surface); 173 | let graphics = graphics_by_surface.get_mut(&surface.id()).unwrap(); 174 | let ctx = RenderContext { 175 | elapsed: init_time.elapsed(), 176 | fade_amount: (last_keypress_time.elapsed() + FADE_BEFORE_FREEZE) 177 | .saturating_sub(FREEZE_AFTER_INACTIVITY) 178 | .as_secs_f32() 179 | / FADE_BEFORE_FREEZE.as_secs_f32(), 180 | }; 181 | let frame = graphics.render(ctx); 182 | if last_keypress_time.elapsed() < FREEZE_AFTER_INACTIVITY { 183 | debug!("requesting next frame"); 184 | surface.frame(qh, surface.clone()); 185 | conn.flush()?; 186 | } 187 | debug!("scheduling present of current frame"); 188 | frame.present(); 189 | } 190 | Event::NewSeatCapability(seat, capability) => { 191 | if capability == sctk::seat::Capability::Keyboard { 192 | debug!("configure keyboard"); 193 | keyboard.replace( 194 | state.access(|s| s.seat_state.get_keyboard(qh, &seat, None))?, 195 | ); 196 | } 197 | } 198 | Event::RemoveSeatCapability(_seat, capability) => { 199 | if capability == sctk::seat::Capability::Keyboard { 200 | debug!("deconfigure keyboard"); 201 | keyboard.take(); 202 | } 203 | } 204 | Event::KeyPressed(key_event) => { 205 | // Sway will only attach input events after the first buffer is committed to a 206 | // lock surface, so we will only start getting KeyPressed events after the first render. 207 | last_keypress_time = std::time::Instant::now(); 208 | match key_event { 209 | KeyEvent { 210 | keysym: Keysym::Escape, 211 | .. 212 | } => { 213 | auth.clear(); 214 | } 215 | KeyEvent { 216 | keysym: Keysym::BackSpace | Keysym::Delete | Keysym::KP_Delete, 217 | .. 218 | } => { 219 | auth.pop(); 220 | } 221 | KeyEvent { 222 | keysym: Keysym::Return | Keysym::KP_Enter | Keysym::ISO_Enter, 223 | .. 224 | } => { 225 | // Note that a Return keypress also has utf8 data "\r", so match this before 226 | // the text arm. 227 | match auth.authenticate() { 228 | Result::Ok(_) => { 229 | session_lock.unlock(); 230 | conn.display().sync(qh, ExitSync); 231 | conn.flush()?; 232 | } 233 | Result::Err(e) => warn!("Authentication failed: {}", e), 234 | }; 235 | } 236 | KeyEvent { 237 | utf8: Some(text), .. 238 | } => { 239 | debug!("got input: {}", text); 240 | for c in text.chars() { 241 | auth.push(c); 242 | } 243 | } 244 | KeyEvent { keysym, .. } => { 245 | debug!("unknown key pressed: {:?}", keysym); 246 | } 247 | }; 248 | } 249 | Event::ExitSync => { 250 | info!("exiting"); 251 | return Ok(()); 252 | } 253 | }; 254 | } 255 | }) 256 | .await 257 | }) 258 | .await 259 | } 260 | -------------------------------------------------------------------------------- /src/screencopy.rs: -------------------------------------------------------------------------------- 1 | use std::{error::Error, sync::Mutex}; 2 | 3 | use anyhow::Result; 4 | #[allow(unused_imports)] 5 | use log::{debug, error, info, warn}; 6 | 7 | use sctk::{ 8 | globals::GlobalData, 9 | reexports::{ 10 | client::{ 11 | globals::GlobalList, 12 | protocol::{ 13 | wl_buffer::WlBuffer, 14 | wl_output::{Transform, WlOutput}, 15 | wl_shm::Format, 16 | }, 17 | Connection, Dispatch, QueueHandle, WEnum, 18 | }, 19 | protocols_wlr::screencopy::v1::client::{ 20 | zwlr_screencopy_frame_v1, zwlr_screencopy_manager_v1, 21 | }, 22 | }, 23 | registry::GlobalProxy, 24 | }; 25 | 26 | pub trait HasWlBuffer { 27 | fn wl_buffer(&self) -> &WlBuffer; 28 | } 29 | 30 | impl HasWlBuffer for sctk::shm::slot::Buffer { 31 | fn wl_buffer(&self) -> &WlBuffer { 32 | self.wl_buffer() 33 | } 34 | } 35 | 36 | pub trait ScreencopyHandler: Sized { 37 | type ShmBuffer: HasWlBuffer + Send + Sync + std::fmt::Debug; 38 | type CreateBufferError: Error; 39 | 40 | fn screencopy_state(&mut self) -> &mut ScreencopyState; 41 | 42 | /// Create an SHM buffer to which Wayland can write the screenshot. 43 | fn create_buffer( 44 | &mut self, 45 | info: &BufferInfo, 46 | ) -> Result; 47 | 48 | /// Get the raw buffer bytes for a screenshot buffer. 49 | fn get_buffer_data( 50 | &mut self, 51 | handle: ScreencopyBufferHandle, 52 | ) -> ScreencopyBuffer; 53 | } 54 | 55 | #[derive(Debug)] 56 | pub struct ScreencopyState { 57 | manager: GlobalProxy, 58 | } 59 | 60 | impl ScreencopyState { 61 | pub fn new(globals: &GlobalList, qh: &QueueHandle) -> Self 62 | where 63 | D: Dispatch + 'static, 64 | { 65 | // Version 3 of the screencopy protocol sends the BufferDone event. 66 | let manager = GlobalProxy::from(globals.bind(qh, 3..=3, GlobalData)); 67 | Self { manager } 68 | } 69 | 70 | pub fn capture_output( 71 | &self, 72 | output: &WlOutput, 73 | qh: &QueueHandle, 74 | ) -> Result>>> 75 | where 76 | D: Dispatch< 77 | zwlr_screencopy_frame_v1::ZwlrScreencopyFrameV1, 78 | ScreencopyCaptureOutputData, 79 | > + ScreencopyHandler 80 | + 'static, 81 | { 82 | let manager = self.manager.get()?; 83 | 84 | let (tx, rx) = futures::channel::oneshot::channel(); 85 | manager.capture_output(0, output, qh, ScreencopyCaptureOutputData::new(tx)); 86 | Ok(rx) 87 | } 88 | } 89 | 90 | #[macro_export] 91 | macro_rules! delegate_screencopy { 92 | ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { 93 | sctk::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: 94 | [ 95 | sctk::reexports::protocols_wlr::screencopy::v1::client::zwlr_screencopy_manager_v1::ZwlrScreencopyManagerV1: sctk::globals::GlobalData 96 | ] => $crate::screencopy::ScreencopyState 97 | ); 98 | sctk::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: 99 | [ 100 | sctk::reexports::protocols_wlr::screencopy::v1::client::zwlr_screencopy_frame_v1::ZwlrScreencopyFrameV1: $crate::screencopy::ScreencopyCaptureOutputData 101 | ] => $crate::screencopy::ScreencopyState 102 | ); 103 | }; 104 | } 105 | 106 | #[derive(Default)] 107 | pub struct ScreencopyCaptureOutputData { 108 | on_done: 109 | Mutex>>>>, 110 | info: Mutex>, 111 | flags: Mutex>, 112 | buffer: Mutex>, 113 | } 114 | 115 | impl ScreencopyCaptureOutputData { 116 | fn new( 117 | on_done: futures::channel::oneshot::Sender>>, 118 | ) -> Self { 119 | Self { 120 | on_done: Mutex::new(Some(on_done)), 121 | info: Mutex::new(None), 122 | flags: Mutex::new(None), 123 | buffer: Mutex::new(None), 124 | } 125 | } 126 | } 127 | 128 | impl Dispatch 129 | for ScreencopyState 130 | where 131 | D: Dispatch, 132 | { 133 | fn event( 134 | _state: &mut D, 135 | _proxy: &zwlr_screencopy_manager_v1::ZwlrScreencopyManagerV1, 136 | _event: zwlr_screencopy_manager_v1::Event, 137 | _: &GlobalData, 138 | _: &Connection, 139 | _: &QueueHandle, 140 | ) { 141 | unreachable!() 142 | } 143 | } 144 | 145 | impl 146 | Dispatch< 147 | zwlr_screencopy_frame_v1::ZwlrScreencopyFrameV1, 148 | ScreencopyCaptureOutputData, 149 | D, 150 | > for ScreencopyState 151 | where 152 | D: Dispatch< 153 | zwlr_screencopy_frame_v1::ZwlrScreencopyFrameV1, 154 | ScreencopyCaptureOutputData, 155 | > + ScreencopyHandler, 156 | { 157 | fn event( 158 | state: &mut D, 159 | proxy: &zwlr_screencopy_frame_v1::ZwlrScreencopyFrameV1, 160 | event: zwlr_screencopy_frame_v1::Event, 161 | data: &ScreencopyCaptureOutputData, 162 | conn: &Connection, 163 | _: &QueueHandle, 164 | ) { 165 | debug!("got screencopy event: {:?}", event); 166 | match event { 167 | // Step 1: one or more Buffer events inform the client of available buffer formats. 168 | zwlr_screencopy_frame_v1::Event::Buffer { 169 | format: WEnum::Value(format), 170 | width, 171 | height, 172 | stride, 173 | } => { 174 | data.info.lock().unwrap().replace(BufferInfo { 175 | width, 176 | height, 177 | stride, 178 | format, 179 | }); 180 | } 181 | // Step 1b: zero or more LinuxDmabuf events inform the client of available DMA buffer formats. 182 | zwlr_screencopy_frame_v1::Event::LinuxDmabuf { .. } => {} 183 | // Step 2: one Flags event informs the client of any flags. 184 | zwlr_screencopy_frame_v1::Event::Flags { 185 | flags: WEnum::Value(flags), 186 | } => { 187 | data.flags.lock().unwrap().replace(flags); 188 | } 189 | // Step 3: one BufferDone event informs the client all Buffer events have been sent, 190 | // and the client should start a copy. 191 | zwlr_screencopy_frame_v1::Event::BufferDone => { 192 | let info_guard = data.info.lock().unwrap(); 193 | let info = info_guard.as_ref().unwrap(); 194 | debug!("Creating buffer with info {:?}", info); 195 | let buffer = state.create_buffer(info).unwrap(); 196 | proxy.copy(buffer.wl_buffer()); 197 | conn.flush().unwrap(); 198 | data.buffer.lock().unwrap().replace(buffer); 199 | } 200 | // Step 4: one Ready event informs the client the copy is successful. 201 | zwlr_screencopy_frame_v1::Event::Ready { .. } => { 202 | let info = data.info.lock().unwrap().take().unwrap(); 203 | let flags = data.flags.lock().unwrap().take().unwrap(); 204 | let buffer = data.buffer.lock().unwrap().take().unwrap(); 205 | 206 | let handle = ScreencopyBufferHandle { 207 | buffer, 208 | info, 209 | transform: Transform::Normal, 210 | y_invert: flags.contains(zwlr_screencopy_frame_v1::Flags::YInvert), 211 | }; 212 | data.on_done 213 | .lock() 214 | .unwrap() 215 | .take() 216 | .unwrap() 217 | .send(Ok(handle)) 218 | .unwrap(); 219 | } 220 | // Step 4b: one Failed event informs the client the copy has failed. 221 | zwlr_screencopy_frame_v1::Event::Failed => { 222 | data.on_done 223 | .lock() 224 | .unwrap() 225 | .take() 226 | .unwrap() 227 | .send(Err(todo!())) 228 | .unwrap(); 229 | } 230 | zwlr_screencopy_frame_v1::Event::Damage { .. } => unimplemented!(), 231 | _ => unimplemented!(), 232 | } 233 | } 234 | } 235 | 236 | #[derive(Debug)] 237 | pub struct BufferInfo { 238 | pub width: u32, 239 | pub height: u32, 240 | pub stride: u32, 241 | pub format: Format, 242 | } 243 | 244 | #[derive(Debug)] 245 | pub struct ScreencopyBufferHandle { 246 | pub buffer: ShmBuffer, 247 | pub info: BufferInfo, 248 | pub transform: Transform, 249 | pub y_invert: bool, 250 | } 251 | 252 | pub struct ScreencopyBuffer { 253 | info: BufferInfo, 254 | transform: Transform, 255 | y_invert: bool, 256 | data: Vec, 257 | } 258 | 259 | impl ScreencopyBuffer { 260 | pub fn new( 261 | ScreencopyBufferHandle { 262 | buffer, 263 | info, 264 | transform, 265 | y_invert, 266 | }: ScreencopyBufferHandle, 267 | data: &[u8], 268 | ) -> Self { 269 | let data = data.to_vec(); 270 | drop(buffer); 271 | Self { 272 | info, 273 | transform, 274 | y_invert, 275 | data, 276 | } 277 | } 278 | 279 | pub fn bytes(&self) -> &[u8] { 280 | &self.data 281 | } 282 | 283 | pub fn width(&self) -> u32 { 284 | self.info.width 285 | } 286 | 287 | pub fn height(&self) -> u32 { 288 | self.info.height 289 | } 290 | 291 | pub fn stride(&self) -> u32 { 292 | self.info.stride 293 | } 294 | 295 | pub fn format(&self) -> Format { 296 | self.info.format 297 | } 298 | 299 | pub fn transform_matrix(&self) -> cgmath::Matrix4 { 300 | use cgmath::{Angle, Matrix4, Rad}; 301 | let angle = Rad::turn_div_4() 302 | * match self.transform { 303 | Transform::Normal | Transform::Flipped => 0.0, 304 | Transform::_90 | Transform::Flipped90 => 1.0, 305 | Transform::_180 | Transform::Flipped180 => 2.0, 306 | Transform::_270 | Transform::Flipped270 => 3.0, 307 | _ => panic!("Unsupported transform"), 308 | }; 309 | let flip = matches!( 310 | self.transform, 311 | Transform::Flipped 312 | | Transform::Flipped90 313 | | Transform::Flipped180 314 | | Transform::Flipped270 315 | ) ^ self.y_invert; 316 | Matrix4::from_angle_z(angle) 317 | * Matrix4::from_nonuniform_scale(if flip { -1.0 } else { 1.0 }, 1.0, 1.0) 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /src/window_manager.rs: -------------------------------------------------------------------------------- 1 | use std::cell::RefCell; 2 | use std::future::Future; 3 | use std::os::fd::AsFd; 4 | use std::ptr::NonNull; 5 | 6 | use anyhow::*; 7 | use futures::channel::mpsc; 8 | use futures::FutureExt; 9 | #[allow(unused_imports)] 10 | use log::{debug, error, info, warn}; 11 | 12 | use sctk::compositor::*; 13 | use sctk::output::*; 14 | use sctk::reexports::client as wl; 15 | use sctk::reexports::client::backend::WaylandError; 16 | use sctk::reexports::client::globals::registry_queue_init; 17 | use sctk::reexports::client::Proxy; 18 | use sctk::registry::*; 19 | use sctk::seat::keyboard::KeyboardHandler; 20 | use sctk::seat::SeatHandler; 21 | use sctk::seat::SeatState; 22 | use sctk::session_lock::*; 23 | use sctk::shm::*; 24 | use tokio::io::unix::AsyncFd; 25 | use tokio::time::timeout; 26 | use wgpu::rwh; 27 | 28 | use crate::screencopy::ScreencopyBuffer; 29 | use crate::screencopy::ScreencopyHandler; 30 | use crate::screencopy::ScreencopyState; 31 | 32 | const RECEIVE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(1); 33 | 34 | pub struct WindowManagerState { 35 | pub output_state: OutputState, 36 | 37 | pub compositor_state: CompositorState, 38 | 39 | pub screencopy_state: ScreencopyState, 40 | 41 | pub registry_state: RegistryState, 42 | 43 | pub shm: Shm, 44 | pub buffer_pool: slot::SlotPool, 45 | 46 | pub session_lock_state: SessionLockState, 47 | // pub session_lock: SessionLock, 48 | // pub surfaces: Vec<(wl::protocol::wl_output::WlOutput, SessionLockSurface)>, 49 | pub seat_state: SeatState, 50 | 51 | pub events: mpsc::UnboundedSender, 52 | } 53 | 54 | impl WindowManagerState { 55 | pub fn queue_redraw(&mut self, surface: wl::protocol::wl_surface::WlSurface) { 56 | self.events 57 | .unbounded_send(Event::RedrawRequested(surface)) 58 | .expect("send event"); 59 | } 60 | } 61 | 62 | pub struct WindowManager { 63 | pub conn: wl::Connection, 64 | pub qh: wl::QueueHandle, 65 | pub event_queue: wl::EventQueue, 66 | 67 | pub state_cell: RefCell, 68 | pub events: mpsc::UnboundedReceiver, 69 | } 70 | 71 | impl WindowManager { 72 | pub fn new() -> Result { 73 | let conn = wl::Connection::connect_to_env()?; 74 | let (globals, event_queue) = registry_queue_init::(&conn)?; 75 | let qh = event_queue.handle(); 76 | 77 | let output_state = OutputState::new(&globals, &qh); 78 | let compositor_state = CompositorState::bind(&globals, &qh)?; 79 | let session_lock_state = SessionLockState::new(&globals, &qh); 80 | let screencopy_state = ScreencopyState::new(&globals, &qh); 81 | let shm = Shm::bind(&globals, &qh)?; 82 | let registry_state = RegistryState::new(&globals); 83 | let seat_state = SeatState::new(&globals, &qh); 84 | 85 | let buffer_pool = slot::SlotPool::new(1024, &shm)?; 86 | 87 | let (tx, rx) = mpsc::unbounded(); 88 | 89 | let state = WindowManagerState { 90 | output_state, 91 | 92 | compositor_state, 93 | 94 | screencopy_state, 95 | 96 | registry_state, 97 | 98 | shm, 99 | buffer_pool, 100 | 101 | session_lock_state, 102 | 103 | seat_state, 104 | 105 | events: tx, 106 | }; 107 | 108 | let state_cell = RefCell::new(state); 109 | 110 | Ok(Self { 111 | conn, 112 | qh, 113 | event_queue, 114 | state_cell, 115 | events: rx, 116 | }) 117 | } 118 | 119 | /// Run the event loop with a provided handler task. 120 | /// 121 | /// The funky lifetime annotations declare the references passed to the handler function 122 | /// to live as long as the original reference to the `WindowManager` itself, which are 123 | /// necessary since the handler function returns a `Future` that captures those references. 124 | pub async fn run<'a, Fut>( 125 | &'a mut self, 126 | f: impl FnOnce( 127 | &'a wl::Connection, 128 | &'a wl::QueueHandle, 129 | WindowManagerStateAccessor<'a>, 130 | &'a mut mpsc::UnboundedReceiver, 131 | ) -> Fut, 132 | ) -> Result<()> 133 | where 134 | Fut: Future>, 135 | { 136 | let event_queue = &mut self.event_queue; 137 | let state_cell = &self.state_cell; 138 | let fd = AsyncFd::new(self.conn.as_fd()).unwrap(); 139 | let receiver = async move { 140 | let mut state = WindowManagerStateAccessor::new(state_cell); 141 | loop { 142 | debug!("flushing event queue"); 143 | event_queue.flush().unwrap(); 144 | 145 | // The Wayland docs say that we should poll while holding a prepared read guard, 146 | // but this deadlocks against wgpu since the wl_display (aka wl::Connection) expects 147 | // to be read once per thread, and cannot synchronize multiple prepared reads on the 148 | // same thread which occurs when we yield to await fd.readable(). 149 | // Instead, we await the FD outside of the prepared read, then handle the case where 150 | // there are no events (ErrorKind::WouldBlock). 151 | debug!("awaiting wayland socket read"); 152 | let mut guard = match timeout(RECEIVE_TIMEOUT, fd.readable()).await { 153 | Result::Ok(v) => v, 154 | Result::Err(_) => continue, 155 | }?; 156 | guard.clear_ready(); 157 | 158 | debug!("reading wayland socket"); 159 | if let Some(read_guard) = event_queue.prepare_read() { 160 | match read_guard.read() { 161 | Result::Err(WaylandError::Io(err)) 162 | if err.kind() == std::io::ErrorKind::WouldBlock => 163 | { 164 | continue 165 | } 166 | v => v, 167 | }?; 168 | } 169 | 170 | // dispatch_pending runs the various callbacks scattered all over the place. 171 | // They all run on this thread, which is handy since we don't need Send/Sync 172 | // to pull events out via channels into other async tasks. 173 | debug!("dispatching pending events"); 174 | state.access(|s| event_queue.dispatch_pending(s))?; 175 | debug!("dispatch complete"); 176 | } 177 | }; 178 | 179 | let state_accessor = WindowManagerStateAccessor::new(&self.state_cell); 180 | let handler = f(&self.conn, &self.qh, state_accessor, &mut self.events); 181 | 182 | // Caution: the handler must not block waiting for a Wayland event, since these are dispatched 183 | // from the receiver task which will only execute when the handler awaits. 184 | futures::select! { 185 | receiver_res = receiver.fuse() => receiver_res, 186 | handler_res = handler.fuse() => handler_res, 187 | } 188 | } 189 | } 190 | 191 | /// WindowManagerStateAccessor wraps access to a `WindowManagerState`, giving 192 | /// mutable access but only within a non-async context such that the reference 193 | /// has a bounded lifetime. 194 | /// 195 | /// This lets us safely share a `WindowManagerState` between multiple async tasks 196 | /// on the same thread, namely within our Wayland client receiver and handler tasks. 197 | /// 198 | /// The case we want to avoid is a reference to `WindowManagerState` is stored across 199 | /// an `await`, which would panic when the inner `RefCell` gets dereferenced in a 200 | /// different async task. 201 | pub struct WindowManagerStateAccessor<'a>(&'a RefCell); 202 | 203 | impl<'a> WindowManagerStateAccessor<'a> { 204 | pub fn new(inner: &'a RefCell) -> Self { 205 | Self(inner) 206 | } 207 | 208 | pub fn access(&mut self, f: impl FnOnce(&mut WindowManagerState) -> R) -> R { 209 | let mut state = self.0.borrow_mut(); 210 | f(&mut state) 211 | } 212 | } 213 | 214 | #[derive(Clone, Debug)] 215 | pub enum Event { 216 | /// New output discovered (either just-connected or on app startup). 217 | NewOutput(wl::protocol::wl_output::WlOutput), 218 | /// Redraw requested for a surface. 219 | RedrawRequested(wl::protocol::wl_surface::WlSurface), 220 | 221 | /// Seat input method added. 222 | NewSeatCapability(wl::protocol::wl_seat::WlSeat, sctk::seat::Capability), 223 | /// Seat input method removed. 224 | RemoveSeatCapability(wl::protocol::wl_seat::WlSeat, sctk::seat::Capability), 225 | /// Key pressed. 226 | KeyPressed(sctk::seat::keyboard::KeyEvent), 227 | 228 | /// Session locked successfully. 229 | SessionLocked, 230 | /// Session lock failed. 231 | SessionLockFinished, 232 | /// Lock surface ready to be configured. 233 | ConfigureLockSurface(SessionLockSurface, (u32, u32)), 234 | 235 | /// Exit was requested and all messages before the sync have been processed. 236 | ExitSync, 237 | } 238 | 239 | pub struct ExitSync; 240 | 241 | #[derive(Clone, Debug)] 242 | pub struct Window { 243 | pub display: wl::protocol::wl_display::WlDisplay, 244 | pub surface: wl::protocol::wl_surface::WlSurface, 245 | } 246 | 247 | impl rwh::HasWindowHandle for Window { 248 | fn window_handle(&self) -> Result, rwh::HandleError> { 249 | let wwh = rwh::WaylandWindowHandle::new( 250 | NonNull::new(self.surface.id().as_ptr() as *mut _).unwrap(), 251 | ); 252 | unsafe { Result::Ok(rwh::WindowHandle::borrow_raw(wwh.into())) } 253 | } 254 | } 255 | 256 | impl rwh::HasDisplayHandle for Window { 257 | fn display_handle(&self) -> Result, rwh::HandleError> { 258 | let wdh = rwh::WaylandDisplayHandle::new( 259 | NonNull::new(self.display.id().as_ptr() as *mut _).unwrap(), 260 | ); 261 | unsafe { Result::Ok(rwh::DisplayHandle::borrow_raw(wdh.into())) } 262 | } 263 | } 264 | 265 | sctk::delegate_output!(WindowManagerState); 266 | 267 | impl OutputHandler for WindowManagerState { 268 | fn output_state(&mut self) -> &mut OutputState { 269 | &mut self.output_state 270 | } 271 | 272 | fn new_output( 273 | &mut self, 274 | _conn: &wl::Connection, 275 | _qh: &wl::QueueHandle, 276 | output: wl::protocol::wl_output::WlOutput, 277 | ) { 278 | debug!("new output: {:?}", output); 279 | self.events 280 | .unbounded_send(Event::NewOutput(output)) 281 | .expect("send event"); 282 | } 283 | 284 | fn update_output( 285 | &mut self, 286 | _conn: &wl::Connection, 287 | _qh: &wl::QueueHandle, 288 | _output: wl::protocol::wl_output::WlOutput, 289 | ) { 290 | unimplemented!() 291 | } 292 | 293 | fn output_destroyed( 294 | &mut self, 295 | _conn: &wl::Connection, 296 | _qh: &wl::QueueHandle, 297 | _output: wl::protocol::wl_output::WlOutput, 298 | ) { 299 | unimplemented!() 300 | } 301 | } 302 | 303 | sctk::delegate_compositor!(WindowManagerState); 304 | 305 | impl CompositorHandler for WindowManagerState { 306 | fn scale_factor_changed( 307 | &mut self, 308 | _conn: &wl::Connection, 309 | _qh: &wl::QueueHandle, 310 | _surface: &wl::protocol::wl_surface::WlSurface, 311 | _new_factor: i32, 312 | ) { 313 | } 314 | 315 | fn transform_changed( 316 | &mut self, 317 | _conn: &wl::Connection, 318 | _qh: &wl::QueueHandle, 319 | _surface: &wl::protocol::wl_surface::WlSurface, 320 | _new_transform: wl::protocol::wl_output::Transform, 321 | ) { 322 | } 323 | 324 | fn frame( 325 | &mut self, 326 | _conn: &wl::Connection, 327 | _qh: &wl::QueueHandle, 328 | surface: &wl::protocol::wl_surface::WlSurface, 329 | _time: u32, 330 | ) { 331 | debug!("got frame event for surface: {:?}", surface); 332 | self.events 333 | .unbounded_send(Event::RedrawRequested(surface.clone())) 334 | .expect("send event"); 335 | } 336 | 337 | fn surface_enter( 338 | &mut self, 339 | _conn: &wl::Connection, 340 | _qh: &wl::QueueHandle, 341 | _surface: &wl::protocol::wl_surface::WlSurface, 342 | _output: &wl::protocol::wl_output::WlOutput, 343 | ) { 344 | } 345 | 346 | fn surface_leave( 347 | &mut self, 348 | _conn: &wl::Connection, 349 | _qh: &wl::QueueHandle, 350 | _surface: &wl::protocol::wl_surface::WlSurface, 351 | _output: &wl::protocol::wl_output::WlOutput, 352 | ) { 353 | } 354 | } 355 | 356 | sctk::delegate_session_lock!(WindowManagerState); 357 | 358 | impl SessionLockHandler for WindowManagerState { 359 | fn locked( 360 | &mut self, 361 | _conn: &wl::Connection, 362 | _qh: &wl::QueueHandle, 363 | _session_lock: SessionLock, 364 | ) { 365 | info!("locked"); 366 | self.events 367 | .unbounded_send(Event::SessionLocked) 368 | .expect("send event"); 369 | } 370 | 371 | fn finished( 372 | &mut self, 373 | _conn: &wl::Connection, 374 | _qh: &wl::QueueHandle, 375 | _session_lock: SessionLock, 376 | ) { 377 | info!("lock finished"); 378 | self.events 379 | .unbounded_send(Event::SessionLockFinished) 380 | .expect("send event"); 381 | } 382 | 383 | fn configure( 384 | &mut self, 385 | _conn: &wl::Connection, 386 | _qh: &wl::QueueHandle, 387 | surface: SessionLockSurface, 388 | configure: SessionLockSurfaceConfigure, 389 | _serial: u32, 390 | ) { 391 | debug!("configure lock surface: {:?}", surface); 392 | self.events 393 | .unbounded_send(Event::ConfigureLockSurface(surface, configure.new_size)) 394 | .expect("send event"); 395 | } 396 | } 397 | 398 | sctk::delegate_shm!(WindowManagerState); 399 | 400 | impl ShmHandler for WindowManagerState { 401 | fn shm_state(&mut self) -> &mut Shm { 402 | &mut self.shm 403 | } 404 | } 405 | 406 | sctk::delegate_registry!(WindowManagerState); 407 | 408 | impl ProvidesRegistryState for WindowManagerState { 409 | fn registry(&mut self) -> &mut RegistryState { 410 | &mut self.registry_state 411 | } 412 | sctk::registry_handlers![OutputState,]; 413 | } 414 | 415 | crate::delegate_screencopy!(WindowManagerState); 416 | 417 | impl ScreencopyHandler for WindowManagerState { 418 | type ShmBuffer = slot::Buffer; 419 | type CreateBufferError = slot::CreateBufferError; 420 | 421 | fn screencopy_state(&mut self) -> &mut ScreencopyState { 422 | &mut self.screencopy_state 423 | } 424 | 425 | fn create_buffer( 426 | &mut self, 427 | info: &crate::screencopy::BufferInfo, 428 | ) -> Result { 429 | debug!("creating buffer: {:?}", info); 430 | let (buffer, _) = self.buffer_pool.create_buffer( 431 | info.width as i32, 432 | info.height as i32, 433 | info.stride as i32, 434 | info.format, 435 | )?; 436 | buffer.activate().unwrap(); 437 | std::result::Result::Ok(buffer) 438 | } 439 | 440 | fn get_buffer_data( 441 | &mut self, 442 | handle: crate::screencopy::ScreencopyBufferHandle, 443 | ) -> crate::screencopy::ScreencopyBuffer { 444 | let bytes = self 445 | .buffer_pool 446 | .canvas(&handle.buffer) 447 | .expect("get buffer bytes"); 448 | ScreencopyBuffer::new(handle, bytes) 449 | } 450 | } 451 | 452 | sctk::delegate_keyboard!(WindowManagerState); 453 | 454 | impl KeyboardHandler for WindowManagerState { 455 | fn enter( 456 | &mut self, 457 | _conn: &wl::Connection, 458 | _qh: &wl::QueueHandle, 459 | _keyboard: &wl::protocol::wl_keyboard::WlKeyboard, 460 | _surface: &wl::protocol::wl_surface::WlSurface, 461 | _serial: u32, 462 | _raw: &[u32], 463 | _keysyms: &[sctk::seat::keyboard::Keysym], 464 | ) { 465 | } 466 | 467 | fn leave( 468 | &mut self, 469 | _conn: &wl::Connection, 470 | _qh: &wl::QueueHandle, 471 | _keyboard: &wl::protocol::wl_keyboard::WlKeyboard, 472 | _surface: &wl::protocol::wl_surface::WlSurface, 473 | _serial: u32, 474 | ) { 475 | } 476 | 477 | fn press_key( 478 | &mut self, 479 | _conn: &wl::Connection, 480 | _qh: &wl::QueueHandle, 481 | _keyboard: &wl::protocol::wl_keyboard::WlKeyboard, 482 | _serial: u32, 483 | event: sctk::seat::keyboard::KeyEvent, 484 | ) { 485 | debug!("press key event: {:?}", event); 486 | self.events 487 | .unbounded_send(Event::KeyPressed(event)) 488 | .expect("send event"); 489 | } 490 | 491 | fn release_key( 492 | &mut self, 493 | _conn: &wl::Connection, 494 | _qh: &wl::QueueHandle, 495 | _keyboard: &wl::protocol::wl_keyboard::WlKeyboard, 496 | _serial: u32, 497 | _event: sctk::seat::keyboard::KeyEvent, 498 | ) { 499 | } 500 | 501 | fn update_modifiers( 502 | &mut self, 503 | _conn: &wl::Connection, 504 | _qh: &wl::QueueHandle, 505 | _keyboard: &wl::protocol::wl_keyboard::WlKeyboard, 506 | _serial: u32, 507 | _modifiers: sctk::seat::keyboard::Modifiers, 508 | _layout: u32, 509 | ) { 510 | } 511 | } 512 | 513 | sctk::delegate_seat!(WindowManagerState); 514 | 515 | impl SeatHandler for WindowManagerState { 516 | fn seat_state(&mut self) -> &mut SeatState { 517 | &mut self.seat_state 518 | } 519 | 520 | fn new_seat( 521 | &mut self, 522 | _conn: &wl::Connection, 523 | _qh: &wl::QueueHandle, 524 | _seat: wl::protocol::wl_seat::WlSeat, 525 | ) { 526 | } 527 | 528 | fn new_capability( 529 | &mut self, 530 | _conn: &wl::Connection, 531 | _qh: &wl::QueueHandle, 532 | seat: wl::protocol::wl_seat::WlSeat, 533 | capability: sctk::seat::Capability, 534 | ) { 535 | debug!("new seat capability: {:?}", capability); 536 | self.events 537 | .unbounded_send(Event::NewSeatCapability(seat, capability)) 538 | .expect("send event"); 539 | } 540 | 541 | fn remove_capability( 542 | &mut self, 543 | _conn: &wl::Connection, 544 | _qh: &wl::QueueHandle, 545 | seat: wl::protocol::wl_seat::WlSeat, 546 | capability: sctk::seat::Capability, 547 | ) { 548 | debug!("remove seat capability: {:?}", capability); 549 | self.events 550 | .unbounded_send(Event::RemoveSeatCapability(seat, capability)) 551 | .expect("send event"); 552 | } 553 | 554 | fn remove_seat( 555 | &mut self, 556 | _conn: &wl::Connection, 557 | _qh: &wl::QueueHandle, 558 | _seat: wl::protocol::wl_seat::WlSeat, 559 | ) { 560 | } 561 | } 562 | 563 | wl::delegate_noop!(WindowManagerState: ignore wl::protocol::wl_buffer::WlBuffer); 564 | 565 | impl wl::Dispatch for WindowManagerState { 566 | fn event( 567 | state: &mut Self, 568 | _proxy: &wl::protocol::wl_callback::WlCallback, 569 | _event: ::Event, 570 | _data: &ExitSync, 571 | _conn: &wl::Connection, 572 | _qhandle: &wl::QueueHandle, 573 | ) { 574 | state 575 | .events 576 | .unbounded_send(Event::ExitSync) 577 | .expect("send event"); 578 | } 579 | } 580 | --------------------------------------------------------------------------------