diff --git a/.gitignore b/.gitignore index ea8c4bf7..d787b706 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/result diff --git a/Cargo.lock b/Cargo.lock index 44393d85..e8371529 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,9 +78,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cairo-rs" -version = "0.18.0" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d859b656775a6b1dd078d3e5924884e6ea88aa649a7fdde03d5b2ec56ffcc10b" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ "bitflags 2.4.0", "cairo-sys-rs", @@ -133,12 +133,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -184,19 +178,15 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.29.6" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" +checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be" dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "matches", - "phf 0.10.1", - "proc-macro2", - "quote", + "phf", "smallvec", - "syn 1.0.109", ] [[package]] @@ -221,34 +211,32 @@ version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ - "convert_case", "proc-macro2", "quote", - "rustc_version", "syn 1.0.109", ] [[package]] name = "drm" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb1b703ffbc7ebd216eba7900008049a56ace55580ecb2ee7fa801e8d8be87" +checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" dependencies = [ "bitflags 2.4.0", "bytemuck", "drm-ffi", "drm-fourcc", - "nix 0.27.1", + "rustix", ] [[package]] name = "drm-ffi" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba7d1c19c4b6270e89d59fb27dc6d02a317c658a8a54e54781e1db9b5947595d" +checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" dependencies = [ "drm-sys", - "nix 0.27.1", + "rustix", ] [[package]] @@ -259,9 +247,13 @@ checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" [[package]] name = "drm-sys" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f1c0468062a56cd5705f1e3b5409eb286d5596a2028ec8e947595d7e715ae" +checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176" +dependencies = [ + "libc", + "linux-raw-sys 0.6.4", +] [[package]] name = "dtoa" @@ -299,6 +291,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "float-cmp" version = "0.9.0" @@ -446,17 +448,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.10" @@ -465,7 +456,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -648,7 +639,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -680,17 +671,16 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "librsvg" -version = "2.56.92" +version = "2.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7e30ebdab4ce0c632d361b54989020c2e15060f77728ca99b8e3daa4cc94f3c" +checksum = "a7411554079bdc0af967356757e6c9b1a60fba1aa7ee95d9c80e170be8ea4892" dependencies = [ - "byteorder", "cairo-rs", "cast", "cssparser", @@ -732,6 +722,18 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "linux-raw-sys" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b5399f6804fbab912acbd8878ed3532d506b7c951b8f9f164ef90fef39e3f4" + [[package]] name = "locale_config" version = "0.3.0" @@ -783,19 +785,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" dependencies = [ "log", - "phf 0.10.1", - "phf_codegen 0.10.0", + "phf", + "phf_codegen", "string_cache", "string_cache_codegen", "tendril", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "matrixmultiply" version = "0.3.7" @@ -887,12 +883,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "num-complex" version = "0.4.4" @@ -1048,7 +1038,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1063,15 +1053,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_shared 0.8.0", -] - [[package]] name = "phf" version = "0.10.1" @@ -1079,38 +1060,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ "phf_macros", - "phf_shared 0.10.0", + "phf_shared", "proc-macro-hack", ] -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", -] - [[package]] name = "phf_codegen" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", + "phf_generator", + "phf_shared", ] [[package]] @@ -1119,8 +1080,8 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.5", + "phf_shared", + "rand", ] [[package]] @@ -1129,23 +1090,14 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", + "phf_generator", + "phf_shared", "proc-macro-hack", "proc-macro2", "quote", "syn 1.0.109", ] -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", -] - [[package]] name = "phf_shared" version = "0.10.0" @@ -1253,20 +1205,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] - [[package]] name = "rand" version = "0.8.5" @@ -1274,18 +1212,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -1295,16 +1223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -1313,25 +1232,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] @@ -1416,12 +1317,16 @@ dependencies = [ ] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rustix" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "semver", + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", ] [[package]] @@ -1441,28 +1346,23 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "selectors" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" +checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cssparser", "derive_more", "fxhash", "log", - "phf 0.8.0", - "phf_codegen 0.8.0", + "new_debug_unreachable", + "phf", + "phf_codegen", "precomputed-hash", "servo_arc", "smallvec", ] -[[package]] -name = "semver" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" - [[package]] name = "serde" version = "1.0.188" @@ -1494,11 +1394,10 @@ dependencies = [ [[package]] name = "servo_arc" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" +checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44" dependencies = [ - "nodrop", "stable_deref_trait", ] @@ -1551,7 +1450,7 @@ dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot", - "phf_shared 0.10.0", + "phf_shared", "precomputed-hash", "serde", ] @@ -1562,8 +1461,8 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", + "phf_generator", + "phf_shared", "proc-macro2", "quote", ] @@ -1642,7 +1541,7 @@ dependencies = [ [[package]] name = "tiny-dfr" -version = "0.2.0" +version = "0.3.1" dependencies = [ "anyhow", "cairo-rs", @@ -1656,7 +1555,7 @@ dependencies = [ "nix 0.27.1", "pkg-config", "privdrop", - "rand 0.8.5", + "rand", "serde", "toml 0.8.8", ] @@ -1802,12 +1701,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1852,7 +1745,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -1861,13 +1763,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -1876,42 +1793,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.15" diff --git a/Cargo.toml b/Cargo.toml index 7b661597..7fce02da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tiny-dfr" -version = "0.2.0" +version = "0.3.1" edition = "2021" license = "MIT AND Apache-2.0" description = "The most basic dynamic function row daemon possible" @@ -11,14 +11,14 @@ repository = "https://github.com/WhatAmISupposedToPutHere/tiny-dfr" [dependencies] cairo-rs = { version = "0.18", default-features = false, features = ["freetype"] } -librsvg = "2.56.0" -drm = "0.10.0" +librsvg = "2.57" +drm = "0.11.1" anyhow = "1" input = "0.8" libc = "0.2" input-linux = { version = "0.6", features = ["serde"] } input-linux-sys = "0.8" -nix = { version = "0.27", features = ["poll", "signal", "inotify"] } +nix = { version = "0.27", features = ["event", "signal", "inotify"] } privdrop = "0.5.3" serde = { version = "1", features = ["derive"] } toml = "0.8" diff --git a/etc/systemd/system/systemd-backlight@backlight:228200000.display-pipe.0.service b/etc/systemd/system/systemd-backlight@backlight:228200000.display-pipe.0.service new file mode 100644 index 00000000..e69de29b diff --git a/etc/systemd/system/systemd-backlight@backlight:appletb_backlight.service b/etc/systemd/system/systemd-backlight@backlight:appletb_backlight.service new file mode 100644 index 00000000..e69de29b diff --git a/etc/systemd/system/tiny-dfr.service b/etc/systemd/system/tiny-dfr.service index cdae3667..1a1ae3b3 100644 --- a/etc/systemd/system/tiny-dfr.service +++ b/etc/systemd/system/tiny-dfr.service @@ -1,8 +1,7 @@ [Unit] Description=Tiny Apple silicon touch bar daemon -After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service systemd-logind.service -StartLimitIntervalSec=30 -StartLimitBurst=2 +After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service systemd-logind.service dev-tiny_dfr_display.device dev-tiny_dfr_backlight.device dev-tiny_dfr_display_backlight.device +BindsTo=dev-tiny_dfr_display.device dev-tiny_dfr_backlight.device dev-tiny_dfr_display_backlight.device [Service] ExecStart=/usr/bin/tiny-dfr diff --git a/etc/udev/rules.d/99-touchbar-backlight.rules b/etc/udev/rules.d/99-touchbar-backlight.rules deleted file mode 100644 index 69d50e88..00000000 --- a/etc/udev/rules.d/99-touchbar-backlight.rules +++ /dev/null @@ -1,2 +0,0 @@ -# The backlight is managed by tiny-df. Tell systemd to leave it alone -SUBSYSTEM=="backlight", KERNEL=="228200000.display-pipe.0", DRIVERS=="panel-summit", ENV{SYSTEMD_READY}="0" diff --git a/etc/udev/rules.d/99-touchbar-seat.rules b/etc/udev/rules.d/99-touchbar-seat.rules index f73534a1..9b0cbde1 100644 --- a/etc/udev/rules.d/99-touchbar-seat.rules +++ b/etc/udev/rules.d/99-touchbar-seat.rules @@ -1,4 +1,5 @@ -SUBSYSTEM=="drm", KERNEL=="card*", DRIVERS=="adp", TAG-="master-of-seat", ENV{ID_SEAT}="seat-touchbar" +SUBSYSTEM=="drm", KERNEL=="card*", DRIVERS=="adp|appletbdrm", TAG-="master-of-seat", ENV{ID_SEAT}="seat-touchbar" +SUBSYSTEM=="input", ATTR{name}=="Apple Inc. Touch Bar Display Touchpad", ENV{ID_SEAT}="seat-touchbar" SUBSYSTEM=="input", ATTR{name}=="MacBookPro17,1 Touch Bar", ENV{ID_SEAT}="seat-touchbar" SUBSYSTEM=="input", ATTR{name}=="Mac14,7 Touch Bar", ENV{ID_SEAT}="seat-touchbar" diff --git a/etc/udev/rules.d/99-touchbar-tiny-dfr.rules b/etc/udev/rules.d/99-touchbar-tiny-dfr.rules index 5169f8fe..cb754012 100644 --- a/etc/udev/rules.d/99-touchbar-tiny-dfr.rules +++ b/etc/udev/rules.d/99-touchbar-tiny-dfr.rules @@ -1,2 +1,15 @@ +ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05ac", ATTR{idProduct}=="8302", ATTR{bConfigurationValue}=="1", ATTR{bConfigurationValue}="0", ATTR{bConfigurationValue}="2" + +SUBSYSTEM=="input", ATTR{name}=="Apple Inc. Touch Bar Display Touchpad", TAG+="systemd", ENV{SYSTEMD_WANTS}="tiny-dfr.service" SUBSYSTEM=="input", ATTR{name}=="MacBookPro17,1 Touch Bar", TAG+="systemd", ENV{SYSTEMD_WANTS}="tiny-dfr.service" SUBSYSTEM=="input", ATTR{name}=="Mac14,7 Touch Bar", TAG+="systemd", ENV{SYSTEMD_WANTS}="tiny-dfr.service" + +SUBSYSTEM=="drm", KERNEL=="card[0-9]*", DRIVERS=="adp|appletbdrm", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/tiny_dfr_display" + +SUBSYSTEM=="backlight", KERNEL=="appletb_backlight", DRIVERS=="hid-appletb-bl", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/tiny_dfr_backlight" +SUBSYSTEM=="backlight", KERNEL=="228200000.display-pipe.0", DRIVERS=="panel-summit", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/tiny_dfr_backlight" + +SUBSYSTEM=="backlight", KERNEL=="apple-panel-bl", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/tiny_dfr_display_backlight" +SUBSYSTEM=="backlight", KERNEL=="gmux_backlight", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/tiny_dfr_display_backlight" +SUBSYSTEM=="backlight", KERNEL=="intel_backlight", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/tiny_dfr_display_backlight" +SUBSYSTEM=="backlight", KERNEL=="acpi_video0", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/tiny_dfr_display_backlight" diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..5e0824ec --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1703068421, + "narHash": "sha256-WSw5Faqlw75McIflnl5v7qVD/B3S2sLh+968bpOGrWA=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d65bceaee0fb1e64363f7871bc43dc1c6ecad99f", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..c05db680 --- /dev/null +++ b/flake.nix @@ -0,0 +1,60 @@ +{ + description = "The most basic dynamic function row daemon possible"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; + }; + outputs = { self, nixpkgs }: + let + supportedSystems = [ "x86_64-linux" "aarch64-linux" ]; + forAllSystems = nixpkgs.lib.genAttrs supportedSystems; + pkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); + in + rec { + packages = forAllSystems(system: + let + pkgs = pkgsFor.${system}; + in + { + default = pkgs.rustPlatform.buildRustPackage { + name = "tiny-dfr"; + version = "0.2.0"; + src = ./.; + cargoLock = { + lockFile = ./Cargo.lock; + }; + nativeBuildInputs = [ + pkgs.pkg-config + ]; + buildInputs = [ + pkgs.cairo + pkgs.libinput + pkgs.freetype + pkgs.fontconfig + pkgs.glib + pkgs.pango + pkgs.gdk-pixbuf + pkgs.libxml2 + ]; + }; + } + ); + + devShells = forAllSystems(system: + let + pkgs = pkgsFor.${system}; + in + { + default = pkgs.mkShell { + inputsFrom = [ + packages.${system}.default + ]; + packages = [ + pkgs.rustfmt + pkgs.rust-analyzer + ]; + RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}"; + }; + } + ); + }; +} diff --git a/share/tiny-dfr/config.toml b/share/tiny-dfr/config.toml index 2eae719c..60c5efbd 100644 --- a/share/tiny-dfr/config.toml +++ b/share/tiny-dfr/config.toml @@ -24,6 +24,17 @@ EnablePixelShift = false # https://www.freedesktop.org/software/fontconfig/fontconfig-user.html FontTemplate = ":bold" +# Set this to false if you want the brightness of the touchbar +# to be set to a static value instead of following the primary +# screen's brightness +AdaptiveBrightness = true + +# With adaptive brightness disabled this is used as the brightness +# in the active state +# With it enabled, this is the maximum point on the brightness curve +# Accepted values are 0-255 +ActiveBrightness = 128 + # This key defines the contents of the primary layer # (the one with F{number} keys) # You can change the individual buttons, add, or remove them @@ -41,6 +52,8 @@ PrimaryLayerKeys = [ # if both are present, the behavior is undefined. # For the list of supported key codes see # https://docs.rs/input-linux/latest/input_linux/enum.Key.html + # Note that the escape key is not specified here, as it is added + # automatically on Macs without a physical one { Text = "F1", Action = "F1" }, { Text = "F2", Action = "F2" }, { Text = "F3", Action = "F3" }, diff --git a/src/backlight.rs b/src/backlight.rs index dd6bd2a7..361fb17d 100644 --- a/src/backlight.rs +++ b/src/backlight.rs @@ -2,17 +2,20 @@ use std::{ fs::{File, OpenOptions, self}, path::{PathBuf, Path}, time::Instant, - io::Write + io::Write, + cmp::min, }; use anyhow::{Result, anyhow}; use input::event::{ Event, switch::{Switch, SwitchEvent, SwitchState}, }; +use crate::config::Config; use crate::TIMEOUT_MS; +const MAX_DISPLAY_BRIGHTNESS: u32 = 509; +const MAX_TOUCH_BAR_BRIGHTNESS: u32 = 255; const BRIGHTNESS_DIM_TIMEOUT: i32 = TIMEOUT_MS * 3; // should be a multiple of TIMEOUT_MS const BRIGHTNESS_OFF_TIMEOUT: i32 = TIMEOUT_MS * 6; // should be a multiple of TIMEOUT_MS -const DEFAULT_BRIGHTNESS: u32 = 128; const DIMMED_BRIGHTNESS: u32 = 1; fn read_attr(path: &Path, attr: &str) -> u32 { @@ -26,11 +29,24 @@ fn read_attr(path: &Path, attr: &str) -> u32 { fn find_backlight() -> Result { for entry in fs::read_dir("/sys/class/backlight/")? { let entry = entry?; - if entry.file_name().to_string_lossy().contains("display-pipe") { + let file_name = entry.file_name(); + let name = file_name.to_string_lossy(); + + if ["display-pipe", "appletb_backlight"].iter().any(|s| name.contains(s)) { + return Ok(entry.path()); + } + } + Err(anyhow!("No Touch Bar backlight device found")) +} + +fn find_display_backlight() -> Result { + for entry in fs::read_dir("/sys/class/backlight/")? { + let entry = entry?; + if ["apple-panel-bl", "gmux_backlight", "intel_backlight", "acpi_video0"].iter().any(|s| entry.file_name().to_string_lossy().contains(s)) { return Ok(entry.path()); } } - Err(anyhow!("No backlight device found")) + Err(anyhow!("No Built-in Retina Display backlight device found")) } fn set_backlight(mut file: &File, value: u32) { @@ -39,22 +55,33 @@ fn set_backlight(mut file: &File, value: u32) { pub struct BacklightManager { last_active: Instant, + max_bl: u32, current_bl: u32, lid_state: SwitchState, - bl_file: File + bl_file: File, + display_bl_path: PathBuf } impl BacklightManager { pub fn new() -> BacklightManager { let bl_path = find_backlight().unwrap(); + let display_bl_path = find_display_backlight().unwrap(); let bl_file = OpenOptions::new().write(true).open(bl_path.join("brightness")).unwrap(); BacklightManager { bl_file, lid_state: SwitchState::Off, + max_bl: read_attr(&bl_path, "max_brightness"), current_bl: read_attr(&bl_path, "brightness"), - last_active: Instant::now() + last_active: Instant::now(), + display_bl_path } } + fn display_to_touchbar(display: u32, active_brightness: u32) -> u32 { + let normalized = display as f64 / MAX_DISPLAY_BRIGHTNESS as f64; + // Add one so that the touch bar does not turn off + let adjusted = (normalized.powf(0.5) * active_brightness as f64) as u32 + 1; + adjusted.min(MAX_TOUCH_BAR_BRIGHTNESS) // Clamp the value to the maximum allowed brightness + } pub fn process_event(&mut self, event: &Event) { match event { Event::Keyboard(_) | Event::Pointer(_) | Event::Gesture(_) | Event::Touch(_) => { @@ -75,17 +102,21 @@ impl BacklightManager { _ => {} } } - pub fn update_backlight(&mut self) { + pub fn update_backlight(&mut self, cfg: &Config) { let since_last_active = (Instant::now() - self.last_active).as_millis() as u64; - let new_bl = if self.lid_state == SwitchState::On { + let new_bl = min(self.max_bl, if self.lid_state == SwitchState::On { 0 } else if since_last_active < BRIGHTNESS_DIM_TIMEOUT as u64 { - DEFAULT_BRIGHTNESS + if cfg.adaptive_brightness { + BacklightManager::display_to_touchbar(read_attr(&self.display_bl_path, "brightness"), cfg.active_brightness) + } else { + cfg.active_brightness + } } else if since_last_active < BRIGHTNESS_OFF_TIMEOUT as u64 { DIMMED_BRIGHTNESS } else { 0 - }; + }); if self.current_bl != new_bl { self.current_bl = new_bl; set_backlight(&self.bl_file, self.current_bl); diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 00000000..6d884520 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,147 @@ +use std::{ + fs::read_to_string, + os::fd::AsFd +}; +use anyhow::Error; +use cairo::FontFace; +use crate::{FunctionLayer, Button}; +use crate::fonts::{FontConfig, Pattern}; +use freetype::Library as FtLibrary; +use input_linux::Key; +use nix::{ + errno::Errno, + sys::inotify::{AddWatchFlags, InitFlags, Inotify, WatchDescriptor} +}; +use serde::Deserialize; + +const USER_CFG_PATH: &'static str = "/etc/tiny-dfr/config.toml"; + +pub struct Config { + pub show_button_outlines: bool, + pub enable_pixel_shift: bool, + pub font_face: FontFace, + pub adaptive_brightness: bool, + pub active_brightness: u32, +} + +#[derive(Deserialize)] +#[serde(rename_all = "PascalCase")] +struct ConfigProxy { + media_layer_default: Option, + show_button_outlines: Option, + enable_pixel_shift: Option, + font_template: Option, + adaptive_brightness: Option, + active_brightness: Option, + primary_layer_keys: Option>, + media_layer_keys: Option> +} + +#[derive(Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct ButtonConfig { + #[serde(alias = "Svg")] + pub icon: Option, + pub text: Option, + pub action: Key +} + +fn load_font(name: &str) -> FontFace { + let fontconfig = FontConfig::new(); + let mut pattern = Pattern::new(name); + fontconfig.perform_substitutions(&mut pattern); + let pat_match = match fontconfig.match_pattern(&pattern) { + Ok(pat) => pat, + Err(_) => panic!("Unable to find specified font. If you are using the default config, make sure you have at least one font installed") + }; + let file_name = pat_match.get_file_name(); + let file_idx = pat_match.get_font_index(); + let ft_library = FtLibrary::init().unwrap(); + let face = ft_library.new_face(file_name, file_idx).unwrap(); + FontFace::create_from_ft(&face).unwrap() +} + +fn load_config(width: u16) -> (Config, [FunctionLayer; 2]) { + let mut base = toml::from_str::(&read_to_string("/usr/share/tiny-dfr/config.toml").unwrap()).unwrap(); + let user = read_to_string(USER_CFG_PATH).map_err::(|e| e.into()) + .and_then(|r| Ok(toml::from_str::(&r)?)); + if let Ok(user) = user { + base.media_layer_default = user.media_layer_default.or(base.media_layer_default); + base.show_button_outlines = user.show_button_outlines.or(base.show_button_outlines); + base.enable_pixel_shift = user.enable_pixel_shift.or(base.enable_pixel_shift); + base.font_template = user.font_template.or(base.font_template); + base.adaptive_brightness = user.adaptive_brightness.or(base.adaptive_brightness); + base.media_layer_keys = user.media_layer_keys.or(base.media_layer_keys); + base.primary_layer_keys = user.primary_layer_keys.or(base.primary_layer_keys); + base.active_brightness = user.active_brightness.or(base.active_brightness); + }; + let media_layer = FunctionLayer::with_config(base.media_layer_keys.unwrap()); + let fkey_layer = FunctionLayer::with_config(base.primary_layer_keys.unwrap()); + let mut layers = if base.media_layer_default.unwrap(){ [media_layer, fkey_layer] } else { [fkey_layer, media_layer] }; + if width >= 2170 { + for layer in &mut layers { + layer.buttons.insert(0, Button::new_text("esc".to_string(), Key::Esc)); + } + } + let cfg = Config { + show_button_outlines: base.show_button_outlines.unwrap(), + enable_pixel_shift: base.enable_pixel_shift.unwrap(), + adaptive_brightness: base.adaptive_brightness.unwrap(), + font_face: load_font(&base.font_template.unwrap()), + active_brightness: base.active_brightness.unwrap() + }; + (cfg, layers) +} + +pub struct ConfigManager { + inotify_fd: Inotify, + watch_desc: Option +} + +fn arm_inotify(inotify_fd: &Inotify) -> Option { + let flags = AddWatchFlags::IN_MOVED_TO | AddWatchFlags::IN_CLOSE | AddWatchFlags::IN_ONESHOT; + match inotify_fd.add_watch(USER_CFG_PATH, flags) { + Ok(wd) => Some(wd), + Err(Errno::ENOENT) => None, + e => Some(e.unwrap()) + } +} + +impl ConfigManager { + pub fn new() -> ConfigManager { + let inotify_fd = Inotify::init(InitFlags::IN_NONBLOCK).unwrap(); + let watch_desc = arm_inotify(&inotify_fd); + ConfigManager { + inotify_fd, watch_desc + } + } + pub fn load_config(&self, width: u16) -> (Config, [FunctionLayer; 2]) { + load_config(width) + } + pub fn update_config(&mut self, cfg: &mut Config, layers: &mut [FunctionLayer; 2], width: u16) -> bool { + if self.watch_desc.is_none() { + self.watch_desc = arm_inotify(&self.inotify_fd); + return false; + } + let evts = match self.inotify_fd.read_events() { + Ok(e) => e, + Err(Errno::EAGAIN) => Vec::new(), + r => r.unwrap(), + }; + let mut ret = false; + for evt in evts { + if evt.wd != self.watch_desc.unwrap() { + continue + } + let parts = load_config(width); + *cfg = parts.0; + *layers = parts.1; + ret = true; + self.watch_desc = arm_inotify(&self.inotify_fd); + } + ret + } + pub fn fd(&self) -> &impl AsFd { + &self.inotify_fd + } +} diff --git a/src/display.rs b/src/display.rs index a0c1589c..0e2a8502 100644 --- a/src/display.rs +++ b/src/display.rs @@ -7,7 +7,7 @@ use drm::{ ClientCapability, Device as DrmDevice, buffer::DrmFourcc, control::{ connector, Device as ControlDevice, property, ResourceHandle, atomic, AtomicCommitFlags, - dumbbuffer::{DumbBuffer, DumbMapping}, framebuffer, ClipRect + dumbbuffer::{DumbBuffer, DumbMapping}, framebuffer, ClipRect, Mode } }; use anyhow::{Result, anyhow}; @@ -34,6 +34,7 @@ impl Card { pub struct DrmBackend { card: Card, + mode: Mode, db: DumbBuffer, fb: framebuffer::Handle } @@ -169,11 +170,12 @@ fn try_open_card(path: &Path) -> Result { card.atomic_commit(AtomicCommitFlags::ALLOW_MODESET, atomic_req)?; - Ok(DrmBackend { card, db, fb }) + Ok(DrmBackend { card, mode, db, fb }) } impl DrmBackend { pub fn open_card() -> Result { + let mut errors = Vec::new(); for entry in fs::read_dir("/dev/dri/")? { let entry = entry?; if !entry.file_name().to_string_lossy().starts_with("card") { @@ -181,10 +183,18 @@ impl DrmBackend { } match try_open_card(&entry.path()) { Ok(card) => return Ok(card), - Err(_) => {} + Err(err) => { + errors.push(format!("{}: {}", entry.path().as_os_str().to_string_lossy(), err.to_string())) + } } } - Err(anyhow!("No touchbar device found")) + Err(anyhow!("No touchbar device found, attempted: [\n {}\n]", errors.join(",\n "))) + } + pub fn mode(&self) -> Mode { + self.mode + } + pub fn fb_info(&self) -> Result { + Ok(self.card.get_framebuffer(self.fb)?) } pub fn dirty(&self, clips: &[ClipRect]) -> Result<()> { Ok(self.card.dirty_framebuffer(self.fb, clips)?) diff --git a/src/fonts.rs b/src/fonts.rs index 9e08c198..d358fadf 100644 --- a/src/fonts.rs +++ b/src/fonts.rs @@ -1,3 +1,4 @@ +#![allow(non_upper_case_globals)] use std::ffi::{c_char, c_int, CStr, CString}; use std::ptr; @@ -9,11 +10,21 @@ struct FcPattern { struct FcConfig { _data: [u8; 0] } + type FcResult = c_int; +const FcResultMatch: FcResult = 0; +const FcResultNoMatch: FcResult = 1; +const FcResultTypeMismatch: FcResult = 2; +const FcResultNoId: FcResult = 3; +const FcResultOutOfMemory: FcResult = 4; + type FcMatchKind = c_int; -#[allow(non_upper_case_globals)] const FcMatchPattern: FcMatchKind = 0; +pub enum FontConfigError { + FontNotFound +} + pub struct FontConfig { config: *const FcConfig } @@ -27,18 +38,23 @@ impl FontConfig { config } } - pub fn match_pattern(&self, pattern: &Pattern) -> Pattern { + pub fn match_pattern(&self, pattern: &Pattern) -> Result { let mut result: FcResult = 0; let match_ = unsafe { FcFontMatch(self.config, pattern.pattern, &mut result) }; - Pattern { - pattern: match_ + if match_ == ptr::null_mut() { + return Err(FontConfigError::FontNotFound); } + Ok(Pattern { + pattern: match_ + }) } pub fn perform_substitutions(&self, pattern: &mut Pattern) { unsafe { - FcConfigSubstitute(self.config, pattern.pattern, FcMatchPattern); + if (FcConfigSubstitute(self.config, pattern.pattern, FcMatchPattern)) == 0 { + panic!("Allocation error while loading fontconfig data"); + } FcDefaultSubstitute(pattern.pattern); } } @@ -52,6 +68,27 @@ impl Drop for FontConfig { } } +fn throw_on_fcpattern_result(res: FcResult) { + match res { + FcResultMatch => {}, + FcResultNoMatch => { + panic!("NULL pattern"); + }, + FcResultTypeMismatch => { + panic!("Wrong type for pattern element"); + }, + FcResultNoId => { + panic!("Unknown pattern element"); + }, + FcResultOutOfMemory => { + panic!("Out of memory"); + }, + r => { + panic!("Unknown fontconfig return value {:?}", r) + } + } +} + pub struct Pattern { pattern: *const FcPattern } @@ -70,7 +107,8 @@ impl Pattern { let name = CString::new("file").unwrap(); unsafe { let mut file_name = ptr::null(); - FcPatternGetString(self.pattern, name.as_ptr(), 0, &mut file_name); + let res = FcPatternGetString(self.pattern, name.as_ptr(), 0, &mut file_name); + throw_on_fcpattern_result(res); CStr::from_ptr(file_name).to_str().unwrap() } } @@ -78,7 +116,8 @@ impl Pattern { let name = CString::new("index").unwrap(); unsafe { let mut index = 0; - FcPatternGetInteger(self.pattern, name.as_ptr(), 0, &mut index); + let res = FcPatternGetInteger(self.pattern, name.as_ptr(), 0, &mut index); + throw_on_fcpattern_result(res); index as isize } } diff --git a/src/main.rs b/src/main.rs index 3929e2e8..b4467cbd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use std::{ - fs::{File, OpenOptions, read_to_string}, + fs::{File, OpenOptions}, os::{ fd::{AsRawFd, AsFd}, unix::{io::OwnedFd, fs::OpenOptionsExt} @@ -9,10 +9,10 @@ use std::{ cmp::min, panic::{self, AssertUnwindSafe} }; -use cairo::{ImageSurface, Format, Context, Surface, Rectangle, FontFace, Antialias}; +use cairo::{ImageSurface, Format, Context, Surface, Rectangle, Antialias}; use rsvg::{Loader, CairoRenderer, SvgHandle}; use drm::control::ClipRect; -use anyhow::{Error, Result}; +use anyhow::Result; use input::{ Libinput, LibinputInterface, Device as InputDevice, event::{ @@ -25,62 +25,31 @@ use libc::{O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY, c_char}; use input_linux::{uinput::UInputHandle, EventKind, Key, SynchronizeKind}; use input_linux_sys::{uinput_setup, input_id, timeval, input_event}; use nix::{ - poll::{poll, PollFd, PollFlags}, sys::{ signal::{Signal, SigSet}, - inotify::{AddWatchFlags, InitFlags, Inotify, WatchDescriptor} - }, + epoll::{Epoll, EpollCreateFlags, EpollEvent, EpollFlags} + }, errno::Errno }; use privdrop::PrivDrop; -use serde::Deserialize; -use freetype::Library as FtLibrary; mod backlight; mod display; mod pixel_shift; mod fonts; +mod config; use backlight::BacklightManager; use display::DrmBackend; use pixel_shift::{PixelShiftManager, PIXEL_SHIFT_WIDTH_PX}; -use fonts::{FontConfig, Pattern}; +use config::{ButtonConfig, Config}; +use crate::config::ConfigManager; -const DFR_WIDTH: i32 = 2008; -const DFR_HEIGHT: i32 = 60; -const DFR_STRIDE: i32 = 64; const BUTTON_SPACING_PX: i32 = 16; const BUTTON_COLOR_INACTIVE: f64 = 0.200; const BUTTON_COLOR_ACTIVE: f64 = 0.400; const ICON_SIZE: i32 = 48; const TIMEOUT_MS: i32 = 10 * 1000; -const USER_CFG_PATH: &'static str = "/etc/tiny-dfr/config.toml"; - -#[derive(Deserialize)] -#[serde(rename_all = "PascalCase")] -struct ConfigProxy { - media_layer_default: Option, - show_button_outlines: Option, - enable_pixel_shift: Option, - font_template: Option, - primary_layer_keys: Option>, - media_layer_keys: Option> -} - -#[derive(Deserialize)] -#[serde(rename_all = "PascalCase")] -struct ButtonConfig { - #[serde(alias = "Svg")] - icon: Option, - text: Option, - action: Key -} - -struct Config { - show_button_outlines: bool, - enable_pixel_shift: bool, - font_face: FontFace, -} enum ButtonImage { Text(String), @@ -145,20 +114,20 @@ impl Button { changed: false, } } - fn render(&self, c: &Context, button_left_edge: f64, button_width: u64, y_shift: f64) { + fn render(&self, c: &Context, height: i32, button_left_edge: f64, button_width: u64, y_shift: f64) { match &self.image { ButtonImage::Text(text) => { let extents = c.text_extents(text).unwrap(); c.move_to( button_left_edge + (button_width as f64 / 2.0 - extents.width() / 2.0).round(), - y_shift + (DFR_HEIGHT as f64 / 2.0 + extents.height() / 2.0).round() + y_shift + (height as f64 / 2.0 + extents.height() / 2.0).round() ); c.show_text(text).unwrap(); }, ButtonImage::Svg(svg) => { let renderer = CairoRenderer::new(&svg); let x = button_left_edge + (button_width as f64 / 2.0 - (ICON_SIZE / 2) as f64).round(); - let y = y_shift + ((DFR_HEIGHT as f64 - ICON_SIZE as f64) / 2.0).round(); + let y = y_shift + ((height as f64 - ICON_SIZE as f64) / 2.0).round(); renderer.render_document(c, &Rectangle::new(x, y, ICON_SIZE as f64, ICON_SIZE as f64) @@ -166,7 +135,7 @@ impl Button { } ButtonImage::Bitmap(surf) => { let x = button_left_edge + (button_width as f64 / 2.0 - (ICON_SIZE / 2) as f64).round(); - let y = y_shift + ((DFR_HEIGHT as f64 - ICON_SIZE as f64) / 2.0).round(); + let y = y_shift + ((height as f64 - ICON_SIZE as f64) / 2.0).round(); c.set_source_surface(surf, x, y).unwrap(); c.rectangle(x, y, ICON_SIZE as f64, ICON_SIZE as f64); c.fill().unwrap(); @@ -184,7 +153,7 @@ impl Button { } #[derive(Default)] -struct FunctionLayer { +pub struct FunctionLayer { buttons: Vec