diff options
| -rw-r--r-- | .github/workflows/release.yml | 112 | ||||
| -rw-r--r-- | Cargo.lock | 560 | ||||
| -rw-r--r-- | Cargo.toml | 17 | ||||
| -rw-r--r-- | src/bin/sctd.rs | 51 | ||||
| -rw-r--r-- | src/lib.rs | 55 | ||||
| -rw-r--r-- | src/platform.rs | 5 | ||||
| -rw-r--r-- | src/platform/linux.rs | 34 | ||||
| -rw-r--r-- | src/platform/macos.rs | 44 |
8 files changed, 614 insertions, 264 deletions
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a887f70..f63fdf0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,50 +4,58 @@ on: tags: - '[0-9]+.[0-9]+.[0-9]+' +permissions: + contents: write + jobs: create-release: name: create-release - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest + outputs: + sctd_version: ${{ env.SCTD_VERSION }} steps: - - name: Create artifacts directory - run: mkdir artifacts - + - uses: actions/checkout@v4 - name: Get the release version from the tag - if: env.SCTD_VERSION == '' + shell: bash + run: echo "SCTD_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV + - name: Show the version run: | - echo "::set-env name=SCTD_VERSION::${GITHUB_REF#refs/tags/}" - echo "version is: ${{ env.SCTD_VERSION }}" - + echo "version is: $SCTD_VERSION" + - name: Check that tag version and Cargo.toml version are the same + shell: bash + run: | + if ! grep -q "version = \"$SCTD_VERSION\"" Cargo.toml; then + echo "version does not match Cargo.toml" >&2 + exit 1 + fi - name: Create GitHub release - id: release - uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ env.SCTD_VERSION }} - release_name: ${{ env.SCTD_VERSION }} - - - name: Save release upload URL to artifact - run: echo "${{ steps.release.outputs.upload_url }}" > artifacts/release-upload-url - - - name: Save version number to artifact - run: echo "${{ env.SCTD_VERSION }}" > artifacts/release-version - - - name: Upload artifacts - uses: actions/upload-artifact@v1 - with: - name: artifacts - path: artifacts + run: gh release create ${{ env.SCTD_VERSION }} --draft --verify-tag --title ${{ env.SCTD_VERSION }} build-release: name: build-release needs: ['create-release'] - runs-on: ubuntu-18.04 + runs-on: ${{ matrix.os }} + strategy: + matrix: + build: [linux, macos] + include: + - build: linux + os: ubuntu-latest + rust: stable + target: x86_64-unknown-linux-gnu + - build: macos + os: macos-latest + rust: stable + target: x86_64-apple-darwin + steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - - name: Install packages + - name: Install packages (Linux) + if: matrix.build == 'linux' run: | sudo apt-get update sudo apt-get install -y --no-install-recommends \ @@ -55,47 +63,33 @@ jobs: libxrandr-dev - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - override: true - - - name: Get release upload URL - uses: actions/download-artifact@v1 + uses: dtolnay/rust-toolchain@master with: - name: artifacts - path: artifacts - - - name: Set release upload URL and release version - shell: bash - run: | - release_upload_url="$(cat artifacts/release-upload-url)" - echo "::set-env name=RELEASE_UPLOAD_URL::$release_upload_url" - echo "release upload url: $RELEASE_UPLOAD_URL" - release_version="$(cat artifacts/release-version)" - echo "::set-env name=RELEASE_VERSION::$release_version" - echo "release version: $RELEASE_VERSION" + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} - name: Build release binary - run: cargo build --verbose --release + run: cargo build --verbose --release --target ${{ matrix.target }} + + - name: Strip release binary (linux and macos) + if: matrix.build == 'linux' || matrix.build == 'macos' + run: strip "target/${{ matrix.target }}/release/sctd" - name: Build archive shell: bash run: | - staging="sctd-${{ env.RELEASE_VERSION }}" + staging="sctd-${{ needs.create-release.outputs.sctd_version }}-${{ matrix.target }}" mkdir -p "$staging" - cp target/release/sctd "$staging" - cp LICENSE "$staging" + + cp "target/${{ matrix.target }}/release/sctd" "$staging/" + cp README.md LICENSE "$staging/" + tar czf "$staging.tar.gz" "$staging" - echo "::set-env name=ASSET::$staging.tar.gz" + shasum -a 256 "$staging.tar.gz" > "$staging.tar.gz.sha256" + echo "ASSET=$staging.tar.gz" >> $GITHUB_ENV + echo "ASSET_SUM=$staging.tar.gz.sha256" >> $GITHUB_ENV - name: Upload release archive - uses: actions/upload-release-asset@v1.0.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ env.RELEASE_UPLOAD_URL }} - asset_path: ${{ env.ASSET }} - asset_name: ${{ env.ASSET }} - asset_content_type: application/octet-stream + run: gh release upload ${{ needs.create-release.outputs.sctd_version }} ${{ env.ASSET }} ${{ env.ASSET_SUM }} @@ -1,6 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] name = "android_system_properties" @@ -12,225 +18,371 @@ dependencies = [ ] [[package]] -name = "atty" -version = "0.2.14" +name = "anstream" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "cc" +version = "1.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", - "time", "wasm-bindgen", - "winapi", + "windows-link", ] [[package]] name = "clap" -version = "3.2.22" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ - "atty", - "bitflags", + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "indexmap", "strsim", - "termcolor", - "textwrap", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ - "os_str_bytes", + "core-foundation-sys", + "libc", ] [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags", + "core-foundation", + "libc", +] + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", +] [[package]] name = "env_logger" -version = "0.9.1" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ - "humantime", + "env_filter", + "jiff", "log", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "foreign-types" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "foreign-types-macros" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ - "libc", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "humantime" -version = "2.1.0" +name = "foreign-types-shared" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "iana-time-zone" -version = "0.1.48" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237a0714f28b1ee39ccec0770ccb544eb02c9ef2c82bb096230eefcffa6468b0" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", - "once_cell", + "log", "wasm-bindgen", - "winapi", + "windows-core", ] [[package]] -name = "indexmap" -version = "1.9.1" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "autocfg", - "hashbrown", + "cc", ] [[package]] -name = "js-sys" -version = "0.3.60" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" -dependencies = [ - "wasm-bindgen", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] -name = "libc" -version = "0.2.133" +name = "jiff" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] [[package]] -name = "log" -version = "0.4.17" +name = "jiff-static" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ - "cfg-if", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "num-integer" -version = "0.1.45" +name = "js-sys" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ - "autocfg", - "num-traits", + "once_cell", + "wasm-bindgen", ] [[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.14.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "os_str_bytes" -version = "6.3.0" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[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-macro2" -version = "1.0.43" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] name = "sctd" -version = "0.3.0" +version = "0.4.0" dependencies = [ "chrono", "clap", + "core-graphics", "env_logger", "log", "spa", @@ -238,25 +390,52 @@ dependencies = [ ] [[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] name = "spa" -version = "0.3.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "188e0376df998cb9f953a6d4ceb8556fe9223d1f3386e5c0cdb69aab31d62f1b" +checksum = "b23404f558ad79b3699cf61d6f2d65a64c1bd63249c1ef70321fec26933abd36" dependencies = [ "chrono", + "thiserror", ] [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "1.0.100" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -264,62 +443,57 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.1.3" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "winapi-util", + "thiserror-impl", ] [[package]] -name = "textwrap" -version = "0.15.1" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "libc", - "wasi", - "winapi", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -328,9 +502,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -338,9 +512,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -351,46 +525,150 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-core" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-implement" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "winapi-util" -version = "0.1.5" +name = "windows-interface" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ - "winapi", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "x11" -version = "2.20.0" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7ae97874a928d821b061fce3d1fc52f08071dd53c89a6102bc06efcac3b2908" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" dependencies = [ "libc", "pkg-config", @@ -1,21 +1,24 @@ [package] name = "sctd" -version = "0.3.0" +version = "0.4.0" authors = ["Amir Saeid <amir@glgdgt.com>"] edition = "2018" license = "CC0-1.0" [dependencies] chrono = "0.4" -spa = "0.3" -clap = "3.2" +spa = "0.5" +clap = "4.5" log = "0.4" [dependencies.env_logger] -version = "0.9" -default_features = false +version = "0.11" +default-features = false features = ["humantime"] -[dependencies.x11] -version = "2.20" +[target.'cfg(target_os = "linux")'.dependencies.x11] +version = "2.21" features = ["xlib", "xrandr"] + +[target.'cfg(target_os = "macos")'.dependencies] +core-graphics = "0.25" diff --git a/src/bin/sctd.rs b/src/bin/sctd.rs index 81e65e5..d691586 100644 --- a/src/bin/sctd.rs +++ b/src/bin/sctd.rs @@ -6,9 +6,9 @@ extern crate clap; extern crate spa; use chrono::prelude::*; -use clap::{value_t_or_exit, App, Arg}; +use clap::{Arg, Command}; use env_logger::Env; -use spa::calc_sunrise_and_set; +use spa::{sunrise_and_set, StdFloatOps}; use std::thread; use std::time::Duration; @@ -16,51 +16,62 @@ fn main() { let env = Env::default().filter_or("SCTD_LOG_LEVEL", "info"); env_logger::init_from_env(env); - let matches = App::new("sctd") - .version("0.3.0") + let matches = Command::new("sctd") + .version(option_env!("CARGO_PKG_VERSION").unwrap_or("N/A")) .about("set color temperature daemon") .arg( - Arg::with_name("latitude") + Arg::new("latitude") .long("latitude") - .takes_value(true) + .value_name("LATITUDE") + .help("Latitude coordinate") .allow_hyphen_values(true), ) .arg( - Arg::with_name("longitude") + Arg::new("longitude") .long("longitude") - .takes_value(true) + .value_name("LONGITUDE") + .help("Longitude coordinate") .allow_hyphen_values(true), ) - .arg(Arg::with_name("reset").long("reset")) + .arg( + Arg::new("reset") + .long("reset") + .help("Reset temperature") + .action(clap::ArgAction::SetTrue), + ) .get_matches(); - if matches.is_present("reset") { + if matches.get_flag("reset") { sctd::reset_temp(); } else { - let latitude = value_t_or_exit!(matches, "latitude", f64); - let longitude = value_t_or_exit!(matches, "longitude", f64); + let latitude: f64 = matches + .get_one::<String>("latitude") + .expect("latitude is required") + .parse() + .expect("latitude must be a valid number"); + let longitude: f64 = matches + .get_one::<String>("longitude") + .expect("longitude is required") + .parse() + .expect("longitude must be a valid number"); let mut temp = 0; loop { let utc: DateTime<Utc> = Utc::now(); - match calc_sunrise_and_set(utc, latitude, longitude) { + match sunrise_and_set::<StdFloatOps>(utc, latitude, longitude) { Ok(ss) => { let new_temp = sctd::get_temp(utc, &ss, latitude, longitude) as u32; if new_temp != temp { temp = new_temp; - info!("setting temperature to {}", temp); + info!("setting temperature to {temp}"); sctd::set_temp(temp); } else { - debug!( - "skipping temperature change as it hasn't changed ({})", - temp - ); + debug!("skipping temperature change as it hasn't changed ({temp})"); } } Err(e) => { error!( - "error calculating sunrise and sunset for {}, {}: {:?}", - latitude, longitude, e + "error calculating sunrise and sunset for {latitude}, {longitude}: {e:?}" ); } } @@ -3,14 +3,16 @@ extern crate log; extern crate spa; +mod platform; + use chrono::prelude::*; -use spa::{calc_solar_position, SunriseAndSet}; -use std::os::raw::{c_ushort, c_void}; -use std::ptr; -use x11::xlib::{XCloseDisplay, XDefaultScreen, XFree, XOpenDisplay, XRootWindow}; -use x11::xrandr::{ - XRRAllocGamma, XRRCrtcGamma, XRRGetCrtcGammaSize, XRRGetScreenResourcesCurrent, XRRSetCrtcGamma, -}; +use spa::{solar_position, StdFloatOps, SunriseAndSet}; + +#[cfg(target_os = "linux")] +use platform::linux as os; + +#[cfg(target_os = "macos")] +use platform::macos as os; const LOW_TEMP: f64 = 3500f64; const HIGH_TEMP: f64 = 5500f64; @@ -26,52 +28,31 @@ pub struct WhitePoint { } pub fn set_temp(temp: u32) { - let ratio: f64 = (temp % 500) as f64 / 500f64; - unsafe { - let display = XOpenDisplay(ptr::null_mut()); - let screen = XDefaultScreen(display); - let root = XRootWindow(display, screen); - let resource = XRRGetScreenResourcesCurrent(display, root); - - for x in 0..(*resource).ncrtc { - let crtcxid = (*resource).crtcs.offset(x as isize); - let size = XRRGetCrtcGammaSize(display, *crtcxid); - let crtc_gamma: *mut XRRCrtcGamma = XRRAllocGamma(size); - let gamma = avg(temp, ratio); - - for i in 0..size { - let g = (65535f64 * i as f64) / size as f64; - *((*crtc_gamma).red as *mut c_ushort).offset(i as isize) = (g * gamma.red) as u16; - *((*crtc_gamma).green as *mut c_ushort).offset(i as isize) = - (g * gamma.green) as u16; - *((*crtc_gamma).blue as *mut c_ushort).offset(i as isize) = (g * gamma.blue) as u16; - } - XRRSetCrtcGamma(display, *crtcxid, crtc_gamma); - XFree(crtc_gamma as *mut c_void); - } - XCloseDisplay(display); - } + os::set_temp(temp); } pub fn reset_temp() { - set_temp(HIGH_TEMP as u32); + os::set_temp(HIGH_TEMP as u32); } fn get_transition_progress_from_elevation(elevation: f64) -> f64 { if elevation < TRANSITION_LOW { - return 0.0; + 0.0 } else if elevation < TRANSITION_HIGH { (TRANSITION_LOW - elevation) / (TRANSITION_LOW - TRANSITION_HIGH) } else { - return 1.0; + 1.0 } } pub fn get_temp(utc: DateTime<Utc>, ss: &SunriseAndSet, lat: f64, lon: f64) -> f64 { match *ss { SunriseAndSet::Daylight(_, _) => { - let elevation = 90f64 - calc_solar_position(utc, lat, lon).unwrap().zenith_angle; - debug!("elevation: {}", elevation); + let elevation = 90f64 + - solar_position::<StdFloatOps>(utc, lat, lon) + .unwrap() + .zenith_angle; + debug!("elevation: {elevation}"); let progress = get_transition_progress_from_elevation(elevation); LOW_TEMP + (progress * (HIGH_TEMP - LOW_TEMP)) } diff --git a/src/platform.rs b/src/platform.rs new file mode 100644 index 0000000..204fd43 --- /dev/null +++ b/src/platform.rs @@ -0,0 +1,5 @@ +#[cfg(target_os = "linux")] +pub mod linux; + +#[cfg(target_os = "macos")] +pub mod macos; diff --git a/src/platform/linux.rs b/src/platform/linux.rs new file mode 100644 index 0000000..ec0fc6a --- /dev/null +++ b/src/platform/linux.rs @@ -0,0 +1,34 @@ +use std::os::raw::{c_ushort, c_void}; +use std::ptr; +use x11::xlib::{XCloseDisplay, XDefaultScreen, XFree, XOpenDisplay, XRootWindow}; +use x11::xrandr::{ + XRRAllocGamma, XRRCrtcGamma, XRRGetCrtcGammaSize, XRRGetScreenResourcesCurrent, XRRSetCrtcGamma, +}; + +pub fn set_temp(temp: u32) { + let ratio: f64 = (temp % 500) as f64 / 500f64; + unsafe { + let display = XOpenDisplay(ptr::null_mut()); + let screen = XDefaultScreen(display); + let root = XRootWindow(display, screen); + let resource = XRRGetScreenResourcesCurrent(display, root); + + for x in 0..(*resource).ncrtc { + let crtcxid = (*resource).crtcs.offset(x as isize); + let size = XRRGetCrtcGammaSize(display, *crtcxid); + let crtc_gamma: *mut XRRCrtcGamma = XRRAllocGamma(size); + let gamma = crate::avg(temp, ratio); + + for i in 0..size { + let g = (65535f64 * i as f64) / size as f64; + *((*crtc_gamma).red as *mut c_ushort).offset(i as isize) = (g * gamma.red) as u16; + *((*crtc_gamma).green as *mut c_ushort).offset(i as isize) = + (g * gamma.green) as u16; + *((*crtc_gamma).blue as *mut c_ushort).offset(i as isize) = (g * gamma.blue) as u16; + } + XRRSetCrtcGamma(display, *crtcxid, crtc_gamma); + XFree(crtc_gamma as *mut c_void); + } + XCloseDisplay(display); + } +} diff --git a/src/platform/macos.rs b/src/platform/macos.rs new file mode 100644 index 0000000..0292250 --- /dev/null +++ b/src/platform/macos.rs @@ -0,0 +1,44 @@ +use core_graphics::display::CGDisplay; + +pub fn set_temp(temp: u32) { + use std::os::raw::c_int; + + let ratio: f64 = (temp % 500) as f64 / 500f64; + let gamma = crate::avg(temp, ratio); + + let main_display = CGDisplay::main(); + + extern "C" { + fn CGSetDisplayTransferByTable( + display: u32, + table_size: u32, + red_table: *const f32, + green_table: *const f32, + blue_table: *const f32, + ) -> c_int; + fn CGDisplayGammaTableCapacity(display: u32) -> u32; + } + + let table_size = unsafe { CGDisplayGammaTableCapacity(main_display.id) } as usize; + + let mut red_table = vec![0.0; table_size]; + let mut green_table = vec![0.0; table_size]; + let mut blue_table = vec![0.0; table_size]; + + for i in 0..table_size { + let value = (i as f32) / (table_size as f32 - 1.0); + red_table[i] = (value * gamma.red as f32).min(1.0); + green_table[i] = (value * gamma.green as f32).min(1.0); + blue_table[i] = (value * gamma.blue as f32).min(1.0); + } + + unsafe { + CGSetDisplayTransferByTable( + main_display.id, + table_size as u32, + red_table.as_ptr(), + green_table.as_ptr(), + blue_table.as_ptr(), + ); + } +} |
