next servicepoint version #1
					 9 changed files with 489 additions and 385 deletions
				
			
		
							
								
								
									
										373
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										373
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -31,7 +31,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "getrandom", | ||||
|  "getrandom 0.2.16", | ||||
|  "once_cell", | ||||
|  "version_check", | ||||
|  "zerocopy", | ||||
|  | @ -53,7 +53,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" | ||||
| dependencies = [ | ||||
|  "android-properties", | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "cc", | ||||
|  "cesu8", | ||||
|  "jni", | ||||
|  | @ -161,9 +161,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" | |||
| 
 | ||||
| [[package]] | ||||
| name = "bitflags" | ||||
| version = "2.8.0" | ||||
| version = "2.9.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" | ||||
| checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bitvec" | ||||
|  | @ -194,18 +194,18 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" | |||
| 
 | ||||
| [[package]] | ||||
| name = "bytemuck" | ||||
| version = "1.21.0" | ||||
| version = "1.23.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" | ||||
| checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" | ||||
| dependencies = [ | ||||
|  "bytemuck_derive", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bytemuck_derive" | ||||
| version = "1.8.1" | ||||
| version = "1.9.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" | ||||
| checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  | @ -220,27 +220,26 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" | |||
| 
 | ||||
| [[package]] | ||||
| name = "bytes" | ||||
| version = "1.10.0" | ||||
| version = "1.10.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" | ||||
| checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bzip2" | ||||
| version = "0.5.1" | ||||
| version = "0.5.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "75b89e7c29231c673a61a46e722602bcd138298f6b9e81e71119693534585f5c" | ||||
| checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" | ||||
| dependencies = [ | ||||
|  "bzip2-sys", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bzip2-sys" | ||||
| version = "0.1.12+1.0.8" | ||||
| version = "0.1.13+1.0.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "72ebc2f1a417f01e1da30ef264ee86ae31d2dcd2d603ea283d3c244a883ca2a9" | ||||
| checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" | ||||
| dependencies = [ | ||||
|  "cc", | ||||
|  "libc", | ||||
|  "pkg-config", | ||||
| ] | ||||
| 
 | ||||
|  | @ -250,7 +249,7 @@ version = "0.13.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "log", | ||||
|  "polling", | ||||
|  "rustix", | ||||
|  | @ -272,9 +271,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "cc" | ||||
| version = "1.2.14" | ||||
| version = "1.2.21" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9" | ||||
| checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" | ||||
| dependencies = [ | ||||
|  "jobserver", | ||||
|  "libc", | ||||
|  | @ -301,9 +300,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" | |||
| 
 | ||||
| [[package]] | ||||
| name = "clap" | ||||
| version = "4.5.30" | ||||
| version = "4.5.37" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d" | ||||
| checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" | ||||
| dependencies = [ | ||||
|  "clap_builder", | ||||
|  "clap_derive", | ||||
|  | @ -311,9 +310,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "clap_builder" | ||||
| version = "4.5.30" | ||||
| version = "4.5.37" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c" | ||||
| checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" | ||||
| dependencies = [ | ||||
|  "anstream", | ||||
|  "anstyle", | ||||
|  | @ -323,9 +322,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "clap_derive" | ||||
| version = "4.5.28" | ||||
| version = "4.5.32" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" | ||||
| checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" | ||||
| dependencies = [ | ||||
|  "heck", | ||||
|  "proc-macro2", | ||||
|  | @ -409,7 +408,7 @@ version = "0.24.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "core-foundation 0.10.0", | ||||
|  "core-graphics-types 0.2.0", | ||||
|  "foreign-types", | ||||
|  | @ -433,7 +432,7 @@ version = "0.2.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "core-foundation 0.10.0", | ||||
|  "libc", | ||||
| ] | ||||
|  | @ -521,9 +520,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" | |||
| 
 | ||||
| [[package]] | ||||
| name = "dpi" | ||||
| version = "0.1.1" | ||||
| version = "0.1.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" | ||||
| checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "drm" | ||||
|  | @ -531,7 +530,7 @@ version = "0.12.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "bytemuck", | ||||
|  "drm-ffi", | ||||
|  "drm-fourcc", | ||||
|  | @ -566,9 +565,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "dwrote" | ||||
| version = "0.11.2" | ||||
| version = "0.11.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "70182709525a3632b2ba96b6569225467b18ecb4a77f46d255f713a6bebf05fd" | ||||
| checksum = "bfe1f192fcce01590bd8d839aca53ce0d11d803bf291b2a6c4ad925a8f0024be" | ||||
| dependencies = [ | ||||
|  "lazy_static", | ||||
|  "libc", | ||||
|  | @ -588,14 +587,14 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "env_logger" | ||||
| version = "0.11.6" | ||||
| version = "0.11.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" | ||||
| checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" | ||||
| dependencies = [ | ||||
|  "anstream", | ||||
|  "anstyle", | ||||
|  "env_filter", | ||||
|  "humantime", | ||||
|  "jiff", | ||||
|  "log", | ||||
| ] | ||||
| 
 | ||||
|  | @ -607,9 +606,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" | |||
| 
 | ||||
| [[package]] | ||||
| name = "errno" | ||||
| version = "0.3.10" | ||||
| version = "0.3.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" | ||||
| checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "windows-sys 0.59.0", | ||||
|  | @ -623,9 +622,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" | |||
| 
 | ||||
| [[package]] | ||||
| name = "flate2" | ||||
| version = "1.0.35" | ||||
| version = "1.1.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" | ||||
| checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" | ||||
| dependencies = [ | ||||
|  "crc32fast", | ||||
|  "miniz_oxide", | ||||
|  | @ -643,7 +642,7 @@ version = "0.14.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b64b34f4efd515f905952d91bc185039863705592c0c53ae6d979805dd154520" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "byteorder", | ||||
|  "core-foundation 0.9.4", | ||||
|  "core-graphics 0.23.2", | ||||
|  | @ -718,20 +717,32 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "getrandom" | ||||
| version = "0.2.15" | ||||
| version = "0.2.16" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" | ||||
| checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "libc", | ||||
|  "wasi", | ||||
|  "wasi 0.11.0+wasi-snapshot-preview1", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "getrandom" | ||||
| version = "0.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "libc", | ||||
|  "r-efi", | ||||
|  "wasi 0.14.2+wasi-0.2.4", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "hashbrown" | ||||
| version = "0.15.2" | ||||
| version = "0.15.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" | ||||
| checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "heck" | ||||
|  | @ -745,17 +756,11 @@ version = "0.4.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "humantime" | ||||
| version = "2.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "indexmap" | ||||
| version = "2.7.1" | ||||
| version = "2.9.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" | ||||
| checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" | ||||
| dependencies = [ | ||||
|  "equivalent", | ||||
|  "hashbrown", | ||||
|  | @ -767,6 +772,30 @@ version = "1.70.1" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "jiff" | ||||
| version = "0.2.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "27e77966151130221b079bcec80f1f34a9e414fa489d99152a201c07fd2182bc" | ||||
| dependencies = [ | ||||
|  "jiff-static", | ||||
|  "log", | ||||
|  "portable-atomic", | ||||
|  "portable-atomic-util", | ||||
|  "serde", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "jiff-static" | ||||
| version = "0.2.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "97265751f8a9a4228476f2fc17874a9e7e70e96b893368e42619880fe143b48a" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "jni" | ||||
| version = "0.21.1" | ||||
|  | @ -791,10 +820,11 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" | |||
| 
 | ||||
| [[package]] | ||||
| name = "jobserver" | ||||
| version = "0.1.32" | ||||
| version = "0.1.33" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" | ||||
| checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" | ||||
| dependencies = [ | ||||
|  "getrandom 0.3.2", | ||||
|  "libc", | ||||
| ] | ||||
| 
 | ||||
|  | @ -816,9 +846,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" | |||
| 
 | ||||
| [[package]] | ||||
| name = "libc" | ||||
| version = "0.2.169" | ||||
| version = "0.2.172" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" | ||||
| checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "libloading" | ||||
|  | @ -836,9 +866,9 @@ version = "0.1.3" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "libc", | ||||
|  "redox_syscall 0.5.8", | ||||
|  "redox_syscall 0.5.11", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -855,9 +885,9 @@ checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" | |||
| 
 | ||||
| [[package]] | ||||
| name = "log" | ||||
| version = "0.4.25" | ||||
| version = "0.4.27" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" | ||||
| checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "memchr" | ||||
|  | @ -876,9 +906,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "miniz_oxide" | ||||
| version = "0.8.4" | ||||
| version = "0.8.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b" | ||||
| checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" | ||||
| dependencies = [ | ||||
|  "adler2", | ||||
| ] | ||||
|  | @ -889,7 +919,7 @@ version = "0.9.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "jni-sys", | ||||
|  "log", | ||||
|  "ndk-sys", | ||||
|  | @ -956,7 +986,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "libc", | ||||
|  "objc2", | ||||
|  | @ -972,7 +1002,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "objc2", | ||||
|  "objc2-core-location", | ||||
|  | @ -996,7 +1026,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "objc2", | ||||
|  "objc2-foundation", | ||||
|  | @ -1038,7 +1068,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "dispatch", | ||||
|  "libc", | ||||
|  | @ -1063,7 +1093,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "objc2", | ||||
|  "objc2-foundation", | ||||
|  | @ -1075,7 +1105,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "objc2", | ||||
|  "objc2-foundation", | ||||
|  | @ -1098,7 +1128,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "objc2", | ||||
|  "objc2-cloud-kit", | ||||
|  | @ -1130,7 +1160,7 @@ version = "0.2.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "objc2", | ||||
|  "objc2-core-location", | ||||
|  | @ -1139,9 +1169,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "once_cell" | ||||
| version = "1.20.3" | ||||
| version = "1.21.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" | ||||
| checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "option-ext" | ||||
|  | @ -1194,18 +1224,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" | |||
| 
 | ||||
| [[package]] | ||||
| name = "pin-project" | ||||
| version = "1.1.9" | ||||
| version = "1.1.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" | ||||
| checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" | ||||
| dependencies = [ | ||||
|  "pin-project-internal", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pin-project-internal" | ||||
| version = "1.1.9" | ||||
| version = "1.1.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" | ||||
| checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  | @ -1220,9 +1250,9 @@ checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" | |||
| 
 | ||||
| [[package]] | ||||
| name = "pkg-config" | ||||
| version = "0.3.31" | ||||
| version = "0.3.32" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" | ||||
| checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "polling" | ||||
|  | @ -1240,41 +1270,62 @@ dependencies = [ | |||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "proc-macro-crate" | ||||
| version = "3.2.0" | ||||
| name = "portable-atomic" | ||||
| version = "1.11.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" | ||||
| checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "portable-atomic-util" | ||||
| version = "0.2.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" | ||||
| dependencies = [ | ||||
|  "portable-atomic", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "proc-macro-crate" | ||||
| version = "3.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" | ||||
| dependencies = [ | ||||
|  "toml_edit", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "proc-macro2" | ||||
| version = "1.0.93" | ||||
| version = "1.0.95" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" | ||||
| checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" | ||||
| dependencies = [ | ||||
|  "unicode-ident", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "quick-xml" | ||||
| version = "0.37.2" | ||||
| version = "0.37.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003" | ||||
| checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" | ||||
| dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "quote" | ||||
| version = "1.0.38" | ||||
| version = "1.0.40" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" | ||||
| checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "r-efi" | ||||
| version = "5.2.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "radium" | ||||
| version = "0.7.0" | ||||
|  | @ -1298,11 +1349,11 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "redox_syscall" | ||||
| version = "0.5.8" | ||||
| version = "0.5.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" | ||||
| checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -1311,7 +1362,7 @@ version = "0.4.6" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" | ||||
| dependencies = [ | ||||
|  "getrandom", | ||||
|  "getrandom 0.2.16", | ||||
|  "libredox", | ||||
|  "thiserror 1.0.69", | ||||
| ] | ||||
|  | @ -1370,7 +1421,7 @@ version = "0.38.44" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "errno", | ||||
|  "libc", | ||||
|  "linux-raw-sys 0.4.15", | ||||
|  | @ -1379,9 +1430,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "rustversion" | ||||
| version = "1.0.19" | ||||
| version = "1.0.20" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" | ||||
| checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "same-file" | ||||
|  | @ -1413,24 +1464,24 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "semver" | ||||
| version = "1.0.25" | ||||
| version = "1.0.26" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" | ||||
| checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "serde" | ||||
| version = "1.0.217" | ||||
| version = "1.0.219" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" | ||||
| checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" | ||||
| dependencies = [ | ||||
|  "serde_derive", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "serde_derive" | ||||
| version = "1.0.217" | ||||
| version = "1.0.219" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" | ||||
| checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  | @ -1439,9 +1490,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "servicepoint" | ||||
| version = "0.13.2" | ||||
| version = "0.14.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "33abd53582a995aaf5d387be4a1f7eb294a084185f88f8cf61652b6272041660" | ||||
| checksum = "0ce70bae3641ccafdeb9832ac367efd51243e0708ef35151ad8c2c4ee578aa4a" | ||||
| dependencies = [ | ||||
|  "bitvec", | ||||
|  "bzip2", | ||||
|  | @ -1449,13 +1500,13 @@ dependencies = [ | |||
|  "log", | ||||
|  "once_cell", | ||||
|  "rust-lzma", | ||||
|  "thiserror 2.0.11", | ||||
|  "thiserror 2.0.12", | ||||
|  "zstd", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "servicepoint-simulator" | ||||
| version = "0.2.0" | ||||
| version = "0.2.1" | ||||
| dependencies = [ | ||||
|  "clap", | ||||
|  "env_logger", | ||||
|  | @ -1464,7 +1515,7 @@ dependencies = [ | |||
|  "pathfinder_geometry", | ||||
|  "servicepoint", | ||||
|  "softbuffer", | ||||
|  "thiserror 2.0.11", | ||||
|  "thiserror 2.0.12", | ||||
|  "winit", | ||||
| ] | ||||
| 
 | ||||
|  | @ -1485,9 +1536,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "smallvec" | ||||
| version = "1.14.0" | ||||
| version = "1.15.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" | ||||
| checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "smithay-client-toolkit" | ||||
|  | @ -1495,7 +1546,7 @@ version = "0.19.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "calloop", | ||||
|  "calloop-wayland-source", | ||||
|  "cursor-icon", | ||||
|  | @ -1543,7 +1594,7 @@ dependencies = [ | |||
|  "objc2-foundation", | ||||
|  "objc2-quartz-core", | ||||
|  "raw-window-handle", | ||||
|  "redox_syscall 0.5.8", | ||||
|  "redox_syscall 0.5.11", | ||||
|  "rustix", | ||||
|  "tiny-xlib", | ||||
|  "wasm-bindgen", | ||||
|  | @ -1569,9 +1620,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" | |||
| 
 | ||||
| [[package]] | ||||
| name = "syn" | ||||
| version = "2.0.98" | ||||
| version = "2.0.101" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" | ||||
| checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  | @ -1595,11 +1646,11 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "thiserror" | ||||
| version = "2.0.11" | ||||
| version = "2.0.12" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" | ||||
| checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" | ||||
| dependencies = [ | ||||
|  "thiserror-impl 2.0.11", | ||||
|  "thiserror-impl 2.0.12", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
|  | @ -1615,9 +1666,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "thiserror-impl" | ||||
| version = "2.0.11" | ||||
| version = "2.0.12" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" | ||||
| checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  | @ -1664,15 +1715,15 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "toml_datetime" | ||||
| version = "0.6.8" | ||||
| version = "0.6.9" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" | ||||
| checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "toml_edit" | ||||
| version = "0.22.24" | ||||
| version = "0.22.26" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" | ||||
| checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" | ||||
| dependencies = [ | ||||
|  "indexmap", | ||||
|  "toml_datetime", | ||||
|  | @ -1703,9 +1754,9 @@ checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" | |||
| 
 | ||||
| [[package]] | ||||
| name = "unicode-ident" | ||||
| version = "1.0.16" | ||||
| version = "1.0.18" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" | ||||
| checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "unicode-segmentation" | ||||
|  | @ -1747,6 +1798,15 @@ version = "0.11.0+wasi-snapshot-preview1" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wasi" | ||||
| version = "0.14.2+wasi-0.2.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" | ||||
| dependencies = [ | ||||
|  "wit-bindgen-rt", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wasm-bindgen" | ||||
| version = "0.2.100" | ||||
|  | @ -1820,9 +1880,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "wayland-backend" | ||||
| version = "0.3.8" | ||||
| version = "0.3.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf" | ||||
| checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" | ||||
| dependencies = [ | ||||
|  "cc", | ||||
|  "downcast-rs", | ||||
|  | @ -1834,11 +1894,11 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "wayland-client" | ||||
| version = "0.31.8" | ||||
| version = "0.31.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f" | ||||
| checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "rustix", | ||||
|  "wayland-backend", | ||||
|  "wayland-scanner", | ||||
|  | @ -1850,16 +1910,16 @@ version = "0.3.0" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "cursor-icon", | ||||
|  "wayland-backend", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wayland-cursor" | ||||
| version = "0.31.8" | ||||
| version = "0.31.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a93029cbb6650748881a00e4922b076092a6a08c11e7fbdb923f064b23968c5d" | ||||
| checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182" | ||||
| dependencies = [ | ||||
|  "rustix", | ||||
|  "wayland-client", | ||||
|  | @ -1868,11 +1928,11 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "wayland-protocols" | ||||
| version = "0.32.6" | ||||
| version = "0.32.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0781cf46869b37e36928f7b432273c0995aa8aed9552c556fb18754420541efc" | ||||
| checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "wayland-backend", | ||||
|  "wayland-client", | ||||
|  "wayland-scanner", | ||||
|  | @ -1880,11 +1940,11 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "wayland-protocols-plasma" | ||||
| version = "0.3.6" | ||||
| version = "0.3.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7ccaacc76703fefd6763022ac565b590fcade92202492381c95b2edfdf7d46b3" | ||||
| checksum = "4fd38cdad69b56ace413c6bcc1fbf5acc5e2ef4af9d5f8f1f9570c0c83eae175" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "wayland-backend", | ||||
|  "wayland-client", | ||||
|  "wayland-protocols", | ||||
|  | @ -1893,11 +1953,11 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "wayland-protocols-wlr" | ||||
| version = "0.3.6" | ||||
| version = "0.3.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "248a02e6f595aad796561fa82d25601bd2c8c3b145b1c7453fc8f94c1a58f8b2" | ||||
| checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "wayland-backend", | ||||
|  "wayland-client", | ||||
|  "wayland-protocols", | ||||
|  | @ -2194,14 +2254,14 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" | |||
| 
 | ||||
| [[package]] | ||||
| name = "winit" | ||||
| version = "0.30.9" | ||||
| version = "0.30.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0" | ||||
| checksum = "b0d05bd8908e14618c9609471db04007e644fd9cce6529756046cfc577f9155e" | ||||
| dependencies = [ | ||||
|  "ahash", | ||||
|  "android-activity", | ||||
|  "atomic-waker", | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "block2", | ||||
|  "bytemuck", | ||||
|  "calloop", | ||||
|  | @ -2246,9 +2306,9 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "winnow" | ||||
| version = "0.7.2" | ||||
| version = "0.7.9" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603" | ||||
| checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3" | ||||
| dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
|  | @ -2262,6 +2322,15 @@ dependencies = [ | |||
|  "winapi", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wit-bindgen-rt" | ||||
| version = "0.39.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" | ||||
| dependencies = [ | ||||
|  "bitflags 2.9.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wyz" | ||||
| version = "0.5.1" | ||||
|  | @ -2315,7 +2384,7 @@ version = "0.4.2" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" | ||||
| dependencies = [ | ||||
|  "bitflags 2.8.0", | ||||
|  "bitflags 2.9.0", | ||||
|  "dlib", | ||||
|  "log", | ||||
|  "once_cell", | ||||
|  | @ -2361,27 +2430,27 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "zstd" | ||||
| version = "0.13.2" | ||||
| version = "0.13.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" | ||||
| checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" | ||||
| dependencies = [ | ||||
|  "zstd-safe", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "zstd-safe" | ||||
| version = "7.2.1" | ||||
| version = "7.2.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" | ||||
| checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" | ||||
| dependencies = [ | ||||
|  "zstd-sys", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "zstd-sys" | ||||
| version = "2.0.13+zstd.1.5.6" | ||||
| version = "2.0.15+zstd.1.5.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" | ||||
| checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" | ||||
| dependencies = [ | ||||
|  "cc", | ||||
|  "pkg-config", | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| [package] | ||||
| name = "servicepoint-simulator" | ||||
| version = "0.2.0" | ||||
| version = "0.2.1" | ||||
| edition = "2021" | ||||
| publish = true | ||||
| license = "GPL-3.0-or-later" | ||||
|  | @ -20,7 +20,7 @@ clap = { version = "4.5", features = ["derive"] } | |||
| thiserror = "2.0" | ||||
| 
 | ||||
| # package parsing | ||||
| servicepoint = { version = "0.13.2", features = ["all_compressions"] } | ||||
| servicepoint = { features = ["all_compressions"], version = "0.14.0" } | ||||
| 
 | ||||
| # font rendering | ||||
| font-kit = "0.14.2" | ||||
|  | @ -31,3 +31,8 @@ pathfinder_geometry = "0.5.1" | |||
| winit = "0.30" | ||||
| # for drawing pixels onto the surface of the window | ||||
| softbuffer = "0.4.6" | ||||
| 
 | ||||
| [profile.release] | ||||
| lto = true          # Enable link-time optimization | ||||
| codegen-units = 1   # Reduce number of codegen units to increase optimizations | ||||
| strip = true        # Strip symbols from binary | ||||
|  |  | |||
							
								
								
									
										18
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
										
									
									
									
								
							|  | @ -1,6 +1,12 @@ | |||
| # servicepoint-simulator | ||||
| 
 | ||||
| A simulator for the CCCB airport display. | ||||
| [](https://git.berlin.ccc.de/servicepoint/servicepoint-simulator/releases) | ||||
| [](https://crates.io/crates/servicepoint-simulator) | ||||
| [](https://crates.io/crates/servicepoint-simulator) | ||||
| [](./LICENSE) | ||||
| [](https://git.berlin.ccc.de/servicepoint/servicepoint-simulator) | ||||
| 
 | ||||
| A simulator for the CCCB service point display. | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
|  | @ -17,6 +23,10 @@ Use cases: | |||
| Uses the [servicepoint](https://github.com/cccb/servicepoint) library for reading the packets. | ||||
| The screenshot above shows the output of two example projects running in parallel (game_of_life and random_brightness). | ||||
| 
 | ||||
| This repository moved | ||||
| to [git.berlin.ccc.de/servicepoint/servicepoint-simulator](https://git.berlin.ccc.de/servicepoint/servicepoint-simulator/). | ||||
| The [GitHub repository](https://github.com/kaesaecracker/servicepoint-simulator) will remain as a mirror. | ||||
| 
 | ||||
| ## Running | ||||
| 
 | ||||
| With cargo installed: `cargo install servicepoint-simulator` | ||||
|  | @ -44,7 +54,8 @@ Options: | |||
| 
 | ||||
| See [env_logger](https://docs.rs/env_logger/latest/env_logger/) to configure logging. | ||||
| 
 | ||||
| Because this program renders to an RGB pixel buffer, you can enjoy the following additional features not available on the real display: | ||||
| Because this program renders to an RGB pixel buffer, you can enjoy the following additional features not available on | ||||
| the real display: | ||||
| 
 | ||||
| - enable or disable the empty space between tile rows (`./servicepoint-simulator --spacers` to enable) | ||||
| - render pixels in red, green, blue or a combination of the three (`./servicepoint-simulator -rgb` for white pixels) | ||||
|  | @ -64,6 +75,7 @@ All creatures welcome. | |||
| 
 | ||||
| ## Legal stuff | ||||
| 
 | ||||
| The included font is https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios (included in the download from https://int10h.org/oldschool-pc-fonts/download/). The font is CC BY-SA 4.0. | ||||
| The included font is https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios (included in the download | ||||
| from https://int10h.org/oldschool-pc-fonts/download/). The font is CC BY-SA 4.0. | ||||
| 
 | ||||
| For everything else see the LICENSE file. | ||||
|  |  | |||
							
								
								
									
										12
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										12
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							|  | @ -7,11 +7,11 @@ | |||
|         ] | ||||
|       }, | ||||
|       "locked": { | ||||
|         "lastModified": 1739824009, | ||||
|         "narHash": "sha256-fcNrCMUWVLMG3gKC5M9CBqVOAnJtyRvGPxptQFl5mVg=", | ||||
|         "lastModified": 1745925850, | ||||
|         "narHash": "sha256-cyAAMal0aPrlb1NgzMxZqeN1mAJ2pJseDhm2m6Um8T0=", | ||||
|         "owner": "nix-community", | ||||
|         "repo": "naersk", | ||||
|         "rev": "e5130d37369bfa600144c2424270c96f0ef0e11d", | ||||
|         "rev": "38bc60bbc157ae266d4a0c96671c6c742ee17a5f", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  | @ -37,11 +37,11 @@ | |||
|     }, | ||||
|     "nixpkgs": { | ||||
|       "locked": { | ||||
|         "lastModified": 1739758141, | ||||
|         "narHash": "sha256-uq6A2L7o1/tR6VfmYhZWoVAwb3gTy7j4Jx30MIrH0rE=", | ||||
|         "lastModified": 1746183838, | ||||
|         "narHash": "sha256-kwaaguGkAqTZ1oK0yXeQ3ayYjs8u/W7eEfrFpFfIDFA=", | ||||
|         "owner": "nixos", | ||||
|         "repo": "nixpkgs", | ||||
|         "rev": "c618e28f70257593de75a7044438efc1c1fc0791", | ||||
|         "rev": "bf3287dac860542719fe7554e21e686108716879", | ||||
|         "type": "github" | ||||
|       }, | ||||
|       "original": { | ||||
|  |  | |||
|  | @ -1,16 +1,22 @@ | |||
| use crate::command_executor::ExecutionResult::{Failure, Shutdown, Success}; | ||||
| use crate::cp437_font::Cp437Font; | ||||
| use crate::font_renderer::FontRenderer8x8; | ||||
| use crate::{ | ||||
|     command_executor::ExecutionResult::{Failure, Shutdown, Success}, | ||||
|     cp437_font::Cp437Font, | ||||
|     font_renderer::FontRenderer8x8, | ||||
| }; | ||||
| use log::{debug, error, info, trace, warn}; | ||||
| use servicepoint::{ | ||||
|     BitVec, Bitmap, BrightnessGrid, CharGrid, Command, Cp437Grid, Grid, Offset, | ||||
|     Origin, Tiles, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, | ||||
|     BinaryOperation, BitVecCommand, Bitmap, BitmapCommand, GlobalBrightnessCommand, | ||||
|     BrightnessGrid, BrightnessGridCommand, CharGridCommand, ClearCommand, | ||||
|     CompressionCode, Cp437GridCommand, FadeOutCommand, Grid, HardResetCommand, | ||||
|     Origin, TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, | ||||
| }; | ||||
| use std::{ | ||||
|     ops::{BitAnd, BitOr, BitXor}, | ||||
|     sync::RwLock, | ||||
| }; | ||||
| use std::ops::{BitAnd, BitOr, BitXor}; | ||||
| use std::sync::RwLock; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct CommandExecutor<'t> { | ||||
| pub struct CommandExecutionContext<'t> { | ||||
|     display: &'t RwLock<Bitmap>, | ||||
|     luma: &'t RwLock<BrightnessGrid>, | ||||
|     cp437_font: Cp437Font, | ||||
|  | @ -24,201 +30,36 @@ pub enum ExecutionResult { | |||
|     Shutdown, | ||||
| } | ||||
| 
 | ||||
| impl<'t> CommandExecutor<'t> { | ||||
|     pub fn new( | ||||
|         display: &'t RwLock<Bitmap>, | ||||
|         luma: &'t RwLock<BrightnessGrid>, | ||||
|         font_renderer: FontRenderer8x8, | ||||
|     ) -> Self { | ||||
|         CommandExecutor { | ||||
|             display, | ||||
|             luma, | ||||
|             font_renderer, | ||||
|             cp437_font: Cp437Font::default(), | ||||
|         } | ||||
|     } | ||||
| pub trait CommandExecute { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult; | ||||
| } | ||||
| 
 | ||||
|     pub(crate) fn execute(&self, command: Command) -> ExecutionResult { | ||||
|         debug!("received {command:?}"); | ||||
|         match command { | ||||
|             Command::Clear => { | ||||
|                 info!("clearing display"); | ||||
|                 self.display.write().unwrap().fill(false); | ||||
|                 Success | ||||
|             } | ||||
|             Command::HardReset => { | ||||
|                 warn!("display shutting down"); | ||||
|                 Shutdown | ||||
|             } | ||||
|             Command::BitmapLinearWin(Origin { x, y, .. }, pixels, _) => { | ||||
|                 self.print_pixel_grid(x, y, &pixels) | ||||
|             } | ||||
|             Command::Cp437Data(origin, grid) => { | ||||
|                 self.print_cp437_data(origin, &grid) | ||||
|             } | ||||
|             #[allow(deprecated)] | ||||
|             Command::BitmapLegacy => { | ||||
|                 warn!("ignoring deprecated command {:?}", command); | ||||
|                 Failure | ||||
|             } | ||||
|             Command::BitmapLinearAnd(offset, vec, _) => { | ||||
|                 self.execute_bitmap_linear(offset, vec, BitAnd::bitand) | ||||
|             } | ||||
|             Command::BitmapLinearOr(offset, vec, _) => { | ||||
|                 self.execute_bitmap_linear(offset, vec, BitOr::bitor) | ||||
|             } | ||||
|             Command::BitmapLinearXor(offset, vec, _) => { | ||||
|                 self.execute_bitmap_linear(offset, vec, BitXor::bitxor) | ||||
|             } | ||||
|             Command::BitmapLinear(offset, vec, _) => { | ||||
|                 self.execute_bitmap_linear(offset, vec, move |_, new| new) | ||||
|             } | ||||
|             Command::CharBrightness(origin, grid) => { | ||||
|                 self.execute_char_brightness(origin, grid) | ||||
|             } | ||||
|             Command::Brightness(brightness) => { | ||||
|                 self.luma.write().unwrap().fill(brightness); | ||||
|                 Success | ||||
|             } | ||||
|             Command::FadeOut => { | ||||
|                 error!("command not implemented: {command:?}"); | ||||
|                 Success | ||||
|             } | ||||
|             Command::Utf8Data(origin, grid) => { | ||||
|                 self.print_utf8_data(origin, &grid) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn execute_char_brightness( | ||||
|         &self, | ||||
|         origin: Origin<Tiles>, | ||||
|         grid: BrightnessGrid, | ||||
|     ) -> ExecutionResult { | ||||
|         let mut luma = self.luma.write().unwrap(); | ||||
|         for inner_y in 0..grid.height() { | ||||
|             for inner_x in 0..grid.width() { | ||||
|                 let brightness = grid.get(inner_x, inner_y); | ||||
|                 luma.set(origin.x + inner_x, origin.y + inner_y, brightness); | ||||
|             } | ||||
|         } | ||||
| impl CommandExecute for ClearCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         info!("clearing display"); | ||||
|         context.display.write().unwrap().fill(false); | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     fn execute_bitmap_linear<Op>( | ||||
|         &self, | ||||
|         offset: Offset, | ||||
|         vec: BitVec, | ||||
|         op: Op, | ||||
|     ) -> ExecutionResult | ||||
|     where | ||||
|         Op: Fn(bool, bool) -> bool, | ||||
|     { | ||||
|         if !Self::check_bitmap_valid(offset as u16, vec.len()) { | ||||
|             return Failure; | ||||
|         } | ||||
|         let mut display = self.display.write().unwrap(); | ||||
|         for bitmap_index in 0..vec.len() { | ||||
|             let (x, y) = Self::get_coordinates_for_index(offset, bitmap_index); | ||||
|             let old_value = display.get(x, y); | ||||
|             display.set(x, y, op(old_value, vec[bitmap_index])); | ||||
|         } | ||||
|         Success | ||||
|     } | ||||
| 
 | ||||
|     fn check_bitmap_valid(offset: u16, payload_len: usize) -> bool { | ||||
|         if offset as usize + payload_len > PIXEL_COUNT { | ||||
|             error!( | ||||
|                 "bitmap with offset {offset} is too big ({payload_len} bytes)" | ||||
|             ); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         true | ||||
|     } | ||||
| 
 | ||||
|     fn print_cp437_data( | ||||
|         &self, | ||||
|         origin: Origin<Tiles>, | ||||
|         grid: &Cp437Grid, | ||||
|     ) -> ExecutionResult { | ||||
|         let font = &self.cp437_font; | ||||
|         let Origin { x, y, .. } = origin; | ||||
|         for char_y in 0usize..grid.height() { | ||||
|             for char_x in 0usize..grid.width() { | ||||
|                 let char_code = grid.get(char_x, char_y); | ||||
|                 trace!( | ||||
|                 "drawing char_code {char_code:#04x} (if this was UTF-8, it would be {})", | ||||
|                 char::from(char_code) | ||||
|             ); | ||||
| 
 | ||||
|                 let tile_x = char_x + x; | ||||
|                 let tile_y = char_y + y; | ||||
| 
 | ||||
|                 match self.print_pixel_grid( | ||||
|                     tile_x * TILE_SIZE, | ||||
|                     tile_y * TILE_SIZE, | ||||
|                     &font[char_code], | ||||
|                 ) { | ||||
|                     Success => {} | ||||
|                     Failure => { | ||||
|                         error!( | ||||
|                             "stopping drawing text because char draw failed" | ||||
|                         ); | ||||
|                         return Failure; | ||||
|                     } | ||||
|                     Shutdown => return Shutdown, | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Success | ||||
|     } | ||||
| 
 | ||||
|     fn print_utf8_data( | ||||
|         &self, | ||||
|         origin: Origin<Tiles>, | ||||
|         grid: &CharGrid, | ||||
|     ) -> ExecutionResult { | ||||
|         let mut display = self.display.write().unwrap(); | ||||
| 
 | ||||
|         let Origin { x, y, .. } = origin; | ||||
|         for char_y in 0usize..grid.height() { | ||||
|             for char_x in 0usize..grid.width() { | ||||
|                 let char = grid.get(char_x, char_y); | ||||
|                 trace!("drawing {char}"); | ||||
| 
 | ||||
|                 let tile_x = char_x + x; | ||||
|                 let tile_y = char_y + y; | ||||
| 
 | ||||
|                 if let Err(e) = self.font_renderer.render( | ||||
|                     char, | ||||
|                     &mut display, | ||||
|                     Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), | ||||
|                 ) { | ||||
|                     error!( | ||||
|                         "stopping drawing text because char draw failed: {e}" | ||||
|                     ); | ||||
|                     return Failure; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Success | ||||
|     } | ||||
| 
 | ||||
|     fn print_pixel_grid( | ||||
|         &self, | ||||
|         offset_x: usize, | ||||
|         offset_y: usize, | ||||
|         pixels: &Bitmap, | ||||
|     ) -> ExecutionResult { | ||||
| impl CommandExecute for BitmapCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         let Self { | ||||
|             origin: | ||||
|             Origin { | ||||
|                 x: offset_x, | ||||
|                 y: offset_y, | ||||
|                 .. | ||||
|             }, | ||||
|             bitmap: pixels, | ||||
|             .. | ||||
|         } = self; | ||||
|         debug!( | ||||
|             "printing {}x{} grid at {offset_x} {offset_y}", | ||||
|             pixels.width(), | ||||
|             pixels.height() | ||||
|         ); | ||||
|         let mut display = self.display.write().unwrap(); | ||||
|         let mut display = context.display.write().unwrap(); | ||||
|         for inner_y in 0..pixels.height() { | ||||
|             for inner_x in 0..pixels.width() { | ||||
|                 let is_set = pixels.get(inner_x, inner_y); | ||||
|  | @ -236,12 +77,186 @@ impl<'t> CommandExecutor<'t> { | |||
| 
 | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     fn get_coordinates_for_index( | ||||
|         offset: usize, | ||||
|         index: usize, | ||||
|     ) -> (usize, usize) { | ||||
|         let pixel_index = offset + index; | ||||
|         (pixel_index % PIXEL_WIDTH, pixel_index / PIXEL_WIDTH) | ||||
| impl CommandExecute for HardResetCommand { | ||||
|     fn execute(&self, _: &CommandExecutionContext) -> ExecutionResult { | ||||
|         warn!("display shutting down"); | ||||
|         Shutdown | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CommandExecute for BitVecCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         let BitVecCommand { | ||||
|             offset, | ||||
|             bitvec, | ||||
|             operation, | ||||
|             .. | ||||
|         } = self; | ||||
|         fn overwrite(_: bool, new: bool) -> bool { | ||||
|             new | ||||
|         } | ||||
|         let operation = match operation { | ||||
|             BinaryOperation::Overwrite => overwrite, | ||||
|             BinaryOperation::And => BitAnd::bitand, | ||||
|             BinaryOperation::Or => BitOr::bitor, | ||||
|             BinaryOperation::Xor => BitXor::bitxor, | ||||
|         }; | ||||
| 
 | ||||
|         if self.offset + bitvec.len() > PIXEL_COUNT { | ||||
|             error!( | ||||
|                 "bitmap with offset {offset} is too big ({} bytes)", | ||||
|                 bitvec.len() | ||||
|             ); | ||||
|             return Failure; | ||||
|         } | ||||
| 
 | ||||
|         let mut display = context.display.write().unwrap(); | ||||
|         for bitmap_index in 0..bitvec.len() { | ||||
|             let pixel_index = offset + bitmap_index; | ||||
|             let (x, y) = (pixel_index % PIXEL_WIDTH, pixel_index / PIXEL_WIDTH); | ||||
|             let old_value = display.get(x, y); | ||||
|             display.set(x, y, operation(old_value, bitvec[bitmap_index])); | ||||
|         } | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CommandExecute for Cp437GridCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         let Cp437GridCommand { origin, grid } = self; | ||||
|         let Origin { x, y, .. } = origin; | ||||
|         for char_y in 0usize..grid.height() { | ||||
|             for char_x in 0usize..grid.width() { | ||||
|                 let char_code = grid.get(char_x, char_y); | ||||
|                 trace!( | ||||
|                 "drawing char_code {char_code:#04x} (if this was UTF-8, it would be {})", | ||||
|                 char::from(char_code) | ||||
|             ); | ||||
| 
 | ||||
|                 let tile_x = char_x + x; | ||||
|                 let tile_y = char_y + y; | ||||
| 
 | ||||
|                 let execute_result = BitmapCommand { | ||||
|                     origin: Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), | ||||
|                     bitmap: context.cp437_font[char_code].clone(), | ||||
|                     compression: CompressionCode::default(), | ||||
|                 } | ||||
|                     .execute(context); | ||||
|                 match execute_result { | ||||
|                     Success => {} | ||||
|                     Failure => { | ||||
|                         error!( | ||||
|                             "stopping drawing text because char draw failed" | ||||
|                         ); | ||||
|                         return Failure; | ||||
|                     } | ||||
|                     Shutdown => return Shutdown, | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[allow(deprecated)] | ||||
| impl CommandExecute for servicepoint::BitmapLegacyCommand { | ||||
|     fn execute(&self, _: &CommandExecutionContext) -> ExecutionResult { | ||||
|         warn!("ignoring deprecated command {:?}", self); | ||||
|         Failure | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CommandExecute for BrightnessGridCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         let BrightnessGridCommand { origin, grid } = self; | ||||
|         let mut luma = context.luma.write().unwrap(); | ||||
|         for inner_y in 0..grid.height() { | ||||
|             for inner_x in 0..grid.width() { | ||||
|                 let brightness = grid.get(inner_x, inner_y); | ||||
|                 luma.set(origin.x + inner_x, origin.y + inner_y, brightness); | ||||
|             } | ||||
|         } | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CommandExecute for CharGridCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         let CharGridCommand { origin, grid } = self; | ||||
|         let mut display = context.display.write().unwrap(); | ||||
| 
 | ||||
|         let Origin { x, y, .. } = origin; | ||||
|         for char_y in 0usize..grid.height() { | ||||
|             for char_x in 0usize..grid.width() { | ||||
|                 let char = grid.get(char_x, char_y); | ||||
|                 trace!("drawing {char}"); | ||||
| 
 | ||||
|                 let tile_x = char_x + x; | ||||
|                 let tile_y = char_y + y; | ||||
| 
 | ||||
|                 if let Err(e) = context.font_renderer.render( | ||||
|                     char, | ||||
|                     &mut display, | ||||
|                     Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), | ||||
|                 ) { | ||||
|                     error!( | ||||
|                         "stopping drawing text because char draw failed: {e}" | ||||
|                     ); | ||||
|                     return Failure; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CommandExecute for GlobalBrightnessCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         context.luma.write().unwrap().fill(self.brightness); | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CommandExecute for FadeOutCommand { | ||||
|     fn execute(&self, _: &CommandExecutionContext) -> ExecutionResult { | ||||
|         error!("command not implemented: {self:?}"); | ||||
|         Success | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CommandExecute for TypedCommand { | ||||
|     fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { | ||||
|         match self { | ||||
|             TypedCommand::Clear(command) => command.execute(context), | ||||
|             TypedCommand::HardReset(command) => command.execute(context), | ||||
|             TypedCommand::Bitmap(command) => command.execute(context), | ||||
|             TypedCommand::Cp437Grid(command) => command.execute(context), | ||||
|             #[allow(deprecated)] | ||||
|             TypedCommand::BitmapLegacy(command) => command.execute(context), | ||||
|             TypedCommand::BitVec(command) => command.execute(context), | ||||
|             TypedCommand::BrightnessGrid(command) => command.execute(context), | ||||
|             TypedCommand::Brightness(command) => command.execute(context), | ||||
|             TypedCommand::FadeOut(command) => command.execute(context), | ||||
|             TypedCommand::CharGrid(command) => command.execute(context), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'t> CommandExecutionContext<'t> { | ||||
|     pub fn new( | ||||
|         display: &'t RwLock<Bitmap>, | ||||
|         luma: &'t RwLock<BrightnessGrid>, | ||||
|         font_renderer: FontRenderer8x8, | ||||
|     ) -> Self { | ||||
|         CommandExecutionContext { | ||||
|             display, | ||||
|             luma, | ||||
|             font_renderer, | ||||
|             cp437_font: Cp437Font::default(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -16,8 +16,9 @@ impl Cp437Font { | |||
| 
 | ||||
| impl Default for Cp437Font { | ||||
|     fn default() -> Self { | ||||
|         let mut bitmaps = | ||||
|             core::array::from_fn(|_| Bitmap::new(TILE_SIZE, TILE_SIZE)); | ||||
|         let mut bitmaps = core::array::from_fn(|_| { | ||||
|             Bitmap::new(TILE_SIZE, TILE_SIZE).unwrap() | ||||
|         }); | ||||
| 
 | ||||
|         for (char_code, bitmap) in bitmaps.iter_mut().enumerate() { | ||||
|             let bits = CP437_FONT_LINEAR[char_code]; | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| use std::{sync::mpsc::Sender, sync::RwLock}; | ||||
| 
 | ||||
| use log::{info, warn}; | ||||
| use servicepoint::*; | ||||
| use std::{sync::mpsc::Sender, sync::RwLock}; | ||||
| use winit::{ | ||||
|     application::ApplicationHandler, dpi::LogicalSize, event::WindowEvent, | ||||
|     event_loop::ActiveEventLoop, keyboard::KeyCode::KeyC, window::WindowId, | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| use crate::font_renderer::FontRenderer8x8; | ||||
| use crate::udp_server::UdpServer; | ||||
| use crate::{command_executor::CommandExecutor, gui::Gui}; | ||||
| use crate::{command_executor::CommandExecutionContext, gui::Gui}; | ||||
| use clap::Parser; | ||||
| use cli::Cli; | ||||
| use log::{info, LevelFilter}; | ||||
|  | @ -32,18 +32,18 @@ fn main() { | |||
|         .expect("could not create event loop"); | ||||
|     event_loop.set_control_flow(ControlFlow::Wait); | ||||
| 
 | ||||
|     let display = RwLock::new(Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT)); | ||||
|     let display = RwLock::new(Bitmap::max_sized()); | ||||
|     let luma = RwLock::new(BrightnessGrid::new(TILE_WIDTH, TILE_HEIGHT)); | ||||
|     let (stop_udp_tx, stop_udp_rx) = mpsc::channel(); | ||||
|     let font_renderer = cli | ||||
|         .font | ||||
|         .map(FontRenderer8x8::from_name) | ||||
|         .unwrap_or_else(FontRenderer8x8::default); | ||||
|     let command_executor = CommandExecutor::new(&display, &luma, font_renderer); | ||||
|     let context = CommandExecutionContext::new(&display, &luma, font_renderer); | ||||
|     let mut udp_server = UdpServer::new( | ||||
|         cli.bind, | ||||
|         stop_udp_rx, | ||||
|         command_executor, | ||||
|         context, | ||||
|         event_loop.create_proxy(), | ||||
|     ); | ||||
|     let mut gui = Gui::new(&display, &luma, stop_udp_tx, cli.gui); | ||||
|  |  | |||
|  | @ -1,20 +1,22 @@ | |||
| use crate::command_executor::{CommandExecutor, ExecutionResult}; | ||||
| use crate::gui::AppEvents; | ||||
| use log::{error, warn}; | ||||
| use servicepoint::Command; | ||||
| use std::io::ErrorKind; | ||||
| use std::net::UdpSocket; | ||||
| use std::sync::mpsc::Receiver; | ||||
| use std::time::Duration; | ||||
| use crate::command_executor::CommandExecute; | ||||
| use crate::{ | ||||
|     command_executor::{CommandExecutionContext, ExecutionResult}, | ||||
|     gui::AppEvents, | ||||
| }; | ||||
| use log::{debug, error, warn}; | ||||
| use servicepoint::TypedCommand; | ||||
| use std::{ | ||||
|     io::ErrorKind, net::UdpSocket, sync::mpsc::Receiver, time::Duration, | ||||
| }; | ||||
| use winit::event_loop::EventLoopProxy; | ||||
| 
 | ||||
| const BUF_SIZE: usize = 8985; | ||||
| const BUF_SIZE: usize = 8985 * 2; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct UdpServer<'t> { | ||||
|     socket: UdpSocket, | ||||
|     stop_rx: Receiver<()>, | ||||
|     command_executor: CommandExecutor<'t>, | ||||
|     command_executor: CommandExecutionContext<'t>, | ||||
|     app_events: EventLoopProxy<AppEvents>, | ||||
|     buf: [u8; BUF_SIZE], | ||||
| } | ||||
|  | @ -23,7 +25,7 @@ impl<'t> UdpServer<'t> { | |||
|     pub fn new( | ||||
|         bind: String, | ||||
|         stop_rx: Receiver<()>, | ||||
|         command_executor: CommandExecutor<'t>, | ||||
|         command_executor: CommandExecutionContext<'t>, | ||||
|         app_events: EventLoopProxy<AppEvents>, | ||||
|     ) -> Self { | ||||
|         let socket = UdpSocket::bind(bind).expect("could not bind socket"); | ||||
|  | @ -45,7 +47,8 @@ impl<'t> UdpServer<'t> { | |||
|             if let Some(cmd) = self.receive_into_buf().and_then(|amount| { | ||||
|                 Self::command_from_slice(&self.buf[..amount]) | ||||
|             }) { | ||||
|                 match self.command_executor.execute(cmd) { | ||||
|                 debug!("received {cmd:?}"); | ||||
|                 match cmd.execute(&self.command_executor) { | ||||
|                     ExecutionResult::Success => { | ||||
|                         self.app_events | ||||
|                             .send_event(AppEvents::UdpPacketHandled) | ||||
|  | @ -65,13 +68,13 @@ impl<'t> UdpServer<'t> { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn command_from_slice(slice: &[u8]) -> Option<Command> { | ||||
|     fn command_from_slice(slice: &[u8]) -> Option<TypedCommand> { | ||||
|         let packet = servicepoint::Packet::try_from(slice) | ||||
|             .inspect_err(|_| { | ||||
|                 warn!("could not load packet with length {}", slice.len()) | ||||
|             }) | ||||
|             .ok()?; | ||||
|         Command::try_from(packet) | ||||
|         TypedCommand::try_from(packet) | ||||
|             .inspect_err(move |err| { | ||||
|                 warn!("could not read command for packet: {:?}", err) | ||||
|             }) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue