aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/release.yml112
-rw-r--r--Cargo.lock560
-rw-r--r--Cargo.toml17
-rw-r--r--src/bin/sctd.rs51
-rw-r--r--src/lib.rs55
-rw-r--r--src/platform.rs5
-rw-r--r--src/platform/linux.rs34
-rw-r--r--src/platform/macos.rs44
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 }}
diff --git a/Cargo.lock b/Cargo.lock
index 2c025f4..099c7fd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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",
diff --git a/Cargo.toml b/Cargo.toml
index 5868b4a..572453f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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:?}"
);
}
}
diff --git a/src/lib.rs b/src/lib.rs
index dfe872a..05f8d9e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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(),
+ );
+ }
+}