Compare commits

...

94 Commits

Author SHA1 Message Date
李通洲 3c618a8cd0 Merge remote-tracking branch 'upstream/master' into dev 2024-02-10 14:14:09 +08:00
李通洲 b5821de793 Release: v2.8.1 2024-02-10 14:02:22 +08:00
李通洲 dec604691c CMake: try fixing packaging name conflicting 2024-02-10 13:59:34 +08:00
Carter Li 72baa6cca9 Merge pull request #712 from fastfetch-cli/dev
Release v2.8.0
2024-02-10 12:02:58 +08:00
李通洲 34b023a74f Release: 2.8.0 (ci skip)
For Luna New Year!
2024-02-10 10:32:14 +08:00
李通洲 8249a8ed6a Doc: update changelog 2024-02-09 00:10:29 +08:00
李通洲 7e1ac5e24a Terminal (Windows): code cleanup 2024-02-08 23:15:58 +08:00
李通洲 55c72a8bb3 Camera (Windows): fix Windows Server Core compatibility 2024-02-08 19:14:09 +08:00
Carter Li b602bb20c2 Battery (Linux): print the same format of battery status as other platforms 2024-02-08 14:10:51 +08:00
Carter Li 46ed24275f Battery (FreeBSD): fix typos 2024-02-08 13:59:02 +08:00
Carter Li 71db83f806 PowerAdapter (Linux): don't print not connected either
To align result to macOS
2024-02-08 13:51:30 +08:00
李通洲 0746afa0c2 PowerAdapter (macOS): don't show not connected if no power adapter is detected 2024-02-08 10:53:58 +08:00
李通洲 805c384819 Battery (macOS): don't show an empty battery if no battery is detected 2024-02-08 10:37:06 +08:00
Carter Li 9e4c0e318c Chore: add dpkg related stuff 2024-02-07 14:39:19 +08:00
李通洲 51eaac2fd7 Doc: update changelog 2024-02-06 09:54:33 +08:00
李通洲 92c3df82e6 Logo (Builtin): add PikaOS
Ref: https://github.com/hykilpikonna/hyfetch/pull/231
2024-02-06 09:30:24 +08:00
李通洲 7f238a701e Logo (Builtin): add tatra
Ref: https://github.com/dylanaraps/neofetch/pull/2439
2024-02-06 09:25:44 +08:00
李通洲 72236f62ad Logo (Builtin): add z/OS
Ref: https://github.com/dylanaraps/neofetch/pull/2436
2024-02-06 09:03:01 +08:00
李通洲 51b0c43d76 Platform (Windows): use %USERNAME% if available 2024-02-05 20:01:19 +08:00
李通洲 79e2007d30 Revert "Platform (Linux): use $HOSTNAME if available"
$HOSTNAME doesn't seem to be a standard variable

This reverts commit 02eb604ceb.
2024-02-05 20:01:18 +08:00
李通洲 02eb604ceb Platform (Linux): use $HOSTNAME if available
Ref: #710
2024-02-05 18:23:21 +08:00
李通洲 ce6b2b85f7 Locale (Linux): use environment variable if available
In some machine `setlocale(LC_MESSAGES, NULL)` returns `C` for some reason.
2024-02-05 16:25:12 +08:00
李通洲 48d1980061 CI: build linux old 2024-02-05 14:32:17 +08:00
李通洲 40fae5c5f1 Camera (Android): add empty color space result 2024-02-04 19:07:47 +08:00
李通洲 e296ee1040 CI (Linux): bump version of linux runners
Drop support of Debian 11
2024-02-04 15:48:58 +08:00
李通洲 199e71553d CI: run camera module 2024-02-04 15:14:18 +08:00
李通洲 13fa218e5a Camera: adjust output format 2024-02-04 14:17:18 +08:00
李通洲 eed5efabea Camera (Windows): detect color space 2024-02-04 14:17:18 +08:00
李通洲 d2315e967e Camera (macOS): detect color space 2024-02-04 14:17:18 +08:00
Carter Li cbe3c70480 Camera (Linux): add property colorspace 2024-02-04 14:17:18 +08:00
李通洲 c918226909 Fastfetch: print videodev2 in --list-features 2024-02-04 09:56:22 +08:00
李通洲 18472660ae CI (FreeBSD): remove unused depenencies 2024-02-04 09:27:04 +08:00
李通洲 458c2ccd01 Camera (FreeBSD): enable support
Requires build dependency `v4l_compat`
2024-02-04 09:26:19 +08:00
李通洲 7bb9efcebb Camera (Android): init support 2024-02-02 23:22:40 +08:00
李通洲 8a42dfd68d Camera: tidy; add module to all.jsonc 2024-02-02 22:43:01 +08:00
李通洲 3edd8a6740 Camera (Linux): init support 2024-02-02 22:14:25 +08:00
李通洲 cba22b7155 Camera (Windows): init support 2024-02-02 20:36:22 +08:00
李通洲 246ad6d288 Sound (Windows): tidy 2024-02-02 20:36:22 +08:00
李通洲 295e119810 Camera (macOS): new module 2024-02-02 20:36:22 +08:00
李通洲 cfe22f9524 Terminal (Linux): try fixing #707 (v2) 2024-02-01 17:56:40 +08:00
李通洲 de2c1d7786 CI: unify artifacts name (v2) 2024-02-01 16:00:33 +08:00
李通洲 7d74339aa0 CI: build in parallel 2024-02-01 15:43:56 +08:00
李通洲 7589e962c2 CI: unify artifact names 2024-02-01 15:25:05 +08:00
李通洲 9a189694f9 CI: silence more warnings 2024-02-01 15:24:07 +08:00
李通洲 4069fbfe7b CI: upgrade codeql-action 2024-02-01 15:02:37 +08:00
李通洲 7ccd886909 CI: build aarch64 binaries 2024-02-01 14:29:28 +08:00
李通洲 42957356b2 GPU: remove libpci related stuff 2024-02-01 13:38:15 +08:00
李通洲 9038cd32b2 Terminal (Linux): don't assume blackbox is build for flatpak 2024-02-01 09:14:06 +08:00
李通洲 128c3bfea6 TerminalShell (Linux): try supporting blackbox
Fix #707
2024-02-01 09:02:49 +08:00
李通洲 60ed822f6a GPU (Linux): fix detection in some cases 2024-01-31 18:58:48 +08:00
Carter Li 527ec1bc61 Logo (Builtin): add asahi2; make asahi logo actually work 2024-01-31 16:47:22 +08:00
Carter Li cbf203901b CPU (Linux): code refactor 2024-01-31 14:36:00 +08:00
Carter Li cf6f3dbe0c CI (Windows): fix build 2024-01-31 13:35:57 +08:00
Carter Li ab625497ce CPU (Linux): code refactor 2024-01-31 13:28:18 +08:00
Yussef Dalton 83532b68dd CPU (Linux): use marketing name on Asahi Linux 2024-01-31 11:02:41 +08:00
Carter Li cd2a1495b8 GPU (FreeBSD): use ffGPUParsePciIds 2024-01-31 10:39:09 +08:00
Carter Li b01d2bdd8c GPU (Linux): rewrite; drop libpci dependency 2024-01-31 10:20:49 +08:00
Carter Li 736d5316cc Merge pull request #705 from fastfetch-cli/dev
Release v2.7.1
2024-01-30 19:25:55 +08:00
李通洲 efe42a2c7d GPU: fix a copy-paste error 2024-01-30 18:54:26 +08:00
李通洲 ee07755139 Release: v2.7.1 2024-01-30 18:45:56 +08:00
李通洲 3d924eeadd Merge remote-tracking branch 'upstream/master' into dev 2024-01-30 18:27:24 +08:00
李通洲 aaa091f23b Terminal (Linux): fix segfault 2024-01-30 15:22:26 +08:00
李通洲 53cd1e5378 DateTime: print timezone info; simplify code 2024-01-29 22:01:54 +08:00
李通洲 3747683f0d GPU: add vendor code of QTI & MTK 2024-01-29 21:49:42 +08:00
李通洲 59c1e3d8c5 Platform: detect real path of exe path 2024-01-28 10:45:21 +08:00
Carter Li 1206f6d2ba Merge pull request #701 from fastfetch-cli/dev
Release v2.7.0
2024-01-26 11:06:32 +08:00
李通洲 9aad3e339a CMake: remove unused deps 2024-01-26 10:44:20 +08:00
李通洲 ef9221f305 CI: generate sha512sums [no ci] 2024-01-26 10:41:31 +08:00
李通洲 391a3a0430 Release: v2.7.0
Bump minor version because of rewriting the FreeBSD GPU detection code
2024-01-26 10:23:44 +08:00
李通洲 6b0314f14b Platform: fix exe path detection 2024-01-26 10:19:21 +08:00
李通洲 8e316eb080 Release: v2.6.4 2024-01-26 10:10:11 +08:00
李通洲 999f2170fe Terminal: ignore sshd 2024-01-26 09:53:12 +08:00
李通洲 0282b884cc OpenCL: fix possible segfaults
Found in Alpine Linux
2024-01-26 09:38:08 +08:00
李通洲 ef7e6d0a6a GPU (WSL): fix uninitialized variables 2024-01-26 09:20:58 +08:00
李通洲 77253a8d81 GPU (FreeBSD): better name detection 2024-01-26 09:20:58 +08:00
Carter Li 2041272f5f GPU (Linux): simpify code 2024-01-25 18:32:40 +08:00
Carter Li d2a41bdfe1 GPU (FreeBSD): drop pciutils dep 2024-01-25 10:33:06 +08:00
Carter Li 025a708ecb Shell: remove trailing \0 in JSON output 2024-01-25 10:33:06 +08:00
John Mertz 4e2c124442 ASCII logos for fedora immutable variants (#700)
Container Linux is also deprecated and continued as Fedora CoreOS
2024-01-23 23:38:41 -06:00
李通洲 79ba9d7a68 TerminalShell (Linux): fix segfault 2024-01-23 18:51:00 +08:00
李通洲 ee60ec3530 TerminalShell: don't detect sh as a terminal 2024-01-23 16:38:43 +08:00
李通洲 9d7cbb0fe3 Revert "3rdparty: use a newer wcwidch implementation"
Unwanted change

This reverts commit 28ea765f19.
2024-01-23 14:42:00 +08:00
李通洲 0b98a14977 Fastfetch: don't expand envs in --config
Since it can only be used in command line
2024-01-23 13:14:53 +08:00
李通洲 8f51763374 Linux: allow command substitution when expanding paths
Ref: https://github.com/fastfetch-cli/fastfetch/discussions/698
2024-01-23 13:13:30 +08:00
李通洲 28ea765f19 3rdparty: use a newer wcwidch implementation 2024-01-23 10:19:02 +08:00
李通洲 5378d05bfb Doc: update changelog 2024-01-22 19:33:27 +08:00
李通洲 bbf04f0d40 Doc: add TerminalTheme 2024-01-22 18:50:11 +08:00
李通洲 ec6195133b TerminalTheme: add new module 2024-01-22 16:40:27 +08:00
李通洲 fa8c99601c TerminalSize: tidy 2024-01-22 14:34:19 +08:00
李通洲 a5d5de90f8 Terminal (Linux): support screen version detection 2024-01-22 14:33:55 +08:00
李通洲 994fd359a5 Terminal (Linux): fix kgx version detection 2024-01-22 11:10:40 +08:00
李通洲 a9a5790cba TerminalShell (Linux): improve terminal detection by env 2024-01-22 11:10:40 +08:00
李通洲 31b3fe403a Wifi (Linux): remove trailing \n
Fix #697
2024-01-22 11:10:30 +08:00
李通洲 14b74fe51d Doc: update issue template 2024-01-22 09:10:03 +08:00
74 changed files with 1970 additions and 568 deletions
+4 -1
View File
@@ -19,7 +19,10 @@ assignees: ''
# Often helpful information: # Often helpful information:
The content of the configuration file you use (if any) Screenshot:
<!-- Paste the screenshot here -->
The content of the configuration file you use (if any):
``` ```
//paste here //paste here
``` ```
+154 -57
View File
@@ -10,7 +10,7 @@ jobs:
steps: steps:
- name: checkout repository - name: checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Install codespell - name: Install codespell
shell: bash shell: bash
@@ -26,7 +26,6 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-22.04, ubuntu-20.04]
compiler: [ compiler: [
{ cc: gcc, cxx: "g++" }, { cc: gcc, cxx: "g++" },
{ cc: clang, cxx: "clang++" }, { cc: clang, cxx: "clang++" },
@@ -37,7 +36,7 @@ jobs:
# The feature libraries are all build against glibc, so they can't be used with musl # The feature libraries are all build against glibc, so they can't be used with musl
- compiler: { cc: "musl-gcc", cxx: "musl-g++" } - compiler: { cc: "musl-gcc", cxx: "musl-g++" }
enableFeatures: ON enableFeatures: ON
runs-on: ${{ matrix.os }} runs-on: ubuntu-22.04
steps: steps:
- name: checkout repository - name: checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -46,16 +45,16 @@ jobs:
run: uname -a run: uname -a
- name: install required packages - name: install required packages
run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev libdrm-dev run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libddcutil-dev libchafa-dev libdrm-dev directx-headers-dev
- name: configure project - name: configure project
env: env:
CC: ${{ matrix.compiler.cc }} CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }} CXX: ${{ matrix.compiler.cxx }}
run: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LIBPCI=${{ matrix.enableFeatures }} -DENABLE_VULKAN=${{ matrix.enableFeatures }} -DENABLE_WAYLAND=${{ matrix.enableFeatures }} -DENABLE_XCB_RANDR=${{ matrix.enableFeatures }} -DENABLE_XCB=${{ matrix.enableFeatures }} -DENABLE_XRANDR=${{ matrix.enableFeatures }} -DENABLE_X11=${{ matrix.enableFeatures }} -DENABLE_GIO=${{ matrix.enableFeatures }} -DENABLE_DCONF=${{ matrix.enableFeatures }} -DENABLE_DBUS=${{ matrix.enableFeatures }} -DENABLE_XFCONF=${{ matrix.enableFeatures }} -DENABLE_SQLITE3=${{ matrix.enableFeatures }} -DENABLE_RPM=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK7=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK6=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} -DENABLE_ZLIB=${{ matrix.enableFeatures }} -DENABLE_EGL=${{ matrix.enableFeatures }} -DENABLE_GLX=${{ matrix.enableFeatures }} -DENABLE_OSMESA=${{ matrix.enableFeatures }} -DENABLE_OPENCL=${{ matrix.enableFeatures }} -DENABLE_LIBNM=${{ matrix.enableFeatures }} -DENABLE_PULSE=${{ matrix.enableFeatures }} -DENABLE_DIRECTX_HEADERS=${{ matrix.enableFeatures }} -DENABLE_DRM=${{ matrix.enableFeatures }} . run: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_VULKAN=${{ matrix.enableFeatures }} -DENABLE_WAYLAND=${{ matrix.enableFeatures }} -DENABLE_XCB_RANDR=${{ matrix.enableFeatures }} -DENABLE_XCB=${{ matrix.enableFeatures }} -DENABLE_XRANDR=${{ matrix.enableFeatures }} -DENABLE_X11=${{ matrix.enableFeatures }} -DENABLE_GIO=${{ matrix.enableFeatures }} -DENABLE_DCONF=${{ matrix.enableFeatures }} -DENABLE_DBUS=${{ matrix.enableFeatures }} -DENABLE_XFCONF=${{ matrix.enableFeatures }} -DENABLE_SQLITE3=${{ matrix.enableFeatures }} -DENABLE_RPM=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK7=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK6=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} -DENABLE_ZLIB=${{ matrix.enableFeatures }} -DENABLE_EGL=${{ matrix.enableFeatures }} -DENABLE_GLX=${{ matrix.enableFeatures }} -DENABLE_OSMESA=${{ matrix.enableFeatures }} -DENABLE_OPENCL=${{ matrix.enableFeatures }} -DENABLE_LIBNM=${{ matrix.enableFeatures }} -DENABLE_PULSE=${{ matrix.enableFeatures }} -DENABLE_DIRECTX_HEADERS=${{ matrix.enableFeatures }} -DENABLE_DRM=${{ matrix.enableFeatures }} -DENABLE_DDCUTIL=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} .
- name: build project - name: build project
run: cmake --build . run: cmake --build . --verbose -j4
- name: run tests - name: run tests
run: ctest run: ctest
@@ -72,9 +71,68 @@ jobs:
- name: run flashfetch - name: run flashfetch
run: time ./flashfetch run: time ./flashfetch
linux: Linux-old-amd64:
name: Linux name: Linux-old-amd64
runs-on: ubuntu-20.04 # 22.04 ships a newer version of glibc than debian stable, allow those people to use the debian package runs-on: ubuntu-20.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: uname -a
run: uname -a
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev directx-headers-dev
- name: install linuxbrew packages
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa ddcutil --ignore-dependencies
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: c
- name: configure project
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
- name: perform CodeQL analysis
uses: github/codeql-action/analyze@v3
- name: list features
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-linux-old-amd64
path: ./fastfetch-*.*
linux-amd64:
name: Linux-amd64
runs-on: ubuntu-22.04 # Ubuntu 22.04 uses Glibc 2.35. Should be fine with Debian 12, which uses Glibc 2.36 (https://packages.debian.org/source/bookworm/glibc)
permissions: permissions:
security-events: write security-events: write
contents: read contents: read
@@ -88,15 +146,15 @@ jobs:
run: uname -a run: uname -a
- name: install required packages - name: install required packages
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev directx-headers-dev run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev directx-headers-dev
- name: install linuxbrew packages - name: install linuxbrew packages
run: | run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick ddcutil --ignore-dependencies /home/linuxbrew/.linuxbrew/bin/brew install imagemagick --ignore-dependencies
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: c languages: c
@@ -104,10 +162,10 @@ jobs:
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project - name: build project
run: cmake --build . --target package --verbose run: cmake --build . --target package --verbose -j4
- name: perform CodeQL analysis - name: perform CodeQL analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3
- name: list features - name: list features
run: ./fastfetch --list-features run: ./fastfetch --list-features
@@ -134,11 +192,46 @@ jobs:
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: fastfetch-linux name: fastfetch-linux-amd64
path: ./fastfetch-*.* path: ./fastfetch-*.*
macos: linux-aarch64:
name: MacOS name: Linux-aarch64
runs-on: ubuntu-22.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: run VM
uses: uraimo/run-on-arch-action@v2
id: runcmd
with:
arch: aarch64
distro: ubuntu22.04
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev directx-headers-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-linux-aarch64
path: ./fastfetch-*.*
macos-universal:
name: macOS-universal
runs-on: macos-latest runs-on: macos-latest
permissions: permissions:
security-events: write security-events: write
@@ -156,7 +249,7 @@ jobs:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: c languages: c
@@ -164,10 +257,10 @@ jobs:
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' . run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' .
- name: build project - name: build project
run: cmake --build . --target package --verbose run: cmake --build . --target package --verbose -j4
- name: perform CodeQL analysis - name: perform CodeQL analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3
- name: list features - name: list features
run: ./fastfetch --list-features run: ./fastfetch --list-features
@@ -190,11 +283,11 @@ jobs:
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: fastfetch-macos name: fastfetch-macos-universal
path: ./fastfetch-*.* path: ./fastfetch-*.*
freebsd: freebsd-amd64:
name: FreeBSD name: FreeBSD-amd64
runs-on: macos-12 runs-on: macos-12
permissions: permissions:
security-events: write security-events: write
@@ -211,9 +304,9 @@ jobs:
run: | run: |
uname -a uname -a
sudo pkg update sudo pkg update
sudo pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd v4l_compat
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose cmake --build . --target package --verbose -j4
./fastfetch --list-features ./fastfetch --list-features
time ./fastfetch time ./fastfetch
time ./fastfetch --format json time ./fastfetch --format json
@@ -224,11 +317,11 @@ jobs:
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: fastfetch-freebsd name: fastfetch-freebsd-amd64
path: ./fastfetch-*.* path: ./fastfetch-*.*
win64: windows-amd64:
name: Win64 name: Windows-amd64
runs-on: windows-latest runs-on: windows-latest
permissions: permissions:
security-events: write security-events: write
@@ -254,7 +347,7 @@ jobs:
run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
- name: build project - name: build project
run: cmake --build . --verbose run: cmake --build . --verbose -j4
- name: copy necessary dlls - name: copy necessary dlls
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll . run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
@@ -278,19 +371,19 @@ jobs:
run: ctest run: ctest
- name: create zip archive - name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win64.zip *.dll fastfetch.exe flashfetch.exe presets run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-windows-amd64.zip *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive - name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win64.7z *.dll fastfetch.exe flashfetch.exe presets run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-windows-amd64.7z *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: fastfetch-win64 name: fastfetch-windows-amd64
path: ./fastfetch-*-Win64.* path: ./fastfetch-*-windows-amd64.*
win32: windows-i686:
name: Win32 name: Windows-i686
runs-on: windows-latest runs-on: windows-latest
permissions: permissions:
security-events: write security-events: write
@@ -313,7 +406,7 @@ jobs:
run: uname -a run: uname -a
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: c, cpp languages: c, cpp
@@ -321,10 +414,10 @@ jobs:
run: env PKG_CONFIG_PATH=/clang32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . run: env PKG_CONFIG_PATH=/clang32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
- name: build project - name: build project
run: cmake --build . --verbose run: cmake --build . --verbose -j4
- name: perform CodeQL analysis - name: perform CodeQL analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3
- name: copy necessary dlls - name: copy necessary dlls
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll . run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
@@ -345,27 +438,28 @@ jobs:
run: ctest run: ctest
- name: create zip archive - name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win32.zip *.dll fastfetch.exe flashfetch.exe presets run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-windows-i686.zip *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive - name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win32.7z *.dll fastfetch.exe flashfetch.exe presets run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-windows-i686.7z *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts - name: upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: fastfetch-win32 name: fastfetch-windows-i686
path: ./fastfetch-*-Win32.* path: ./fastfetch-*-windows-i686.*
release: release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch' if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
name: Release name: Release
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
- linux - linux-amd64
- macos - linux-aarch64
- freebsd - macos-universal
- win64 - freebsd-amd64
- win32 - windows-amd64
- windows-i686
permissions: permissions:
contents: write contents: write
steps: steps:
@@ -376,38 +470,41 @@ jobs:
repository: ${{ github.repository }} repository: ${{ github.repository }}
- name: download artifacts - name: download artifacts
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
- name: create release - name: create release
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
tag: ${{ needs.linux.outputs.ffversion }} tag: ${{ needs.linux-amd64.outputs.ffversion }}
commit: ${{ github.sha }} commit: ${{ github.sha }}
artifactErrorsFailBuild: true artifactErrorsFailBuild: true
artifacts: fastfetch-*/fastfetch-* artifacts: fastfetch-*/fastfetch-*
body: "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux.outputs.ffversion }}/CHANGELOG.md) for details." body: "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-amd64.outputs.ffversion }}/CHANGELOG.md) for details."
- name: download source tarballs - name: download source tarballs
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
run: | run: |
for i in 1 2 3 4 5; do curl -L --remote-name-all --output-dir fastfetch-source --create-dirs https://github.com/${{ github.repository }}/archive/refs/tags/${{ needs.linux.outputs.ffversion }}.{tar.gz,zip} && break || sleep 5; done for i in 1 2 3 4 5; do curl -L --remote-name-all --output-dir fastfetch-source --create-dirs https://github.com/${{ github.repository }}/archive/refs/tags/${{ needs.linux-amd64.outputs.ffversion }}.{tar.gz,zip} && break || sleep 5; done
ls fastfetch-*/* ls fastfetch-*/*
- name: generate release notes - name: generate release notes
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
run: | run: |
echo "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux.outputs.ffversion }}/CHANGELOG.md) for details." > fastfetch-release-notes.md echo "Please refer to [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ needs.linux-amd64.outputs.ffversion }}/CHANGELOG.md) for details." > fastfetch-release-notes.md
echo -e "\n---\n\n<details><summary>SHA256SUMs</summary><br>\n\n\`\`\`" >> fastfetch-release-notes.md echo -e "\n---\n\n<details><summary>SHA256SUMs</summary><br>\n\n\`\`\`" >> fastfetch-release-notes.md
sha256sum fastfetch-*/* >> fastfetch-release-notes.md sha256sum fastfetch-*/* >> fastfetch-release-notes.md
echo -e "\`\`\`\n</details>" >> fastfetch-release-notes.md echo -e "\`\`\`\n</details>" >> fastfetch-release-notes.md
echo -e "\n<details><summary>SHA512SUMs</summary><br>\n\n\`\`\`" >> fastfetch-release-notes.md
sha512sum fastfetch-*/* >> fastfetch-release-notes.md
echo -e "\`\`\`\n</details>" >> fastfetch-release-notes.md
- name: update release body - name: update release body
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
tag: ${{ needs.linux.outputs.ffversion }} tag: ${{ needs.linux-amd64.outputs.ffversion }}
commit: ${{ github.sha }} commit: ${{ github.sha }}
bodyFile: fastfetch-release-notes.md bodyFile: fastfetch-release-notes.md
allowUpdates: true allowUpdates: true
+45
View File
@@ -1,3 +1,48 @@
# 2.8.1
Changes:
* The linux binaries are now built with glibc 2.35, which means they no longer support Debian 11 and Ubuntu 20.04. Users using these distros may download the artifacts `fastfetch-linux-old` from GitHub Actions.
Features:
* Rewrite GPU module, drop libpci dependency (GPU, Linux)
* Detect marketing name of Apple Silicon CPUs for asahi linux (CPU, Linux)
* Add new module `Camera`, which prints the name and resolution of connected cameras
Bugfixes:
* Fix compatibility with packages installed by flatpak (Terminal, Linux)
* Don't show an empty battery if no battery is detected (macOS, Battery)
* Don't show `not connected` if no power adapter is found (macOS / Linux, PowerAdapter)
* Make format of battery status be consistent with other platforms (Linux, Battery)
Logo:
* Print Asahi logo in asahi linux (Logo, Linux)
* Add Asahi2, z/OS, Tatra, PikaOS
# 2.7.1
Features:
* Config presets in app folder now work with symlinks
Bugfixes:
* Fix a possible segfault when detecting terminal (Terminal, Linux)
# 2.7.0
Features:
* Add new module `TerminalTheme`, which prints the foreground and background color of the current terminal window. Currently doesn't work on Windows.
* Allow command substitution when expanding paths. For example, now it's possible to use `"source": "$(ls ~/path/to/images/*.png | shuf -n 1)"` in JSONC config file to randomly choose an image to display. (#698)
* Use native methods instead of pciutils to detect GPUs in FreeBSD. (GPU, FreeBSD)
Bugfixes:
* Fix text formatting (Wifi, Linux)
* Fix terminal detection in some cases (Terminal)
* Remove trailing `\0` in JSON results (FreeBSD)
* Fix uninitialized variables (GPU, Linux)
* Fix a possible segfault (OpenCL)
Logo:
* Add ASCII logos for fedora immutable variants (#700)
# 2.6.3 # 2.6.3
Bugfixes: Bugfixes:
+18 -9
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch project(fastfetch
VERSION 2.6.3 VERSION 2.8.1
LANGUAGES C LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool" DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -42,7 +42,6 @@ include(CheckIncludeFile)
include(CMakeDependentOption) include(CMakeDependentOption)
cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF) cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF) cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF)
@@ -70,7 +69,6 @@ cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF) cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF) cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF) cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_PCI_MEMORY "Enable detecting GPU memory size with libpci" OFF "LINUX OR BSD" OFF)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF) option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF) option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
@@ -293,6 +291,7 @@ set(LIBFASTFETCH_SRC
src/detection/os/os.c src/detection/os/os.c
src/detection/packages/packages.c src/detection/packages/packages.c
src/detection/publicip/publicip.c src/detection/publicip/publicip.c
src/detection/terminaltheme/terminaltheme.c
src/detection/terminalfont/terminalfont.c src/detection/terminalfont/terminalfont.c
src/detection/terminalshell/terminalshell.c src/detection/terminalshell/terminalshell.c
src/detection/version/version.c src/detection/version/version.c
@@ -309,6 +308,7 @@ set(LIBFASTFETCH_SRC
src/modules/board/board.c src/modules/board/board.c
src/modules/brightness/brightness.c src/modules/brightness/brightness.c
src/modules/break/break.c src/modules/break/break.c
src/modules/camera/camera.c
src/modules/chassis/chassis.c src/modules/chassis/chassis.c
src/modules/colors/colors.c src/modules/colors/colors.c
src/modules/cpu/cpu.c src/modules/cpu/cpu.c
@@ -348,6 +348,7 @@ set(LIBFASTFETCH_SRC
src/modules/swap/swap.c src/modules/swap/swap.c
src/modules/media/media.c src/modules/media/media.c
src/modules/terminal/terminal.c src/modules/terminal/terminal.c
src/modules/terminaltheme/terminaltheme.c
src/modules/terminalfont/terminalfont.c src/modules/terminalfont/terminalfont.c
src/modules/terminalsize/terminalsize.c src/modules/terminalsize/terminalsize.c
src/modules/theme/theme.c src/modules/theme/theme.c
@@ -432,6 +433,7 @@ if(LINUX)
src/detection/wm/wm_nosupport.c src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/util/platform/FFPlatform_unix.c src/util/platform/FFPlatform_unix.c
) )
elseif(ANDROID) elseif(ANDROID)
@@ -485,6 +487,7 @@ elseif(ANDROID)
src/detection/wm/wm_nosupport.c src/detection/wm/wm_nosupport.c
src/detection/de/de_nosupport.c src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c src/detection/wmtheme/wmtheme_nosupport.c
src/detection/camera/camera_android.c
src/util/platform/FFPlatform_unix.c src/util/platform/FFPlatform_unix.c
) )
elseif(BSD) elseif(BSD)
@@ -514,7 +517,7 @@ elseif(BSD)
src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c src/detection/font/font_linux.c
src/detection/gpu/gpu_linux.c src/detection/gpu/gpu_bsd.c
src/detection/gtk_qt/gtk.c src/detection/gtk_qt/gtk.c
src/detection/host/host_bsd.c src/detection/host/host_bsd.c
src/detection/lm/lm_linux.c src/detection/lm/lm_linux.c
@@ -547,6 +550,7 @@ elseif(BSD)
src/detection/wm/wm_nosupport.c src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/util/platform/FFPlatform_unix.c src/util/platform/FFPlatform_unix.c
) )
elseif(APPLE) elseif(APPLE)
@@ -602,6 +606,7 @@ elseif(APPLE)
src/detection/wm/wm_apple.c src/detection/wm/wm_apple.c
src/detection/de/de_nosupport.c src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m src/detection/wmtheme/wmtheme_apple.m
src/detection/camera/camera_apple.m
src/util/apple/cf_helpers.c src/util/apple/cf_helpers.c
src/util/apple/osascript.m src/util/apple/osascript.m
src/util/platform/FFPlatform_unix.c src/util/platform/FFPlatform_unix.c
@@ -657,6 +662,7 @@ elseif(WIN32)
src/detection/wm/wm_windows.cpp src/detection/wm/wm_windows.cpp
src/detection/de/de_nosupport.c src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_windows.c src/detection/wmtheme/wmtheme_windows.c
src/detection/camera/camera_windows.cpp
src/util/windows/getline.c src/util/windows/getline.c
src/util/windows/com.cpp src/util/windows/com.cpp
src/util/windows/registry.c src/util/windows/registry.c
@@ -790,10 +796,6 @@ function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
endforeach() endforeach()
endfunction() endfunction()
ff_lib_enable(LIBPCI
"libpci"
"Pci"
)
ff_lib_enable(VULKAN ff_lib_enable(VULKAN
"vulkan" "vulkan"
"Vulkan" "Vulkan"
@@ -916,9 +918,11 @@ if(LINUX)
) )
elseif(APPLE) elseif(APPLE)
target_link_libraries(libfastfetch target_link_libraries(libfastfetch
PRIVATE "-framework AVFoundation"
PRIVATE "-framework Cocoa" PRIVATE "-framework Cocoa"
PRIVATE "-framework CoreFoundation" PRIVATE "-framework CoreFoundation"
PRIVATE "-framework CoreAudio" PRIVATE "-framework CoreAudio"
PRIVATE "-framework CoreMedia"
PRIVATE "-framework CoreVideo" PRIVATE "-framework CoreVideo"
PRIVATE "-framework CoreWLAN" PRIVATE "-framework CoreWLAN"
PRIVATE "-framework IOBluetooth" PRIVATE "-framework IOBluetooth"
@@ -1103,6 +1107,11 @@ install(
################## ##################
set(CPACK_GENERATOR "TGZ;ZIP") set(CPACK_GENERATOR "TGZ;ZIP")
if(APPLE)
string(TOLOWER "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-macos-universal" CPACK_PACKAGE_FILE_NAME)
else() # We don't use this in Windows
string(TOLOWER "${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}" CPACK_PACKAGE_FILE_NAME)
endif()
if(LINUX) if(LINUX)
set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB;RPM") set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB;RPM")
@@ -1119,7 +1128,7 @@ set(CPACK_SET_DESTDIR ON)
set(CPACK_PACKAGE_CONTACT "Linus Dierheimer <Linus@Dierheimer.de>") set(CPACK_PACKAGE_CONTACT "Linus Dierheimer <Linus@Dierheimer.de>")
set(CPACK_PACKAGE_DESCRIPTION "\ set(CPACK_PACKAGE_DESCRIPTION "\
fastfetch is a neofetch-like tool for fetching system information and displaying them in a pretty way. \ fastfetch is a neofetch-like tool for fetching system information and displaying them in a pretty way. \
It is written in c to achieve much better performance.\ It is written mostly in C to achieve much better performance.\
") ")
include(CPack) include(CPack)
+18
View File
@@ -0,0 +1,18 @@
fastfetch (2.7.1ubuntu2) jammy; urgency=medium
* Ignore .git
-- Carter Li <zhangsongcui@live.cn> Wed, 07 Feb 2024 14:23:23 +0800
fastfetch (2.7.1ubuntu1) jammy; urgency=medium
* Update build scripts
-- Carter Li <zhangsongcui@live.cn> Wed, 07 Feb 2024 13:53:37 +0800
fastfetch (2.7.1) jammy; urgency=medium
* Initial release.
-- Carter Li <zhangsongcui@live.cn> Tue, 06 Feb 2024 15:01:11 +0800
+1
View File
@@ -0,0 +1 @@
12
+13
View File
@@ -0,0 +1,13 @@
Source: fastfetch
Section: universe/utils
Priority: optional
Maintainer: Carter Li <zhangsongcui@live.cn>
Build-Depends: libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libxfconf-0-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, libosmesa6-dev, ocl-icd-opencl-dev, libnm-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, directx-headers-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build
Standards-Version: 4.0.0
Homepage: https://github.com/fastfetch-cli/fastfetch
Package: fastfetch
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Fastfetch is a neofetch-like tool for fetching system information and displaying them in a pretty way.
It is written mainly in C, with performance and customizability in mind.
+11
View File
@@ -0,0 +1,11 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: fastfetch
Source: https://github.com/fastfetch-cli/fastfetch
Files: *
Copyright: 2024 fastfetch-cli
License: Expat
Files: src/3rdparty/yyjson/*
Copyright: 2020 YaoYuan
License: Expat
+1
View File
@@ -0,0 +1 @@
fastfetch_2.7.1ubuntu2_source.buildinfo universe/utils optional
Vendored Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
debuild -S -i -I
dput ppa:zhangsongcui3371/fastfetch ~/fastfetch_*.changes
Vendored Executable
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/make -f
%:
dh $@ --buildsystem=cmake+ninja
override_dh_ctest_configure:
dh_ctest_configure -- -DSET_TWEAK=OFF -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
+4
View File
@@ -0,0 +1,4 @@
version=4
opts="filenamemangle=s%.*/@ANY_VERSION@%@PACKAGE@-$1.tar.gz%,searchmode=plain" \
https://api.github.com/repos/fastfetch-cli/fastfetch/releases?per_page=100 \
https://api.github.com/repos/fastfetch-cli/fastfetch/tarball/@ANY_VERSION@
+5
View File
@@ -648,6 +648,7 @@
"terminal", "terminal",
"terminalfont", "terminalfont",
"terminalsize", "terminalsize",
"terminaltheme",
"title", "title",
"theme", "theme",
"uptime", "uptime",
@@ -772,6 +773,10 @@
"const": "terminalsize", "const": "terminalsize",
"description": "Print current terminal size" "description": "Print current terminal size"
}, },
{
"const": "terminaltheme",
"description": "Print current terminal theme (foreground and background colors)"
},
{ {
"const": "theme", "const": "theme",
"description": "Print current theme of desktop environment" "description": "Print current theme of desktop environment"
+2
View File
@@ -28,6 +28,7 @@
"terminal", "terminal",
"terminalfont", "terminalfont",
"terminalsize", "terminalsize",
"terminaltheme",
"cpu", "cpu",
"cpuusage", "cpuusage",
"gpu", "gpu",
@@ -49,6 +50,7 @@
"users", "users",
"bluetooth", "bluetooth",
"sound", "sound",
"camera",
"gamepad", "gamepad",
"weather", "weather",
"netio", "netio",
+2
View File
@@ -34,6 +34,7 @@
"terminal", "terminal",
"terminalfont", "terminalfont",
"terminalsize", "terminalsize",
"terminaltheme",
"cpu", "cpu",
"cpuusage", "cpuusage",
"gpu", "gpu",
@@ -55,6 +56,7 @@
"users", "users",
"bluetooth", "bluetooth",
"sound", "sound",
"camera",
"gamepad", "gamepad",
{ {
"type": "weather", "type": "weather",
+3 -3
View File
@@ -163,9 +163,6 @@ void ffListFeatures(void)
#ifdef FF_HAVE_THREADS #ifdef FF_HAVE_THREADS
"threads\n" "threads\n"
#endif #endif
#ifdef FF_HAVE_LIBPCI
"libpci\n"
#endif
#ifdef FF_HAVE_VULKAN #ifdef FF_HAVE_VULKAN
"vulkan\n" "vulkan\n"
#endif #endif
@@ -241,6 +238,9 @@ void ffListFeatures(void)
#ifdef FF_HAVE_DDCUTIL #ifdef FF_HAVE_DDCUTIL
"libddcutil\n" "libddcutil\n"
#endif #endif
#if __has_include(<linux/videodev2.h>)
"videodev2\n"
#endif
#ifdef FF_HAVE_DIRECTX_HEADERS #ifdef FF_HAVE_DIRECTX_HEADERS
"Directx Headers\n" "Directx Headers\n"
#endif #endif
+1 -1
View File
@@ -115,7 +115,7 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
#if __has_include(<wordexp.h>) // https://github.com/termux/termux-packages/pull/7056 #if __has_include(<wordexp.h>) // https://github.com/termux/termux-packages/pull/7056
wordexp_t exp; wordexp_t exp;
if(wordexp(in, &exp, WRDE_NOCMD) != 0) if(wordexp(in, &exp, 0) != 0)
return false; return false;
if (exp.we_wordc == 1) if (exp.we_wordc == 1)
+2
View File
@@ -15,6 +15,7 @@ static FFModuleBaseInfo* B[] = {
}; };
static FFModuleBaseInfo* C[] = { static FFModuleBaseInfo* C[] = {
(void*) &instance.config.modules.camera,
(void*) &instance.config.modules.chassis, (void*) &instance.config.modules.chassis,
(void*) &instance.config.modules.command, (void*) &instance.config.modules.command,
(void*) &instance.config.modules.colors, (void*) &instance.config.modules.colors,
@@ -124,6 +125,7 @@ static FFModuleBaseInfo* T[] = {
(void*) &instance.config.modules.terminal, (void*) &instance.config.modules.terminal,
(void*) &instance.config.modules.terminalFont, (void*) &instance.config.modules.terminalFont,
(void*) &instance.config.modules.terminalSize, (void*) &instance.config.modules.terminalSize,
(void*) &instance.config.modules.terminalTheme,
(void*) &instance.config.modules.title, (void*) &instance.config.modules.title,
(void*) &instance.config.modules.theme, (void*) &instance.config.modules.theme,
NULL, NULL,
+8 -10
View File
@@ -20,6 +20,14 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
if (IORegistryEntryCreateCFProperties(entryBattery, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) if (IORegistryEntryCreateCFProperties(entryBattery, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
continue; continue;
int currentCapacity, maxCapacity;
if (ffCfDictGetInt(properties, CFSTR(kIOPMPSMaxCapacityKey), &maxCapacity) != NULL || maxCapacity <= 0)
continue;
if (ffCfDictGetInt(properties, CFSTR(kIOPMPSCurrentCapacityKey), &currentCapacity) != NULL || currentCapacity <= 0)
continue;
bool boolValue; bool boolValue;
FFBatteryResult* battery = ffListAdd(results); FFBatteryResult* battery = ffListAdd(results);
@@ -30,16 +38,6 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
ffStrbufInit(&battery->technology); ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->status); ffStrbufInit(&battery->status);
ffStrbufInit(&battery->manufactureDate); ffStrbufInit(&battery->manufactureDate);
battery->capacity = 0.0/0.0;
int currentCapacity, maxCapacity;
if (ffCfDictGetInt(properties, CFSTR(kIOPMPSMaxCapacityKey), &maxCapacity) != NULL || maxCapacity <= 0)
continue;
if (ffCfDictGetInt(properties, CFSTR(kIOPMPSCurrentCapacityKey), &currentCapacity) != NULL || currentCapacity <= 0)
continue;
battery->capacity = currentCapacity * 100.0 / maxCapacity; battery->capacity = currentCapacity * 100.0 / maxCapacity;
ffCfDictGetString(properties, CFSTR(kIOPMDeviceNameKey), &battery->modelName); ffCfDictGetString(properties, CFSTR(kIOPMDeviceNameKey), &battery->modelName);
+2 -2
View File
@@ -54,13 +54,13 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
else if(battio.battinfo.state & ACPI_BATT_STAT_CHARGING) else if(battio.battinfo.state & ACPI_BATT_STAT_CHARGING)
ffStrbufAppendS(&battery->status, "Charging, "); ffStrbufAppendS(&battery->status, "Charging, ");
if(battio.battinfo.state & ACPI_BATT_STAT_CRITICAL) if(battio.battinfo.state & ACPI_BATT_STAT_CRITICAL)
ffStrbufAppendS(&battery->status, "Ctritical, "); ffStrbufAppendS(&battery->status, "Critical, ");
} }
int acadStatus; int acadStatus;
if (ioctl(acpifd, ACPIIO_ACAD_GET_STATUS, &acadStatus) >= 0 && acadStatus) if (ioctl(acpifd, ACPIIO_ACAD_GET_STATUS, &acadStatus) >= 0 && acadStatus)
{ {
ffStrbufAppendS(&battery->status, "AC connected"); ffStrbufAppendS(&battery->status, "AC Connected");
} }
else else
{ {
+22
View File
@@ -5,6 +5,8 @@
#include <dirent.h> #include <dirent.h>
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power
static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* options, FFlist* results) static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* options, FFlist* results)
{ {
uint32_t dirLength = dir->length; uint32_t dirLength = dir->length;
@@ -68,6 +70,26 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option
ffStrbufTrimRightSpace(&result->status); ffStrbufTrimRightSpace(&result->status);
ffStrbufSubstrBefore(dir, dirLength); ffStrbufSubstrBefore(dir, dirLength);
// Unknown, Charging, Discharging, Not charging, Full
if (ffStrbufEqualS(&result->status, "Not charging") || ffStrbufEqualS(&result->status, "Full"))
ffStrbufSetStatic(&result->status, "AC Connected");
else if (ffStrbufEqualS(&result->status, "Unknown"))
ffStrbufClear(&result->status);
ffStrbufAppendS(dir, "/capacity_level");
if (ffReadFileBuffer(dir->chars, &tmpBuffer))
{
ffStrbufTrimRightSpace(&result->manufacturer);
if (ffStrbufEqualS(&tmpBuffer, "Critical"))
{
if (result->status.length)
ffStrbufAppendS(&result->status, ", Critical");
else
ffStrbufSetStatic(&result->status, "Critical");
}
}
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufInit(&result->serial); ffStrbufInit(&result->serial);
ffStrbufAppendS(dir, "/serial_number"); ffStrbufAppendS(dir, "/serial_number");
if (ffReadFileBuffer(dir->chars, &result->serial)) if (ffReadFileBuffer(dir->chars, &result->serial))
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "fastfetch.h"
typedef struct FFCameraResult
{
FFstrbuf name;
FFstrbuf vendor;
FFstrbuf id;
FFstrbuf colorspace;
uint32_t width;
uint32_t height;
} FFCameraResult;
const char* ffDetectCamera(FFlist* result /* list of FFCameraResult */);
+61
View File
@@ -0,0 +1,61 @@
#include "camera.h"
#include "common/processing.h"
#include "common/properties.h"
#define FF_TERMUX_API_PATH FASTFETCH_TARGET_DIR_ROOT "/libexec/termux-api"
#define FF_TERMUX_API_PARAM "CameraInfo"
static inline void wrapYyjsonFree(yyjson_doc** doc)
{
assert(doc);
if (*doc)
yyjson_doc_free(*doc);
}
const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if(ffProcessAppendStdOut(&buffer, (char* const[]){
FF_TERMUX_API_PATH,
FF_TERMUX_API_PARAM,
NULL
}))
return "Starting `" FF_TERMUX_API_PATH " " FF_TERMUX_API_PARAM "` failed";
yyjson_doc* __attribute__((__cleanup__(wrapYyjsonFree))) doc = yyjson_read_opts(buffer.chars, buffer.length, 0, NULL, NULL);
if (!doc)
return "Failed to parse camera info";
yyjson_val* root = yyjson_doc_get_root(doc);
if (!yyjson_is_arr(root))
return "Camera info result is not a JSON array";
yyjson_val* device;
size_t idx, max;
yyjson_arr_foreach(root, idx, max, device)
{
FFCameraResult* camera = (FFCameraResult*) ffListAdd(result);
{
const char* facing = yyjson_get_str(yyjson_obj_get(device, "facing"));
if (facing)
ffStrbufInitF(&camera->name, "builtin-%s", facing);
else
ffStrbufInitStatic(&camera->name, "Unknown");
}
ffStrbufInit(&camera->vendor);
ffStrbufInitS(&camera->id, yyjson_get_str(yyjson_obj_get(device, "id")));
yyjson_val* sizes = yyjson_arr_get_first(yyjson_obj_get(device, "jpeg_output_sizes"));
if (yyjson_is_obj(sizes))
{
camera->width = (uint32_t) yyjson_get_uint(yyjson_obj_get(sizes, "width"));
camera->height = (uint32_t) yyjson_get_uint(yyjson_obj_get(sizes, "height"));
}
else
camera->width = camera->height = 0;
ffStrbufInit(&camera->colorspace);
}
return NULL;
}
+31
View File
@@ -0,0 +1,31 @@
#include "camera.h"
#import <AVFoundation/AVCaptureDevice.h>
const char* ffDetectCamera(FFlist* result)
{
AVCaptureDeviceDiscoverySession* session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
if (!session)
return "Failed to create AVCaptureDeviceDiscoverySession";
for (AVCaptureDevice* device in session.devices)
{
FFCameraResult* camera = (FFCameraResult*) ffListAdd(result);
ffStrbufInitS(&camera->name, device.localizedName.UTF8String);
ffStrbufInitS(&camera->vendor, device.manufacturer.UTF8String);
ffStrbufInitS(&camera->id, device.uniqueID.UTF8String);
switch (device.activeColorSpace)
{
case AVCaptureColorSpace_sRGB: ffStrbufInitStatic(&camera->colorspace, "sRGB"); break;
case AVCaptureColorSpace_P3_D65: ffStrbufInitStatic(&camera->colorspace, "P3-D65"); break;
case 2 /*AVCaptureColorSpace_HLG_BT2020*/: ffStrbufInitStatic(&camera->colorspace, "BT2020-HLG"); break;
case 3 /*AVCaptureColorSpace_AppleLog*/: ffStrbufInitStatic(&camera->colorspace, "AppleLog"); break;
}
CMVideoDimensions size = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription);
camera->width = size.width < 0 ? 0 : (uint32_t) size.width;
camera->height = size.height < 0 ? 0 : (uint32_t) size.height;
}
return NULL;
}
+61
View File
@@ -0,0 +1,61 @@
#include "camera.h"
#include "common/io/io.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#if __has_include(<linux/videodev2.h>)
#include <linux/videodev2.h>
#endif
const char* ffDetectCamera(FFlist* result)
{
#if __has_include(<linux/videodev2.h>)
char path[] = "/dev/videoN";
for (uint32_t i = 0; i <= 9; ++i)
{
path[sizeof(path) - 2] = (char) (i + '0');
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY);
if (fd < 0)
break;
struct v4l2_capability cap = {};
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0 || !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
continue;
struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0)
continue;
FFCameraResult* camera = (FFCameraResult*) ffListAdd(result);
ffStrbufInitS(&camera->name, (const char*) cap.card);
ffStrbufInit(&camera->vendor);
ffStrbufInitS(&camera->id, (const char*) cap.bus_info);
switch (fmt.fmt.pix.colorspace)
{
case V4L2_COLORSPACE_SMPTE170M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 170M"); break;
case V4L2_COLORSPACE_SMPTE240M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 240M"); break;
case V4L2_COLORSPACE_BT878: ffStrbufInitStatic(&camera->colorspace, "BT.808"); break;
case V4L2_COLORSPACE_470_SYSTEM_M: ffStrbufInitStatic(&camera->colorspace, "NTSC"); break;
case V4L2_COLORSPACE_470_SYSTEM_BG: ffStrbufInitStatic(&camera->colorspace, "EBU 3213"); break;
case V4L2_COLORSPACE_JPEG: ffStrbufInitStatic(&camera->colorspace, "JPEG"); break;
case V4L2_COLORSPACE_REC709:
case V4L2_COLORSPACE_SRGB: ffStrbufInitStatic(&camera->colorspace, "sRGB"); break;
case V4L2_COLORSPACE_OPRGB: ffStrbufInitStatic(&camera->colorspace, "Adobe RGB"); break;
case V4L2_COLORSPACE_BT2020: ffStrbufInitStatic(&camera->colorspace, "BT.2020"); break;
case V4L2_COLORSPACE_RAW: ffStrbufInitStatic(&camera->colorspace, "RAW"); break;
case V4L2_COLORSPACE_DCI_P3: ffStrbufInitStatic(&camera->colorspace, "DCI-P3"); break;
default: ffStrbufInit(&camera->colorspace); break;
}
camera->width = fmt.fmt.pix.width;
camera->height = fmt.fmt.pix.height;
}
return NULL;
#else
FF_UNUSED(result);
return "Fastfetch was compiled without <linux/videodev2.h>";
#endif
}
+129
View File
@@ -0,0 +1,129 @@
extern "C" {
#include "camera.h"
#include "common/library.h"
}
#include "util/windows/com.hpp"
#include "util/windows/unicode.hpp"
#include <initguid.h>
#include <mfapi.h>
#include <mfidl.h>
template <typename Fn>
struct on_scope_exit {
on_scope_exit(Fn &&fn): _fn(std::move(fn)) {}
~on_scope_exit() { this->_fn(); }
private:
Fn _fn;
};
extern "C"
const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
{
FF_LIBRARY_LOAD(mfplat, NULL, "dlopen mfplat" FF_LIBRARY_EXTENSION " failed", "mfplat" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(mfplat, MFCreateAttributes)
FF_LIBRARY_LOAD(mf, NULL, "dlopen mf" FF_LIBRARY_EXTENSION " failed", "mf" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(mf, MFEnumDeviceSources)
const char* error = ffInitCom();
if (error)
return error;
IMFAttributes* FF_AUTO_RELEASE_COM_OBJECT attrs = nullptr;
if (FAILED(ffMFCreateAttributes(&attrs, 1)))
return "MFCreateAttributes() failed";
if (FAILED(attrs->SetGUID(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
)))
return "SetGUID(MF_*) failed";
IMFActivate** devices = NULL;
uint32_t count;
if (FAILED(ffMFEnumDeviceSources(attrs, &devices, &count)))
return "MFEnumDeviceSources() failed";
for (uint32_t i = 0; i < count; i++)
{
IMFActivate* device = devices[i];
wchar_t buffer[256];
uint32_t length = 0;
if (FAILED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, buffer, sizeof(buffer), &length)) || length == 0)
continue;
FFCameraResult* camera = (FFCameraResult*) ffListAdd(result);
ffStrbufInitNWS(&camera->name, length, buffer);
ffStrbufInit(&camera->colorspace);
ffStrbufInit(&camera->vendor);
ffStrbufInit(&camera->id);
camera->width = 0;
camera->height = 0;
if (SUCCEEDED(device->GetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, buffer, sizeof(buffer), &length)) && length > 0)
ffStrbufSetNWS(&camera->id, length, buffer);
IMFMediaSource* FF_AUTO_RELEASE_COM_OBJECT source = nullptr;
if (FAILED(device->ActivateObject(IID_PPV_ARGS(&source))))
continue;
on_scope_exit destroySource([&] { source->Shutdown(); });
IMFPresentationDescriptor* FF_AUTO_RELEASE_COM_OBJECT pd = nullptr;
if (FAILED(source->CreatePresentationDescriptor(&pd)))
continue;
IMFStreamDescriptor* FF_AUTO_RELEASE_COM_OBJECT sd = NULL;
BOOL selected;
if (FAILED(pd->GetStreamDescriptorByIndex(0, &selected, &sd)))
continue;
IMFMediaTypeHandler* FF_AUTO_RELEASE_COM_OBJECT handler = NULL;
if (FAILED(sd->GetMediaTypeHandler(&handler)))
continue;
DWORD mediaTypeCount;
if (FAILED(handler->GetMediaTypeCount(&mediaTypeCount)))
continue;
// Assume first type is the maximum resolution
IMFMediaType* FF_AUTO_RELEASE_COM_OBJECT type = NULL;
for (DWORD idx = 0; SUCCEEDED(handler->GetMediaTypeByIndex(idx, &type)); ++idx)
{
GUID majorType;
if (FAILED(type->GetMajorType(&majorType)) || majorType != MFMediaType_Video)
continue;
MFVideoPrimaries primaries;
static_assert(sizeof(primaries) == sizeof(uint32_t), "");
if (SUCCEEDED(type->GetUINT32(MF_MT_VIDEO_PRIMARIES, (uint32_t*) &primaries)))
{
switch (primaries)
{
case MFVideoPrimaries_BT709: ffStrbufSetStatic(&camera->colorspace, "sRGB"); break;
case MFVideoPrimaries_BT470_2_SysM:
case MFVideoPrimaries_BT470_2_SysBG: ffStrbufSetStatic(&camera->colorspace, "NTSC"); break;
case MFVideoPrimaries_SMPTE170M: ffStrbufSetStatic(&camera->colorspace, "SMPTE 170M"); break;
case MFVideoPrimaries_SMPTE240M: ffStrbufSetStatic(&camera->colorspace, "SMPTE 240M"); break;
case MFVideoPrimaries_EBU3213: ffStrbufSetStatic(&camera->colorspace, "EBU 3213"); break;
case MFVideoPrimaries_SMPTE_C: ffStrbufSetStatic(&camera->colorspace, "SMPTE C"); break;
case MFVideoPrimaries_BT2020: ffStrbufSetStatic(&camera->colorspace, "BT.2020"); break;
case MFVideoPrimaries_XYZ: ffStrbufSetStatic(&camera->colorspace, "XYZ"); break;
case MFVideoPrimaries_DCI_P3: ffStrbufSetStatic(&camera->colorspace, "DCI-P3"); break;
case MFVideoPrimaries_ACES: ffStrbufSetStatic(&camera->colorspace, "ACES"); break;
default: break;
}
}
MFGetAttributeSize(type, MF_MT_FRAME_SIZE, &camera->width, &camera->height);
break;
}
}
CoTaskMemFree(devices);
return nullptr;
}
+71
View File
@@ -4,6 +4,7 @@
#include "common/properties.h" #include "common/properties.h"
#include "detection/temps/temps_linux.h" #include "detection/temps/temps_linux.h"
#include "util/mallocHelper.h" #include "util/mallocHelper.h"
#include "util/stringUtils.h"
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <stdlib.h> #include <stdlib.h>
@@ -34,6 +35,10 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
FF_AUTO_FREE char* line = NULL; FF_AUTO_FREE char* line = NULL;
size_t len = 0; size_t len = 0;
#ifdef __aarch64__
FF_STRBUF_AUTO_DESTROY implementer = ffStrbufCreate();
#endif
while(getline(&line, &len, cpuinfo) != -1) while(getline(&line, &len, cpuinfo) != -1)
{ {
//Stop after the first CPU //Stop after the first CPU
@@ -47,12 +52,36 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
ffParsePropLine(line, "cpu MHz :", cpuMHz) || ffParsePropLine(line, "cpu MHz :", cpuMHz) ||
ffParsePropLine(line, "isa :", cpuIsa) || ffParsePropLine(line, "isa :", cpuIsa) ||
ffParsePropLine(line, "uarch :", cpuUarch) || ffParsePropLine(line, "uarch :", cpuUarch) ||
#ifdef __aarch64__
(cpu->vendor.length == 0 && ffParsePropLine(line, "CPU implementer :", &implementer)) ||
#endif
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) //For MIPS (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) //For MIPS
); );
} }
#ifdef __aarch64__
// https://github.com/util-linux/util-linux/blob/2cd89de14549d2b2c079a4f8b73f75500d229fee/sys-utils/lscpu-arm.c#L286
if (cpu->vendor.length == 0 && implementer.length > 2 /* 0xX */)
{
uint32_t implId = (uint32_t) strtoul(implementer.chars, NULL, 16);
switch (implId)
{
case 0x41: ffStrbufSetStatic(&cpu->vendor, "ARM"); break;
case 0x42: ffStrbufSetStatic(&cpu->vendor, "Broadcom"); break;
case 0x48: ffStrbufSetStatic(&cpu->vendor, "HiSilicon"); break;
case 0x4e: ffStrbufSetStatic(&cpu->vendor, "Nvidia"); break;
case 0x51: ffStrbufSetStatic(&cpu->vendor, "Qualcomm"); break;
case 0x53: ffStrbufSetStatic(&cpu->vendor, "Samsung"); break;
case 0x61: ffStrbufSetStatic(&cpu->vendor, "Apple"); break;
case 0x69: ffStrbufSetStatic(&cpu->vendor, "Intel"); break;
}
}
#endif
return NULL; return NULL;
} }
@@ -121,6 +150,44 @@ static void parseIsa(FFstrbuf* cpuIsa)
} }
} }
void detectAsahi(FFCPUResult* cpu)
{
// In Asahi Linux, reading /proc/device-tree/compatible gives
// information on the device model. It consists of 3 NUL terminated
// strings, the second of which gives the actual SoC model. But it
// is not the marketing name, i.e. for M2 there is "apple,t8112" in
// the compatible string.
if (cpu->name.length == 0 && ffStrbufEqualS(&cpu->vendor, "Apple"))
{
char content[32];
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
if (length <= 0) return;
// get the second NUL terminated string
char* modelName = memchr(content, '\0', (size_t) length) + 1;
if (modelName - content < length && ffStrStartsWith(modelName, "apple,t"))
{
// https://github.com/AsahiLinux/docs/wiki/Codenames
switch (strtoul(modelName + strlen("apple,t"), NULL, 10))
{
case 8103: ffStrbufSetStatic(&cpu->name, "Apple M1"); break;
case 6000: ffStrbufSetStatic(&cpu->name, "Apple M1 Pro"); break;
case 6001: ffStrbufSetStatic(&cpu->name, "Apple M1 Max"); break;
case 6002: ffStrbufSetStatic(&cpu->name, "Apple M1 Ultra"); break;
case 8112: ffStrbufSetStatic(&cpu->name, "Apple M2"); break;
case 6020: ffStrbufSetStatic(&cpu->name, "Apple M2 Pro"); break;
case 6021: ffStrbufSetStatic(&cpu->name, "Apple M2 Max"); break;
case 6022: ffStrbufSetStatic(&cpu->name, "Apple M2 Ultra"); break;
case 8122: ffStrbufSetStatic(&cpu->name, "Apple M3"); break;
case 6030: ffStrbufSetStatic(&cpu->name, "Apple M3 Pro"); break;
case 6031:
case 6034: ffStrbufSetStatic(&cpu->name, "Apple M3 Max"); break;
default: ffStrbufSetStatic(&cpu->name, "Apple Silicon"); break;
}
}
}
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{ {
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET; cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
@@ -167,6 +234,10 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
detectAndroid(cpu); detectAndroid(cpu);
#endif #endif
#if defined(__linux__) && defined(__aarch64__)
detectAsahi(cpu);
#endif
if (cpu->name.length == 0) if (cpu->name.length == 0)
{ {
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
+78
View File
@@ -6,6 +6,8 @@ const char* FF_GPU_VENDOR_NAME_APPLE = "Apple";
const char* FF_GPU_VENDOR_NAME_AMD = "AMD"; const char* FF_GPU_VENDOR_NAME_AMD = "AMD";
const char* FF_GPU_VENDOR_NAME_INTEL = "Intel"; const char* FF_GPU_VENDOR_NAME_INTEL = "Intel";
const char* FF_GPU_VENDOR_NAME_NVIDIA = "NVIDIA"; const char* FF_GPU_VENDOR_NAME_NVIDIA = "NVIDIA";
const char* FF_GPU_VENDOR_NAME_QUALCOMM = "Qualcomm";
const char* FF_GPU_VENDOR_NAME_MTK = "MTK";
const char* FF_GPU_VENDOR_NAME_VMWARE = "VMware"; const char* FF_GPU_VENDOR_NAME_VMWARE = "VMware";
const char* FF_GPU_VENDOR_NAME_PARALLEL = "Parallel"; const char* FF_GPU_VENDOR_NAME_PARALLEL = "Parallel";
const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft"; const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
@@ -33,6 +35,10 @@ const char* ffGetGPUVendorString(unsigned vendorId)
return FF_GPU_VENDOR_NAME_INTEL; return FF_GPU_VENDOR_NAME_INTEL;
else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3)) else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3))
return FF_GPU_VENDOR_NAME_NVIDIA; return FF_GPU_VENDOR_NAME_NVIDIA;
else if(arrayContains((const unsigned[]) {0x5143}, vendorId, 1))
return FF_GPU_VENDOR_NAME_QUALCOMM;
else if(arrayContains((const unsigned[]) {0x14c3}, vendorId, 1))
return FF_GPU_VENDOR_NAME_MTK;
else if(arrayContains((const unsigned[]) {0x15ad}, vendorId, 1)) else if(arrayContains((const unsigned[]) {0x15ad}, vendorId, 1))
return FF_GPU_VENDOR_NAME_VMWARE; return FF_GPU_VENDOR_NAME_VMWARE;
else if(arrayContains((const unsigned[]) {0x1af4}, vendorId, 1)) else if(arrayContains((const unsigned[]) {0x1af4}, vendorId, 1))
@@ -112,3 +118,75 @@ const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result)
return "GPU detection failed"; return "GPU detection failed";
} }
#ifndef _WIN32
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
{
if (content->length)
{
char buffer[32];
uint32_t len = (uint32_t) snprintf(buffer, sizeof(buffer), "\n%04x ", vendor);
char* start = (char*) memmem(content->chars, content->length, buffer, len);
char* end = content->chars + content->length;
if (start)
{
start += len;
end = memchr(start, '\n', (uint32_t) (end - start));
if (!end)
end = content->chars + content->length;
if (!gpu->vendor.length)
ffStrbufSetNS(&gpu->vendor, (uint32_t) (end - start), start);
start = end; // point to '\n' of vendor
end = start + 1; // point to start of devices
// find the start of next vendor
while (end[0] == '\t' || end[0] == '#')
{
end = strchr(end, '\n');
if (!end)
{
end = content->chars + content->length;
break;
}
else
end++;
}
len = (uint32_t) snprintf(buffer, sizeof(buffer), "\n\t%04x ", device);
start = memmem(start, (size_t) (end - start), buffer, len);
if (start)
{
start += len;
end = memchr(start, '\n', (uint32_t) (end - start));
if (!end)
end = content->chars + content->length;
char* openingBracket = memchr(start, '[', (uint32_t) (end - start));
if (openingBracket)
{
openingBracket++;
char* closingBracket = memchr(openingBracket, ']', (uint32_t) (end - openingBracket));
if (closingBracket)
ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket);
}
if (!gpu->name.length)
ffStrbufSetNS(&gpu->name, (uint32_t) (end - start), start);
}
}
}
if (!gpu->name.length)
{
const char* subclassStr;
switch (subclass)
{
case 0 /*PCI_CLASS_DISPLAY_VGA*/: subclassStr = " (VGA compatible)"; break;
case 1 /*PCI_CLASS_DISPLAY_XGA*/: subclassStr = " (XGA compatible)"; break;
case 2 /*PCI_CLASS_DISPLAY_3D*/: subclassStr = " (3D)"; break;
default: subclassStr = ""; break;
}
ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr);
}
}
#endif
+4
View File
@@ -42,3 +42,7 @@ const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus); const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
const char* ffGetGPUVendorString(unsigned vendorId); const char* ffGetGPUVendorString(unsigned vendorId);
#ifndef _WIN32
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
#endif
+95
View File
@@ -0,0 +1,95 @@
#include "gpu_driver_specific.h"
#include "common/io/io.h"
#include "3rdparty/nvml/nvml.h"
#include "util/mallocHelper.h"
#include "common/io/io.h"
#include <dev/pci/pcireg.h>
#include <sys/pciio.h>
#include <fcntl.h>
#include <paths.h>
static bool loadPciIds(FFstrbuf* pciids)
{
// https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/pciconf/pathnames.h
ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", pciids);
if (pciids->length > 0) return true;
ffReadFileBuffer("/usr/share/pciids/pci.ids", pciids);
if (pciids->length > 0) return true;
return false;
}
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
FF_AUTO_CLOSE_FD int fd = open("/dev/pci", O_RDONLY, 0);
struct pci_conf confs[128];
struct pci_match_conf match = {
.pc_class = PCIC_DISPLAY,
.flags = PCI_GETCONF_MATCH_CLASS,
};
struct pci_conf_io pcio = {
.pat_buf_len = sizeof(match),
.num_patterns = 1,
.patterns = &match,
.match_buf_len = sizeof(confs),
.matches = confs,
};
if (ioctl(fd, PCIOCGETCONF, &pcio) < 0)
return "ioctl(fd, PCIOCGETCONF, &pc) failed";
if (pcio.status == PCI_GETCONF_ERROR)
return "ioctl(fd, PCIOCGETCONF, &pc) returned error";
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
loadPciIds(&pciids);
for (uint32_t i = 0; i < pcio.num_matches; ++i)
{
struct pci_conf* pc = &confs[i];
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(pc->pc_vendor));
ffStrbufInit(&gpu->name);
ffStrbufInitS(&gpu->driver, pc->pd_name);
ffStrbufInit(&gpu->platformApi);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->deviceId = ((uint64_t) pc->pc_sel.pc_domain << 6) | ((uint64_t) pc->pc_sel.pc_bus << 4) | ((uint64_t) pc->pc_sel.pc_dev << 2) | pc->pc_sel.pc_func;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
ffGPUParsePciIds(&pciids, pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific))
{
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
.type = FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID,
.pciBusId = {
.domain = (uint32_t) pc->pc_sel.pc_domain,
.bus = pc->pc_sel.pc_bus,
.device = pc->pc_sel.pc_dev,
.func = pc->pc_sel.pc_func,
},
}, (FFGpuDriverResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.type = &gpu->type,
.frequency = &gpu->frequency,
}, "libnvidia-ml.so");
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
gpu->type = gpu->dedicated.total > (uint64_t)1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
}
return NULL;
}
+88 -278
View File
@@ -1,154 +1,24 @@
#include "detection/gpu/gpu.h" #include "detection/gpu/gpu.h"
#include "detection/vulkan/vulkan.h" #include "detection/vulkan/vulkan.h"
#include "detection/temps/temps_linux.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API #ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
#include "detection/gpu/gpu_driver_specific.h" #include "detection/gpu/gpu_driver_specific.h"
#endif #endif
#ifdef FF_HAVE_LIBPCI #include <inttypes.h>
#include "common/io/io.h"
#include "common/library.h"
#include "common/properties.h"
#include "common/parsing.h"
#include "detection/temps/temps_linux.h"
#include "util/stringUtils.h"
#include <string.h>
#include <unistd.h>
#include <pci/pci.h>
#include <setjmp.h>
// Fix building on Ubuntu 20.04 FF_MAYBE_UNUSED static void pciDetectTemp(FFGPUResult* gpu, uint32_t deviceClass)
#ifndef PCI_IORESOURCE_MEM
#define PCI_IORESOURCE_MEM 0x00000200
#endif
#ifndef PCI_IORESOURCE_PREFETCH
#define PCI_IORESOURCE_PREFETCH 0x00002000
#endif
typedef struct PCIData
{
struct pci_access* access;
FF_LIBRARY_SYMBOL(pci_fill_info)
FF_LIBRARY_SYMBOL(pci_read_byte)
FF_LIBRARY_SYMBOL(pci_lookup_name)
FF_LIBRARY_SYMBOL(pci_get_param)
#if PCI_LIB_VERSION >= 0x030800
FF_LIBRARY_SYMBOL(pci_get_string_property)
#endif
} PCIData;
static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(device->vendor_id));
if(gpu->vendor.length > 0)
return;
ffStrbufEnsureFree(&gpu->vendor, 255);
pci->ffpci_lookup_name(pci->access, gpu->vendor.chars, (int) gpu->vendor.allocated, PCI_LOOKUP_VENDOR, device->vendor_id);
ffStrbufRecalculateLength(&gpu->vendor);
if(ffStrbufContainIgnCaseS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if(ffStrbufContainIgnCaseS(&gpu->vendor, "Intel"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if(ffStrbufContainIgnCaseS(&gpu->vendor, "NVIDIA"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
else if(ffStrbufContainIgnCaseS(&gpu->vendor, "Apple"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
}
static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
u8 revId = 0;
bool revIdSet = false;
#if PCI_LIB_VERSION >= 0x030800
revIdSet = pci->ffpci_fill_info(device, PCI_FILL_CLASS_EXT) & PCI_FILL_CLASS_EXT;
if(revIdSet)
revId = device->rev_id;
#endif
if(!revIdSet)
{
#ifdef __FreeBSD__
return;
#else
revId = pci->ffpci_read_byte(device, PCI_REVISION_ID);
#endif
}
FF_STRBUF_AUTO_DESTROY query = ffStrbufCreateF("%X, %X,", device->device_id, revId);
ffParsePropFileData("libdrm/amdgpu.ids", query.chars, &gpu->name);
const char* removeStrings[] = {
"AMD ", "ATI ",
" (TM)", "(TM)",
" Graphics Adapter", " Graphics", " Series", " Edition"
};
ffStrbufRemoveStrings(&gpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
}
static void pciDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
if(ffStrbufEqualS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD))
{
drmDetectDeviceName(gpu, pci, device);
if(gpu->name.length > 0)
return;
}
ffStrbufEnsureFree(&gpu->name, 255);
pci->ffpci_lookup_name(pci->access, gpu->name.chars, (int) gpu->name.allocated, PCI_LOOKUP_DEVICE, device->vendor_id, device->device_id);
ffStrbufRecalculateLength(&gpu->name);
uint32_t openingBracket = ffStrbufFirstIndexC(&gpu->name, '[');
uint32_t closingBracket = ffStrbufNextIndexC(&gpu->name, openingBracket, ']');
if(closingBracket < gpu->name.length)
{
ffStrbufSubstrBefore(&gpu->name, closingBracket);
ffStrbufSubstrAfter(&gpu->name, openingBracket);
}
}
static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
#if PCI_LIB_VERSION >= 0x030800
pci->ffpci_fill_info(device, PCI_FILL_DRIVER);
ffStrbufAppendS(&gpu->driver, pci->ffpci_get_string_property(device, PCI_FILL_DRIVER));
#endif
const char* base = pci->ffpci_get_param(pci->access, "sysfs.path");
if(!ffStrSet(base))
return;
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateF("%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func);
if (gpu->driver.length == 0)
{
ffStrbufEnsureFree(&gpu->driver, 1023);
ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator
if(resultLength > 0)
{
gpu->driver.length = (uint32_t) resultLength;
gpu->driver.chars[resultLength] = '\0';
ffStrbufSubstrAfterLastC(&gpu->driver, '/');
}
}
ffStrbufAppendC(&gpu->driver, ' ');
ffStrbufAppendS(&path, "/module/version");
ffAppendFileBuffer(path.chars, &gpu->driver);
ffStrbufTrimRightSpace(&gpu->driver);
}
FF_MAYBE_UNUSED static void pciDetectTemp(FFGPUResult* gpu, struct pci_dev* device)
{ {
const FFlist* tempsResult = ffDetectTemps(); const FFlist* tempsResult = ffDetectTemps();
FF_LIST_FOR_EACH(FFTempValue, tempValue, *tempsResult) FF_LIST_FOR_EACH(FFTempValue, tempValue, *tempsResult)
{ {
// FIXME: this code doesn't take multiGPUs into count
//The kernel exposes the device class multiplied by 256 for some reason //The kernel exposes the device class multiplied by 256 for some reason
if(tempValue->deviceClass == device->device_class * 256) if(tempValue->deviceClass == deviceClass * 256)
{ {
gpu->temperature = tempValue->value; gpu->temperature = tempValue->value;
return; return;
@@ -156,108 +26,117 @@ FF_MAYBE_UNUSED static void pciDetectTemp(FFGPUResult* gpu, struct pci_dev* devi
} }
} }
FF_MAYBE_UNUSED static bool pciDetectMemory(FFGPUResult* gpu, const PCIData* pci, struct pci_dev* device) static void pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
{ {
gpu->dedicated.used = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET; ffStrbufAppendS(pciDir, "/driver");
char pathBuf[PATH_MAX];
uint32_t flags = (uint32_t) pci->ffpci_fill_info(device, PCI_FILL_IO_FLAGS | PCI_FILL_SIZES); ssize_t resultLength = readlink(pciDir->chars, pathBuf, sizeof(pathBuf));
if (!(flags & PCI_FILL_IO_FLAGS) || !(flags & PCI_FILL_SIZES)) if(resultLength > 0)
{ {
gpu->dedicated.total = gpu->shared.total = FF_GPU_VMEM_SIZE_UNSET; const char* slash = memrchr(pathBuf, '/', (size_t) resultLength);
return false; if (slash)
{
slash++;
ffStrbufSetNS(&gpu->driver, (uint32_t) (resultLength - (slash - pathBuf)), slash);
} }
gpu->dedicated.total = gpu->shared.total = 0; ffStrbufAppendS(pciDir, "/module/version");
for (uint32_t i = 0; i < sizeof(device->size) / sizeof(device->size[0]); i++) if (ffReadFileBuffer(pciDir->chars, buffer))
{ {
if (!(device->flags[i] & PCI_IORESOURCE_MEM)) continue; ffStrbufTrimRightSpace(buffer);
ffStrbufAppendC(&gpu->driver, ' ');
// Assume dedicated memories are prefetchable ffStrbufAppend(&gpu->driver, buffer);
// At least it's true for my laptop
if (device->flags[i] & PCI_IORESOURCE_PREFETCH)
gpu->dedicated.total += device->size[i];
else
gpu->shared.total += device->size[i];
} }
if (gpu->dedicated.total == 0 && gpu->shared.total == 0)
{
gpu->dedicated.total = gpu->shared.total = FF_GPU_VMEM_SIZE_UNSET;
return false;
} }
return true;
} }
FF_MAYBE_UNUSED static void pciDetectType(FFGPUResult* gpu) static bool loadPciIds(FFstrbuf* pciids)
{ {
//There is no straightforward way to detect the type of a GPU. ffReadFileBuffer("/usr/share/hwdata/pci.ids", pciids);
//The approach taken here is to look at the memory sizes of the device. if (pciids->length > 0) return true;
//Since integrated GPUs usually use the system ram, they don't have expansive ROMs
//and their memory sizes are usually smaller than 1GB. ffReadFileBuffer("/usr/share/misc/pci.ids", pciids); // debian?
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET) if (pciids->length > 0) return true;
{
gpu->type = gpu->dedicated.total > (uint64_t)1024 * 1024 * 1024 // 1GB ffReadFileBuffer("/usr/local/share/hwdata/pci.ids", pciids);
? FF_GPU_TYPE_DISCRETE if (pciids->length > 0) return true;
: FF_GPU_TYPE_INTEGRATED;
} return false;
else
gpu->type = FF_GPU_TYPE_UNKNOWN;
} }
static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* results, PCIData* pci, struct pci_dev* device) static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
{ {
pci->ffpci_fill_info(device, PCI_FILL_CLASS); //https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci
const char* pciDirPath = "/sys/bus/pci/devices/";
char class[1024]; DIR* dirp = opendir(pciDirPath);
pci->ffpci_lookup_name(pci->access, class, sizeof(class) - 1, PCI_LOOKUP_CLASS, device->device_class); if(dirp == NULL)
return "Failed to open `/sys/bus/pci/devices/`";
if( FF_STRBUF_AUTO_DESTROY pciDir = ffStrbufCreateA(64);
//https://pci-ids.ucw.cz/read/PD/03 ffStrbufAppendS(&pciDir, pciDirPath);
strcasecmp("VGA compatible controller", class) != 0 &&
strcasecmp("XGA compatible controller", class) != 0 &&
strcasecmp("3D controller", class) != 0 &&
strcasecmp("Display controller", class) != 0
) return;
pci->ffpci_fill_info(device, PCI_FILL_IDENT); const uint32_t pciBaseDirLength = pciDir.length;
FFGPUResult* gpu = ffListAdd(results); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
loadPciIds(&pciids);
ffStrbufInit(&gpu->platformApi); struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
ffStrbufInit(&gpu->vendor); ffStrbufSubstrBefore(&pciDir, pciBaseDirLength);
pciDetectVendorName(gpu, pci, device); ffStrbufAppendS(&pciDir, entry->d_name);
const uint32_t pciDevDirLength = pciDir.length;
ffStrbufAppendS(&pciDir, "/modalias");
if (!ffReadFileBuffer(pciDir.chars, &buffer))
continue;
ffStrbufSubstrBefore(&pciDir, pciDevDirLength);
uint32_t vendorId, deviceId;
uint8_t classId, subclassId;
if (sscanf(buffer.chars, "pci:v%8" SCNx32 "d%8" SCNx32 "sv%*8ssd%*8sbc%2" SCNx8 "sc%2" SCNx8, &vendorId, &deviceId, &classId, &subclassId) != 4)
continue;
if (classId != 0x03 /*PCI_BASE_CLASS_DISPLAY*/)
continue;
uint32_t pciDomain, pciBus, pciDevice, pciFunc;
if (sscanf(entry->d_name, "%" SCNx32 ":%" SCNx32 ":%" SCNx32 ".%" SCNx32, &pciDomain, &pciBus, &pciDevice, &pciFunc) != 4)
continue;
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString((uint16_t) vendorId));
ffStrbufInit(&gpu->name); ffStrbufInit(&gpu->name);
pciDetectDeviceName(gpu, pci, device);
ffStrbufInit(&gpu->driver); ffStrbufInit(&gpu->driver);
pciDetectDriverName(gpu, pci, device); ffStrbufInit(&gpu->platformApi);
#if FF_USE_PCI_MEMORY
// Libpci reports at least 2 false results (#495, #497)
pciDetectMemory(gpu, pci, device);
pciDetectType(gpu);
#else
gpu->dedicated.used = gpu->shared.used = gpu->dedicated.total = gpu->shared.total = FF_GPU_VMEM_SIZE_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
#endif
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET; gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->deviceId = ((uint64_t) pciDomain << 6) | ((uint64_t) pciBus << 4) | (deviceId << 2) | pciFunc;
gpu->frequency = FF_GPU_FREQUENCY_UNSET; gpu->frequency = FF_GPU_FREQUENCY_UNSET;
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
pciDetectDriver(gpu, &pciDir, &buffer);
ffStrbufSubstrBefore(&pciDir, pciDevDirLength);
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API #ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific)) if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific))
{ {
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) { ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
.type = FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID, .type = FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID,
.pciBusId = { .pciBusId = {
.domain = (uint32_t) device->domain, .domain = pciDomain,
.bus = device->bus, .bus = pciBus,
.device = device->dev, .device = pciDevice,
.func = device->func, .func = pciFunc,
}, },
}, (FFGpuDriverResult) { }, (FFGpuDriverResult) {
.temp = options->temp ? &gpu->temperature : NULL, .temp = options->temp ? &gpu->temperature : NULL,
@@ -274,77 +153,13 @@ static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
#ifdef __linux__ #ifdef __linux__
if(options->temp && gpu->temperature != gpu->temperature) if(options->temp && gpu->temperature != gpu->temperature)
pciDetectTemp(gpu, device); pciDetectTemp(gpu, ((uint32_t) classId << 8) + subclassId);
#endif #endif
}
jmp_buf pciInitJmpBuf;
static void __attribute__((__noreturn__))
handlePciInitError(FF_MAYBE_UNUSED char *msg, ...)
{
longjmp(pciInitJmpBuf, 1);
}
// https://github.com/pciutils/pciutils/blob/bca0412843fa650c749128ade03f35ab3e8fe2b9/lib/init.c#L186
static void __attribute__((__noreturn__))
handlePciGenericError(char *msg, ...)
{
va_list args;
va_start(args, msg);
fputs("pcilib: ", stderr);
vfprintf(stderr, msg, args);
va_end(args);
fputc('\n', stderr);
exit(1);
}
static void handlePciWarning(FF_MAYBE_UNUSED char *msg, ...)
{
// noop
}
static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
{
PCIData pci;
FF_LIBRARY_LOAD(libpci, &instance.config.library.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_cleanup);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_fill_info);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_lookup_name);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_read_byte);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_get_param);
#if PCI_LIB_VERSION >= 0x030800
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_get_string_property);
#endif
pci.access = ffpci_alloc();
pci.access->warning = handlePciWarning;
pci.access->error = handlePciInitError;
if(setjmp(pciInitJmpBuf) == 0) // https://github.com/pciutils/pciutils/issues/136
ffpci_init(pci.access);
else
return "pcilib: Cannot find any working access method.";
pci.access->error = handlePciGenericError; // set back to generic error so we don't mess up error handling in other places
ffpci_scan_bus(pci.access);
struct pci_dev* device = pci.access->devices;
while(device != NULL)
{
pciHandleDevice(options, gpus, &pci, device);
device = device->next;
} }
ffpci_cleanup(pci.access);
return NULL; return NULL;
} }
#endif
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{ {
#ifdef FF_HAVE_DIRECTX_HEADERS #ifdef FF_HAVE_DIRECTX_HEADERS
@@ -353,10 +168,5 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
return NULL; return NULL;
#endif #endif
#ifdef FF_HAVE_LIBPCI
return pciDetectGPUs(options, gpus); return pciDetectGPUs(options, gpus);
#else
FF_UNUSED(options, gpus);
return "fastfetch is built without libpci support";
#endif
} }
+1
View File
@@ -68,6 +68,7 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET; gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET; gpu->frequency = FF_GPU_FREQUENCY_UNSET;
ffStrbufInitStatic(&gpu->platformApi, "DXCore");
ffStrbufInit(&gpu->driver); ffStrbufInit(&gpu->driver);
uint64_t value = 0; uint64_t value = 0;
+8
View File
@@ -4,6 +4,14 @@
void ffDetectLocale(FFstrbuf* result) void ffDetectLocale(FFstrbuf* result)
{ {
ffStrbufAppendS(result, getenv("LC_MESSAGES"));
if(result->length > 0)
return;
ffStrbufAppendS(result, getenv("LANG"));
if(result->length > 0)
return;
#ifdef LC_MESSAGES #ifdef LC_MESSAGES
ffStrbufAppendS(result, setlocale(LC_MESSAGES, NULL)); ffStrbufAppendS(result, setlocale(LC_MESSAGES, NULL));
+5 -5
View File
@@ -23,15 +23,15 @@ typedef struct OpenCLData
static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result) static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
{ {
cl_platform_id platformID; cl_platform_id platformID = NULL;
cl_uint numPlatforms; cl_uint numPlatforms = 0;
data->ffclGetPlatformIDs(1, &platformID, &numPlatforms); data->ffclGetPlatformIDs(1, &platformID, &numPlatforms);
if(numPlatforms == 0) if(numPlatforms == 0)
return "clGetPlatformIDs returned 0 platforms"; return "clGetPlatformIDs returned 0 platforms";
cl_device_id deviceID; cl_device_id deviceID = NULL;
cl_uint numDevices; cl_uint numDevices = 0;
data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_GPU, 1, &deviceID, &numDevices); data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_GPU, 1, &deviceID, &numDevices);
if(numDevices == 0) if(numDevices == 0)
@@ -40,7 +40,7 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
if(numDevices == 0) if(numDevices == 0)
return "clGetDeviceIDs returned 0 devices"; return "clGetDeviceIDs returned 0 devices";
char version[64]; char version[64] = "";
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(version), version, NULL); data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(version), version, NULL);
if(!ffStrSet(version)) if(!ffStrSet(version))
return "clGetDeviceInfo returned NULL or empty string"; return "clGetDeviceInfo returned NULL or empty string";
@@ -13,5 +13,3 @@ typedef struct FFPowerAdapterResult
} FFPowerAdapterResult; } FFPowerAdapterResult;
const char* ffDetectPowerAdapter(FFlist* results); const char* ffDetectPowerAdapter(FFlist* results);
#define FF_POWERADAPTER_NOT_CONNECTED -1
@@ -7,6 +7,9 @@
const char* ffDetectPowerAdapter(FFlist* results) const char* ffDetectPowerAdapter(FFlist* results)
{ {
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef details = IOPSCopyExternalPowerAdapterDetails();
if (details && CFDictionaryContainsKey(details, CFSTR(kIOPSPowerAdapterWattsKey)))
{
FFPowerAdapterResult* adapter = ffListAdd(results); FFPowerAdapterResult* adapter = ffListAdd(results);
ffStrbufInit(&adapter->name); ffStrbufInit(&adapter->name);
@@ -14,11 +17,8 @@ const char* ffDetectPowerAdapter(FFlist* results)
ffStrbufInit(&adapter->manufacturer); ffStrbufInit(&adapter->manufacturer);
ffStrbufInit(&adapter->modelName); ffStrbufInit(&adapter->modelName);
ffStrbufInit(&adapter->serial); ffStrbufInit(&adapter->serial);
adapter->watts = FF_POWERADAPTER_NOT_CONNECTED; adapter->watts = 0;
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef details = IOPSCopyExternalPowerAdapterDetails();
if (details)
{
ffCfDictGetString(details, CFSTR(kIOPSNameKey), &adapter->name); ffCfDictGetString(details, CFSTR(kIOPSNameKey), &adapter->name);
if (ffCfDictGetString(details, CFSTR("Model"), &adapter->modelName) != NULL) if (ffCfDictGetString(details, CFSTR("Model"), &adapter->modelName) != NULL)
{ {
+11 -18
View File
@@ -28,6 +28,14 @@ static void parsePowerAdapter(FFstrbuf* dir, FF_MAYBE_UNUSED const char* id, FFl
if(ffStrbufIgnCaseEqualS(&tmpBuffer, "Device")) if(ffStrbufIgnCaseEqualS(&tmpBuffer, "Device"))
return; return;
ffStrbufAppendS(dir, "/online");
char online = '1';
ffReadFileData(dir->chars, sizeof(online), &online);
ffStrbufSubstrBefore(dir, dirLength);
if (online == '0')
return;
//input_power_limit must exist and be not empty //input_power_limit must exist and be not empty
ffStrbufAppendS(dir, "/input_power_limit"); ffStrbufAppendS(dir, "/input_power_limit");
bool available = ffReadFileBuffer(dir->chars, &tmpBuffer); bool available = ffReadFileBuffer(dir->chars, &tmpBuffer);
@@ -35,24 +43,14 @@ static void parsePowerAdapter(FFstrbuf* dir, FF_MAYBE_UNUSED const char* id, FFl
if (!available) if (!available)
return; return;
FFPowerAdapterResult* result = ffListAdd(results); FFPowerAdapterResult* result = ffListAdd(results);
ffStrbufInit(&result->name); ffStrbufInit(&result->name);
ffStrbufInit(&result->description); ffStrbufInit(&result->description);
ffStrbufAppendS(dir, "/online");
char online = '1';
ffReadFileData(dir->chars, sizeof(online), &online);
ffStrbufSubstrBefore(dir, dirLength);
if (online == '0')
result->watts = FF_POWERADAPTER_NOT_CONNECTED;
else
result->watts = (int) (ffStrbufToDouble(&tmpBuffer) / 1e6 + 0.5); result->watts = (int) (ffStrbufToDouble(&tmpBuffer) / 1e6 + 0.5);
//At this point, we have a battery. Try to get as much values as possible.
ffStrbufInit(&result->manufacturer); ffStrbufInit(&result->manufacturer);
ffStrbufInit(&result->modelName);
ffStrbufInit(&result->serial);
ffStrbufAppendS(dir, "/manufacturer"); ffStrbufAppendS(dir, "/manufacturer");
if (ffReadFileBuffer(dir->chars, &result->manufacturer)) if (ffReadFileBuffer(dir->chars, &result->manufacturer))
ffStrbufTrimRightSpace(&result->manufacturer); ffStrbufTrimRightSpace(&result->manufacturer);
@@ -60,13 +58,11 @@ static void parsePowerAdapter(FFstrbuf* dir, FF_MAYBE_UNUSED const char* id, FFl
ffStrbufSetStatic(&result->manufacturer, "Apple Inc."); ffStrbufSetStatic(&result->manufacturer, "Apple Inc.");
ffStrbufSubstrBefore(dir, dirLength); ffStrbufSubstrBefore(dir, dirLength);
ffStrbufInit(&result->modelName);
ffStrbufAppendS(dir, "/model_name"); ffStrbufAppendS(dir, "/model_name");
if (ffReadFileBuffer(dir->chars, &result->modelName)) if (ffReadFileBuffer(dir->chars, &result->modelName))
ffStrbufTrimRightSpace(&result->modelName); ffStrbufTrimRightSpace(&result->modelName);
ffStrbufSubstrBefore(dir, dirLength); ffStrbufSubstrBefore(dir, dirLength);
ffStrbufInit(&result->serial);
ffStrbufAppendS(dir, "/serial_number"); ffStrbufAppendS(dir, "/serial_number");
if (ffReadFileBuffer(dir->chars, &result->serial)) if (ffReadFileBuffer(dir->chars, &result->serial))
ffStrbufTrimRightSpace(&result->serial); ffStrbufTrimRightSpace(&result->serial);
@@ -95,8 +91,5 @@ const char* ffDetectPowerAdapter(FFlist* results)
ffStrbufSubstrBefore(&baseDir, baseDirLength); ffStrbufSubstrBefore(&baseDir, baseDirLength);
} }
if(results->length == 0)
return "\"/sys/class/power_supply/\" doesn't contain any power adapter folder";
return NULL; return NULL;
} }
+2 -2
View File
@@ -17,8 +17,8 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
IMMDeviceEnumerator* FF_AUTO_RELEASE_COM_OBJECT pEnum = NULL; IMMDeviceEnumerator* FF_AUTO_RELEASE_COM_OBJECT pEnum = NULL;
if (FAILED(CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void **)&pEnum))) if (FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&pEnum)))
return "CoCreateInstance(__uuidof(MMDeviceEnumerator)) failed"; return "CoCreateInstance(CLSID_MMDeviceEnumerator) failed";
LPWSTR mainDeviceId = NULL; LPWSTR mainDeviceId = NULL;
@@ -315,7 +315,7 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
detectFromConfigFile("lxterminal/lxterminal.conf", "fontname =", terminalFont); detectFromConfigFile("lxterminal/lxterminal.conf", "fontname =", terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "tilix")) else if(ffStrbufIgnCaseEqualS(&terminal->processName, "tilix"))
detectFromGSettings("/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont); detectFromGSettings("/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont);
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "gnome-terminal-")) else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "gnome-terminal"))
detectFromGSettings("/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont); detectFromGSettings("/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "kgx")) else if(ffStrbufIgnCaseEqualS(&terminal->processName, "kgx"))
detectKgx(terminalFont); detectKgx(terminalFont);
+31 -2
View File
@@ -281,7 +281,7 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
FF_MAYBE_UNUSED static bool getTerminalVersionKgx(FFstrbuf* version) FF_MAYBE_UNUSED static bool getTerminalVersionKgx(FFstrbuf* version)
{ {
if(ffProcessAppendStdOut(version, (char* const[]){ if(ffProcessAppendStdOut(version, (char* const[]){
"gnome-terminal", "kgx",
"--version", "--version",
NULL NULL
})) return false; })) return false;
@@ -356,6 +356,20 @@ FF_MAYBE_UNUSED static bool getTerminalVersionXterm(FFstrbuf* exe, FFstrbuf* ver
return version->length > 0; return version->length > 0;
} }
FF_MAYBE_UNUSED static bool getTerminalVersionBlackbox(FFstrbuf* exe, FFstrbuf* version)
{
if(ffProcessAppendStdOut(version, (char* const[]){
exe->chars,
"--version",
NULL
})) return false;
//BlackBox version 0.14.0 (flatpak)
ffStrbufSubstrAfterFirstS(version, "version ");
ffStrbufSubstrBeforeFirstC(version, ' ');
return version->length > 0;
}
FF_MAYBE_UNUSED static bool getTerminalVersionUrxvt(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version) FF_MAYBE_UNUSED static bool getTerminalVersionUrxvt(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version)
{ {
if(ffProcessAppendStdErr(version, (char* const[]){ if(ffProcessAppendStdErr(version, (char* const[]){
@@ -400,6 +414,15 @@ static bool getTerminalVersionContour(FFstrbuf* exe, FFstrbuf* version)
return version->length > 0; return version->length > 0;
} }
static bool getTerminalVersionScreen(FFstrbuf* exe, FFstrbuf* version)
{
if(!getExeVersionRaw(exe, version)) return false;
// Screen version 4.09.01 (GNU) 20-Aug-23
ffStrbufSubstrAfter(version, strlen("Screen version ") - 1);
ffStrbufSubstrBeforeFirstC(version, ' ');
return version->length > 0;
}
#ifdef _WIN32 #ifdef _WIN32
static bool getTerminalVersionWindowsTerminal(FFstrbuf* exe, FFstrbuf* version) static bool getTerminalVersionWindowsTerminal(FFstrbuf* exe, FFstrbuf* version)
@@ -440,7 +463,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
if(ffStrbufStartsWithIgnCaseS(processName, "gnome-terminal-")) if(ffStrbufStartsWithIgnCaseS(processName, "gnome-terminal"))
return getTerminalVersionGnome(version); return getTerminalVersionGnome(version);
if(ffStrbufIgnCaseEqualS(processName, "konsole")) if(ffStrbufIgnCaseEqualS(processName, "konsole"))
@@ -473,6 +496,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
if(ffStrbufIgnCaseEqualS(processName, "xterm")) if(ffStrbufIgnCaseEqualS(processName, "xterm"))
return getTerminalVersionXterm(exe, version); return getTerminalVersionXterm(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "blackbox"))
return getTerminalVersionBlackbox(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "st")) if(ffStrbufIgnCaseEqualS(processName, "st"))
return getTerminalVersionSt(exe, version); return getTerminalVersionSt(exe, version);
@@ -511,6 +537,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
if(ffStrbufStartsWithIgnCaseS(processName, "contour")) if(ffStrbufStartsWithIgnCaseS(processName, "contour"))
return getTerminalVersionContour(exe, version); return getTerminalVersionContour(exe, version);
if(ffStrbufStartsWithIgnCaseS(processName, "screen"))
return getTerminalVersionScreen(exe, version);
const char* termProgramVersion = getenv("TERM_PROGRAM_VERSION"); const char* termProgramVersion = getenv("TERM_PROGRAM_VERSION");
if(termProgramVersion) if(termProgramVersion)
{ {
@@ -86,7 +86,7 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
args, &size, args, &size,
NULL, 0 NULL, 0
) == 0) ) == 0)
ffStrbufSetS(exePath, args); ffStrbufSetNS(exePath, (uint32_t) (size - 1), args);
size = ARG_MAX; size = ARG_MAX;
if(sysctl( if(sysctl(
@@ -123,6 +123,9 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid, int32_t* tty) static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid, int32_t* tty)
{ {
if (pid <= 0)
return "Invalid pid";
#ifdef __linux__ #ifdef __linux__
char statFilePath[64]; char statFilePath[64];
@@ -144,8 +147,13 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid, int
) )
return "sscanf(stat) failed"; return "sscanf(stat) failed";
if (tty && (tty_ >> 8) == 0x88) if (tty)
{
if ((tty_ >> 8) == 0x88)
*tty = tty_ & 0xFF; *tty = tty_ & 0xFF;
else
*tty = -1;
}
#elif defined(__APPLE__) #elif defined(__APPLE__)
@@ -209,11 +217,13 @@ static pid_t getShellInfo(FFShellResult* result, pid_t pid)
name[0] = '\0'; name[0] = '\0';
pid_t ppid = 0; pid_t ppid = 0;
int32_t tty = -1;
while (getProcessNameAndPpid(pid, name, &ppid, &result->tty) == NULL) while (getProcessNameAndPpid(pid, name, &ppid, &tty) == NULL)
{ {
//Common programs that are between terminal and own process, but are not the shell //Common programs that are between terminal and own process, but are not the shell
if( if(
// tty < 0 || //A shell should connect to a tty
ffStrEquals(name, "sh") || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell ffStrEquals(name, "sh") || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell
ffStrEquals(name, "sudo") || ffStrEquals(name, "sudo") ||
ffStrEquals(name, "su") || ffStrEquals(name, "su") ||
@@ -237,6 +247,7 @@ static pid_t getShellInfo(FFShellResult* result, pid_t pid)
result->pid = (uint32_t) pid; result->pid = (uint32_t) pid;
result->ppid = (uint32_t) ppid; result->ppid = (uint32_t) ppid;
result->tty = tty;
ffStrbufSetS(&result->processName, name); ffStrbufSetS(&result->processName, name);
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName, &result->exePath); getProcessInformation(pid, &result->processName, &result->exe, &result->exeName, &result->exePath);
break; break;
@@ -255,6 +266,7 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
{ {
//Known shells //Known shells
if ( if (
ffStrEquals(name, "sh") ||
ffStrEquals(name, "ash") || ffStrEquals(name, "ash") ||
ffStrEquals(name, "bash") || ffStrEquals(name, "bash") ||
ffStrEquals(name, "zsh") || ffStrEquals(name, "zsh") ||
@@ -272,6 +284,10 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
ffStrEquals(name, "oil.ovm") || ffStrEquals(name, "oil.ovm") ||
ffStrEquals(name, "xonsh") || // works in Linux but not in macOS because kernel returns `Python` in this case ffStrEquals(name, "xonsh") || // works in Linux but not in macOS because kernel returns `Python` in this case
ffStrEquals(name, "login") || ffStrEquals(name, "login") ||
ffStrEquals(name, "sshd") ||
#ifdef __linux__
ffStrStartsWith(name, "flatpak-") || // #707
#endif
ffStrEndsWith(name, ".sh") ffStrEndsWith(name, ".sh")
) )
{ {
@@ -297,6 +313,25 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
return ppid; return ppid;
} }
static bool getTerminalInfoByPidEnv(FFTerminalResult* result, const char* pidEnv)
{
const char* envStr = getenv(pidEnv);
if (envStr == NULL)
return false;
pid_t pid = (pid_t) strtol(envStr, NULL, 10);
result->pid = (uint32_t) pid;
char name[256];
if (getProcessNameAndPpid(pid, name, (pid_t*) &result->ppid, NULL) == NULL)
{
ffStrbufSetS(&result->processName, name);
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName, &result->exePath);
return true;
}
return false;
}
static void getTerminalFromEnv(FFTerminalResult* result) static void getTerminalFromEnv(FFTerminalResult* result)
{ {
if( if(
@@ -319,58 +354,80 @@ static void getTerminalFromEnv(FFTerminalResult* result)
const char* term = NULL; const char* term = NULL;
//SSH //SSH
if(getenv("SSH_CONNECTION") != NULL) if(
getenv("SSH_TTY") != NULL
)
term = getenv("SSH_TTY"); term = getenv("SSH_TTY");
else if(
getenv("KITTY_PID") != NULL ||
getenv("KITTY_INSTALLATION_DIR") != NULL
)
{
if (getTerminalInfoByPidEnv(result, "KITTY_PID"))
return;
term = "kitty";
}
#ifdef __linux__ #ifdef __linux__ // WSL
//Windows Terminal //Windows Terminal
if(!ffStrSet(term) && ( else if(
getenv("WT_SESSION") != NULL || getenv("WT_SESSION") != NULL ||
getenv("WT_PROFILE_ID") != NULL getenv("WT_PROFILE_ID") != NULL
)) term = "Windows Terminal"; ) term = "Windows Terminal";
//ConEmu //ConEmu
if(!ffStrSet(term) && ( else if(
getenv("ConEmuPID") != NULL getenv("ConEmuPID") != NULL
)) term = "ConEmu"; ) term = "ConEmu";
#endif #endif
//Alacritty //Alacritty
if(!ffStrSet(term) && ( else if(
getenv("ALACRITTY_SOCKET") != NULL || getenv("ALACRITTY_SOCKET") != NULL ||
getenv("ALACRITTY_LOG") != NULL || getenv("ALACRITTY_LOG") != NULL ||
getenv("ALACRITTY_WINDOW_ID") != NULL getenv("ALACRITTY_WINDOW_ID") != NULL
)) term = "Alacritty"; ) term = "Alacritty";
#ifdef __ANDROID__ #ifdef __ANDROID__
//Termux //Termux
if(!ffStrSet(term) && ( else if(
getenv("TERMUX_VERSION") != NULL || getenv("TERMUX_VERSION") != NULL ||
getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL
)) term = "com.termux"; )
{
if (getTerminalInfoByPidEnv(result, "TERMUX_APP__PID"))
return;
term = "com.termux";
}
#endif #endif
#ifdef __linux__ #if defined(__linux__) || defined(__FreeBSD__)
//Konsole //Konsole
if(!ffStrSet(term) && ( else if(
getenv("KONSOLE_VERSION") != NULL getenv("KONSOLE_VERSION") != NULL
)) term = "konsole"; ) term = "konsole";
else if(
getenv("GNOME_TERMINAL_SCREEN") != NULL ||
getenv("GNOME_TERMINAL_SERVICE") != NULL
) term = "gnome-terminal";
#endif #endif
//MacOS, mintty //MacOS, mintty
if(!ffStrSet(term)) else if(getenv("TERM_PROGRAM") != NULL)
term = getenv("TERM_PROGRAM"); term = getenv("TERM_PROGRAM");
if(!ffStrSet(term)) else if(getenv("LC_TERMINAL") != NULL)
term = getenv("LC_TERMINAL"); term = getenv("LC_TERMINAL");
//Normal Terminal //Normal Terminal
if(!ffStrSet(term)) else
{
term = getenv("TERM"); term = getenv("TERM");
//TTY //TTY
if(!ffStrSet(term) || ffStrEquals(term, "linux")) if(!ffStrSet(term) || ffStrEquals(term, "linux"))
term = ttyname(STDIN_FILENO); term = ttyname(STDIN_FILENO);
}
if(ffStrSet(term)) if(ffStrSet(term))
{ {
@@ -429,6 +486,8 @@ static void setTerminalInfoDetails(FFTerminalResult* result)
ffStrbufInitStatic(&result->prettyName, "WezTerm"); ffStrbufInitStatic(&result->prettyName, "WezTerm");
else if(ffStrbufStartsWithS(&result->processName, "tmux:")) else if(ffStrbufStartsWithS(&result->processName, "tmux:"))
ffStrbufInitStatic(&result->prettyName, "tmux"); ffStrbufInitStatic(&result->prettyName, "tmux");
else if(ffStrbufStartsWithS(&result->processName, "screen-"))
ffStrbufInitStatic(&result->prettyName, "screen");
#if defined(__ANDROID__) #if defined(__ANDROID__)
@@ -437,7 +496,7 @@ static void setTerminalInfoDetails(FFTerminalResult* result)
#elif defined(__linux__) || defined(__FreeBSD__) #elif defined(__linux__) || defined(__FreeBSD__)
else if(ffStrbufStartsWithS(&result->processName, "gnome-terminal-")) else if(ffStrbufStartsWithS(&result->processName, "gnome-terminal"))
ffStrbufInitStatic(&result->prettyName, "GNOME Terminal"); ffStrbufInitStatic(&result->prettyName, "GNOME Terminal");
else if(ffStrbufStartsWithS(&result->processName, "kgx")) else if(ffStrbufStartsWithS(&result->processName, "kgx"))
ffStrbufInitStatic(&result->prettyName, "GNOME Console"); ffStrbufInitStatic(&result->prettyName, "GNOME Console");
@@ -298,10 +298,11 @@ static uint32_t getTerminalInfo(FFTerminalResult* result, uint32_t pid)
{ {
if(!hasGui) if(!hasGui)
{ {
//We are nested shell //We are in nested shell
ffStrbufClear(&result->processName); ffStrbufClear(&result->processName);
ffStrbufClear(&result->prettyName); ffStrbufClear(&result->prettyName);
ffStrbufClear(&result->exe); ffStrbufClear(&result->exe);
ffStrbufClear(&result->exePath);
result->exeName = ""; result->exeName = "";
pid = ppid; pid = ppid;
continue; continue;
@@ -320,6 +321,7 @@ static uint32_t getTerminalInfo(FFTerminalResult* result, uint32_t pid)
ffStrbufClear(&result->processName); ffStrbufClear(&result->processName);
ffStrbufClear(&result->prettyName); ffStrbufClear(&result->prettyName);
ffStrbufClear(&result->exe); ffStrbufClear(&result->exe);
ffStrbufClear(&result->exePath);
result->exeName = ""; result->exeName = "";
return 0; return 0;
} }
@@ -10,10 +10,10 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result)
ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize);
if (winsize.ws_row == 0 || winsize.ws_col == 0) if (winsize.ws_row == 0 || winsize.ws_col == 0)
ffGetTerminalResponse("\033[18t", "\033[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col); ffGetTerminalResponse("\e[18t", "\e[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col);
if (winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0) if (winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0)
ffGetTerminalResponse("\033[14t", "\033[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel); ffGetTerminalResponse("\e[14t", "\e[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel);
if (winsize.ws_row == 0 && winsize.ws_col == 0) if (winsize.ws_row == 0 && winsize.ws_col == 0)
return false; return false;
@@ -14,7 +14,7 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result)
} }
else else
{ {
ffGetTerminalResponse("\033[18t", "\033[8;%hu;%hut", &result->rows, &result->columns); ffGetTerminalResponse("\e[18t", "\e[8;%hu;%hut", &result->rows, &result->columns);
} }
} }
@@ -0,0 +1,91 @@
#include "terminaltheme.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include <inttypes.h>
static bool detectByEscapeCode(FFTerminalThemeResult* result)
{
int command = 0;
if (ffGetTerminalResponse("\e]10;?\e\\", "\e]%d;rgb:%" SCNx16 "/%" SCNx16 "/%" SCNx16 "\e\\", &command, &result->fg.r, &result->fg.g, &result->fg.b) == NULL)
{
if (command != 10)
return false;
if (result->fg.r > 0x0100 || result->fg.g > 0x0100 || result->fg.b > 0x0100)
result->fg.r /= 0x0100, result->fg.g /= 0x0100, result->fg.b /= 0x0100;
}
else
return false;
if (ffGetTerminalResponse("\e]11;?\e\\", "\e]%d;rgb:%" SCNx16 "/%" SCNx16 "/%" SCNx16 "\e\\", &command, &result->bg.r, &result->bg.g, &result->bg.b) == NULL)
{
if (command != 11)
return false;
if (result->bg.r > 0x0100 || result->bg.g > 0x0100 || result->bg.b > 0x0100)
result->bg.r /= 0x0100, result->bg.g /= 0x0100, result->bg.b /= 0x0100;
}
else
return false;
return true;
}
static FFTerminalThemeColor fgbgToColor(int num)
{
// https://github.com/dalance/termbg/blob/13c478a433fa182e65c401d26a1e7792a7f7f453/src/lib.rs#L251
switch (num)
{
case 0: return (FFTerminalThemeColor){ 0, 0, 0, false}; // black
case 1: return (FFTerminalThemeColor){205, 0, 0, false}; // red
case 2: return (FFTerminalThemeColor){ 0, 205, 0, false}; // green
case 3: return (FFTerminalThemeColor){205, 205, 0, false}; // yellow
case 4: return (FFTerminalThemeColor){ 0, 0, 238, false}; // blue
case 5: return (FFTerminalThemeColor){205, 0, 205, false}; // magenta
case 6: return (FFTerminalThemeColor){ 0, 205, 205, false}; // cyan
case 7: return (FFTerminalThemeColor){229, 229, 229, false}; // white
case 8: return (FFTerminalThemeColor){127, 127, 127, false}; // bright black
case 9: return (FFTerminalThemeColor){255, 0, 0, false}; // bright red
case 10: return (FFTerminalThemeColor){ 0, 255, 0, false}; // bright green
case 11: return (FFTerminalThemeColor){255, 255, 0, false}; // bright yellow
case 12: return (FFTerminalThemeColor){ 92, 92, 255, false}; // bright blue
case 13: return (FFTerminalThemeColor){255, 0, 255, false}; // bright magenta
case 14: return (FFTerminalThemeColor){ 0, 255, 255, false}; // bright cyan
case 15: return (FFTerminalThemeColor){255, 255, 255, false}; // bright white
default: return (FFTerminalThemeColor){ 0, 0, 0, false}; // invalid
}
}
static bool detectByEnv(FFTerminalThemeResult* result)
{
const char* color = getenv("COLORFGBG"); // 7;0
if (!ffStrSet(color))
return false;
int f, g;
if (sscanf(color, "%d;%d", &f, &g) != 2)
return false;
result->fg = fgbgToColor(f);
result->bg = fgbgToColor(g);
return true;
}
static inline bool detectColor(FFTerminalThemeResult* result)
{
if (detectByEscapeCode(result))
return true;
return detectByEnv(result);
}
bool ffDetectTerminalTheme(FFTerminalThemeResult* result)
{
if (!detectColor(result)) return false;
result->fg.dark = result->fg.r * 299 + result->fg.g * 587 + result->fg.b * 114 < 128000;
result->bg.dark = result->bg.r * 299 + result->bg.g * 587 + result->bg.b * 114 < 128000;
return true;
}
@@ -0,0 +1,19 @@
#pragma once
#include "fastfetch.h"
typedef struct FFTerminalThemeColor
{
uint16_t r;
uint16_t g;
uint16_t b;
bool dark;
} FFTerminalThemeColor;
typedef struct FFTerminalThemeResult
{
FFTerminalThemeColor fg;
FFTerminalThemeColor bg;
} FFTerminalThemeResult;
bool ffDetectTerminalTheme(FFTerminalThemeResult* result);
+5 -1
View File
@@ -250,7 +250,11 @@ static const char* detectWifiWithIoctls(FFlist* result)
item->conn.txRate = 0.0/0.0; item->conn.txRate = 0.0/0.0;
ffStrbufSetF(&path, "/sys/class/net/%s/operstate", i->if_name); ffStrbufSetF(&path, "/sys/class/net/%s/operstate", i->if_name);
if (!ffAppendFileBuffer(path.chars, &item->inf.status) || !ffStrbufEqualS(&item->inf.status, "up\n")) if (!ffAppendFileBuffer(path.chars, &item->inf.status))
continue;
ffStrbufTrimRightSpace(&item->inf.status);
if (!ffStrbufEqualS(&item->inf.status, "up"))
continue; continue;
FF_AUTO_CLOSE_FD int sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); FF_AUTO_CLOSE_FD int sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+3 -4
View File
@@ -300,7 +300,7 @@ static void listModules(bool pretty)
{ {
++count; ++count;
if (pretty) if (pretty)
printf("%d)%s%-13s: %s\n", count, count > 9 ? " " : " ", (*modules)->name, (*modules)->description); printf("%d)%s%-14s: %s\n", count, count > 9 ? " " : " ", (*modules)->name, (*modules)->description);
else else
printf("%s:%s\n", (*modules)->name, (*modules)->description); printf("%s:%s\n", (*modules)->name, (*modules)->description);
} }
@@ -483,10 +483,8 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
if(isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value)) if(isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value))
return; return;
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(128);
if (ffPathExpandEnv(value, &absolutePath))
{ {
bool success = isJsonConfig ? parseJsoncFile(absolutePath.chars) : parseConfigFile(data, absolutePath.chars); bool success = isJsonConfig ? parseJsoncFile(value) : parseConfigFile(data, value);
if(success) if(success)
return; return;
@@ -494,6 +492,7 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
//Try to load as a relative path //Try to load as a relative path
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(128);
FF_LIST_FOR_EACH(FFstrbuf, path, instance.state.platform.dataDirs) FF_LIST_FOR_EACH(FFstrbuf, path, instance.state.platform.dataDirs)
{ {
//We need to copy it, because if a config file loads a config file, the value of path must be unchanged //We need to copy it, because if a config file loads a config file, the value of path must be unchanged
+18
View File
@@ -0,0 +1,18 @@
$1_wwM $2_ww
$1MMM$2MMMM
$1MM
$3_ww##############yy_
$4wMMMMM$3###########$4MMMMm
$4,MMMMMMMMM$3######$4MMMMMMMM0_
$4wMMMMMMMMMMMMM$5MM$60MMMMMMMMMMm
$4,MMMMMMMMMMMMMMM$5MMMM$60MMMMMMMMM0,
$4wMMMMMMMMMMMMMMMM$5MMMMM0$6MMMMMMMMMMb
$4_MMMMMMMMMMMMMMMMMM$5MMMMMMM0$6MMMMMMMMM0,
$4_MMMMMMMMMMMMMMMMMMM$5MMMM$7M$5MMMW$6MMMMMMMMMM_
$4_MMMMMMMMMMMMMMMMMMMM$5MMMM$7M0$5MMMW$6MMMMMMMMMM_
$4~MMMMMMMMMMMMMMMMM$5MMMM$7M$5MMMW$6MMMMM00~
$4~MMMMMMMMMMMMM$5MMMWMMM$60MM$5MMM$6~
$4~MMMMMMMMMM$5MMMMM$60MMM~~
$4~MMMMMM$5MMM$60MM~
$4~MM$5M$6@~
$4M
+18
View File
@@ -0,0 +1,18 @@
,clll:.$2 .,::::::::::::'
$1:ooooooo$2 .;::::::::::::::
$1looooooo$2 ,:::::::::::::::'
$1looooooo$2 .::::::::::::::::
$1looooooo$2 ;:::::::::::::::.
$1looooooo$2 .::::::::::::::::
$1looooool$2;;;;,::::::::::::::::
$1looool$2::, .::::::::::::::
$1looooc$2:: ;::
$1looooc$2::;. .::;
$1loooool$2:::::::::::.
$1looooooo$2. .::::::'
$1looooooo$2 .::::::,;,..
$1looooooo$2 :::;' ';:;.
$1looooooo$2 ::: :::
$1cooooooo$2 .::' '::.
$1 .ooooc $2 ::, ,::
''''
+17
View File
@@ -0,0 +1,17 @@
:oooo, .','
.';;;.;oooooooolooooo'
coooooooooooooooooooooooolc'
.':oooooooooooo$2ll$1ooooooooooooool
.oooooooooooooooo$2ll$1oooooooooooo$2l$1ool
ooooooooooooooooo$2ll$1ooooooooooo$2ll$1oo'
oooo$2l$1oooooooooo$2lll$1ooooooooo$2lll$1oo
.ooooo$2lll$1ooooo$2lll$1ooooooooo$2lll$1ool
.ooooooo$2lll$1oo$2llll$1oooo$2lllll$1ooooo:
'oooooooo$2llllllllllll$1oooooooo'
.c,.oo$2lllll$1oooooooo.$2
'll;
'll.
lll
lll
;ll,
.l:
+17
View File
@@ -0,0 +1,17 @@
.;ooooooooooooooooooooooooooo.
,dddddddddddddddddddddddddddddd'$3;
$1 lddddddddddddddddddddddddddddd'$3;;;
$1ddddd$2,XXX.$1ddddd$2,XXX.$1dddd'$2,XXX.$3;;;;;
$1ddddd$2XX$1x$2XX$1ddddd$2XX$1x$2XX$1ddd'$2,XX$3x$2XX$3;;;;;
$1ddddd$2'XXX'$1ddddd$2'XXX'$1dd'$2XXXXXX'$3;;;;;
$1dddddd$2;X;$1ddddddd$2;X:$1d'$2XXX$3;;;;;;;;;;;
$1dddddd$2;X;$1ddddddd$2;X:$2XXX$3;;;;;;;;;;;;;
$1dddddd$2;X;$1dddddd'$2;XXX,,,,,,XXX.$3;;;;;
$1dddddd$2;X;$1dddd'$2XXXX$2XXXXXXXXX$3x$2XX$3;;;;;
$1dddddd$2;X;$1dd'$2XXX$3;;;;;;;;;;;$2XXX$3;;;;;;
$1dddddd$2;X;$1'$2XXX$3;;;;;;;;;;;;;;;;;;;;;;
$1dddddd$2;XXXXX,,,,,,,,,,,,,;XXX:$3;;;;;
$1dddddd$2:XXXXXXXXXXXXXXXXXXXX$3x$2XX$3;;;;;
$1ddddd'$3;;;;;;;;;;;;;;;;;;;$2'XXX'$3;;;;'
$1ddd'$3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$1o'$3;;;;;;;;;;;;;;;;;;;;;;;;;;;;'
+28
View File
@@ -0,0 +1,28 @@
'',,, ,,,d,
',, ,,'
', ,.
., '
. .
' .
.. oddddkdlc:;,.. ..
. ............lllc, .
. ....................: .
. . ....................
'. ..........'o........d0XX0.
....lllllllcOOOcllllll............cxlxc...;okkkx.
..................................';lc'...lo.
.'''''''''''''.....................,;,.......
',,,,,,,,,,,,,,,,''...............dkkkd......
',,,,,,,,,,,,,,,,,,,'............;okkkd;....
.,,,,,,,,,,,,,,,,,,,,,............;cll;.....
,,,,,,,,,,,,,,,,,,,,'....................:d,
,,,,,,,,,,,,,,,,,,,....................oxxx:
.,,,,,,,,,,,,,,,,,'..................oxxxxx. .
.,,,,,,,,,,,,,,'.......... ,oxxxxxxx .
.;,,,,,,,,,,,,'.. 'cxxxxxxxxx,
:dl:,'',,'.... .;lxxxxxxxxxd;
,codol:;'. ...,;cldxxxxxxxxxoc.
.:cxxxxxdlccccc:ccldxxxxxxxxxxxxxx::.
.'::dxxxxxxxxxxxxxxxxxxxxxxxd::'.
..,::cdxxxxxxxxxxxxxdc::,..
...,;:::::::;,...
+15
View File
@@ -0,0 +1,15 @@
. .:. . .:.
.^^.!.:::. .^!?J?^
.:^.^!!!~:~^. .7??77!~~^.
.~^.!??77?!.^~: ..:^^7JJJ7~~^.
.^~.^7???7~.~~. .7??????????!
.:^:^^~^^:!^ ^: .......^!:...
.!7~.::.!.::. ~BG~ :^ ^~:
:!!~ ~. ?BBBB! ^?J!. .!~.
:!. .JBY. .Y#BBBY?~!???J7. :^^.
.. :5#B#P~P#BBP?7?55J?J7:
^P#BBBBBBBB5?7J5555J!.....
!BBBBBBGBBGJ77::Y555J?77777^
?BBBBG5JJ5PJ?!: .?Y??????77?~.
.YBGPYJ??????Y?^^^^~7?????????7?!.
.^^:..::::::::.....:::::::::::..:.
+7
View File
@@ -0,0 +1,7 @@
// OOOOOOO SSSSSSS
// OO OO SS
zzzzzz // OO OO SS
zz // OO OO SSSS
zz // OO OO SS
zz // OO OO SS
zzzzzz // OOOOOOO SSSSSSS
+121 -1
View File
@@ -468,6 +468,23 @@ static const FFlogo A[] = {
.colorKeys = FF_COLOR_FG_YELLOW, .colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_GREEN, .colorTitle = FF_COLOR_FG_GREEN,
}, },
// Asahi2
{
.names = {"asahi2", "asahi-linux2"},
.lines = FASTFETCH_DATATEXT_LOGO_ASAHI2,
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.colors = {
FF_COLOR_FG_LIGHT_YELLOW,
FF_COLOR_FG_CYAN,
FF_COLOR_FG_RED,
FF_COLOR_FG_LIGHT_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_BLACK,
FF_COLOR_FG_LIGHT_CYAN,
},
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_GREEN,
},
// Aster // Aster
{ {
.names = {"aster"}, .names = {"aster"},
@@ -974,7 +991,7 @@ static const FFlogo C[] = {
// ContainerLinux // ContainerLinux
{ {
.names = {"ContainerLinux", "Container Linux", "Container Linux by CoreOS"}, .names = {"ContainerLinux", "Container Linux", "Container Linux by CoreOS"},
.lines = FASTFETCH_DATATEXT_LOGO_CONTAINER_LINUX, .lines = FASTFETCH_DATATEXT_LOGO_FEDORA_COREOS,
.colors = { .colors = {
FF_COLOR_FG_BLUE, FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE, FF_COLOR_FG_WHITE,
@@ -1445,6 +1462,22 @@ static const FFlogo F[] = {
.colorKeys = FF_COLOR_FG_BLUE, .colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE, .colorTitle = FF_COLOR_FG_BLUE,
}, },
// FedoraAsahiRemix
{
.names = {"fedora-asahi-remix"},
.lines = FASTFETCH_DATATEXT_LOGO_ASAHI,
.colors = {
FF_COLOR_FG_YELLOW,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_RED,
"38", //cyan
FF_COLOR_FG_WHITE,
FF_COLOR_FG_CYAN,
FF_COLOR_FG_BLUE,
},
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_GREEN,
},
// FedoraSmall // FedoraSmall
{ {
.names = {"Fedora_small", "fedora-linux-small"}, .names = {"Fedora_small", "fedora-linux-small"},
@@ -1468,6 +1501,68 @@ static const FFlogo F[] = {
.colorKeys = FF_COLOR_FG_BLUE, .colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE, .colorTitle = FF_COLOR_FG_BLUE,
}, },
// FedoraSilverblue
{
.names = {"Fedora_silverblue", "fedora-silverblue", "fedora-linux-silverblue", "fedora-linux_silverblue"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_FEDORA_SILVERBLUE,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// FedoraKinoite
{
.names = {"Fedora_kinoite", "fedora-kinoite", "fedora-linux-kinoite", "fedora-linux_kinoite"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_FEDORA_KINOITE,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// FedoraSericea
{
.names = {"Fedora_sericea", "fedora-sericea", "fedora-linux-sericea", "fedora-linux_sericea"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_FEDORA_SERICEA,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// FedoraOnyx placeholder - Currently does not have a logo
//{
//.names = {"Fedora_onyx", "fedora-onyx", "fedora-linux-onyx", "fedora-linux_onyx"},
//.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
//.lines = FASTFETCH_DATATEXT_LOGO_FEDORA_ONYX,
//.colors = {
//FF_COLOR_FG_BLUE,
//FF_COLOR_FG_WHITE,
//},
//.colorKeys = FF_COLOR_FG_BLUE,
//.colorTitle = FF_COLOR_FG_BLUE,
//},
// FedoraCoreOS
{
.names = {"Fedora_coreos", "fedora-coreos", "fedora-linux-coreos", "fedora-linux_coreos"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_FEDORA_COREOS,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_WHITE,
},
// FemboyOS // FemboyOS
{ {
.names = {"FemboyOS"}, .names = {"FemboyOS"},
@@ -3127,6 +3222,14 @@ static const FFlogo P[] = {
FF_COLOR_FG_WHITE, FF_COLOR_FG_WHITE,
}, },
}, },
// PikaOS
{
.names = {"PikaOS"},
.lines = FASTFETCH_DATATEXT_LOGO_PIKAOS,
.colors = {
FF_COLOR_FG_YELLOW,
},
},
// Pisi // Pisi
{ {
.names = {"Pisi"}, .names = {"Pisi"},
@@ -3820,6 +3923,15 @@ static const FFlogo T[] = {
FF_COLOR_FG_WHITE, FF_COLOR_FG_WHITE,
}, },
}, },
// Tatra
{
.names = {"Tatra"},
.lines = FASTFETCH_DATATEXT_LOGO_TATRA,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_GREEN,
},
},
// TeArch // TeArch
{ {
.names = {"TeArch"}, .names = {"TeArch"},
@@ -4327,6 +4439,14 @@ static const FFlogo Z[] = {
.colorKeys = FF_COLOR_FG_BLUE, .colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE, .colorTitle = FF_COLOR_FG_BLUE,
}, },
// Z/OS
{
.names = {"z/OS", "zos"},
.lines = FASTFETCH_DATATEXT_LOGO_ZOS,
.colors = {
FF_COLOR_FG_BLUE,
},
},
// LAST // LAST
{}, {},
}; };
+170
View File
@@ -0,0 +1,170 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "detection/libc/libc.h"
#include "detection/camera/camera.h"
#include "modules/camera/camera.h"
#include "util/stringUtils.h"
#define FF_CAMERA_NUM_FORMAT_ARGS 5
static void printDevice(FFCameraOptions* options, const FFCameraResult* device, uint8_t index)
{
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_CAMERA_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffStrbufWriteTo(&device->name, stdout);
if (device->colorspace.length > 0)
{
fputs(" - ", stdout);
ffStrbufWriteTo(&device->colorspace, stdout);
}
if (device->width > 0 && device->height > 0)
printf(" (%ux%u px)\n", (unsigned) device->width, (unsigned) device->height);
else
putchar('\n');
}
else
{
ffPrintFormat(FF_CAMERA_MODULE_NAME, index, &options->moduleArgs, FF_CAMERA_NUM_FORMAT_ARGS, (FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &device->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->vendor},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->colorspace},
{FF_FORMAT_ARG_TYPE_STRBUF, &device->id},
{FF_FORMAT_ARG_TYPE_UINT, &device->width},
{FF_FORMAT_ARG_TYPE_UINT, &device->height},
});
}
}
void ffPrintCamera(FFCameraOptions* options)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFCameraResult));
const char* error = ffDetectCamera(&result);
if (error)
{
ffPrintError(FF_CAMERA_MODULE_NAME, 0, &options->moduleArgs, "%s", error);
return;
}
if (result.length == 0)
{
ffPrintError(FF_CAMERA_MODULE_NAME, 0, &options->moduleArgs, "No camera found");
return;
}
for(uint32_t i = 0; i < result.length; i++)
{
uint8_t index = (uint8_t) (result.length == 1 ? 0 : i + 1);
printDevice(options, FF_LIST_GET(FFCameraResult, result, i), index);
}
FF_LIST_FOR_EACH(FFCameraResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->id);
ffStrbufDestroy(&dev->colorspace);
}
}
bool ffParseCameraCommandOptions(FFCameraOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_CAMERA_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
return false;
}
void ffParseCameraJsonObject(FFCameraOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
ffPrintError(FF_CAMERA_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
void ffGenerateCameraJsonConfig(FFCameraOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyCameraOptions))) FFCameraOptions defaultOptions;
ffInitCameraOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
}
void ffGenerateCameraJsonResult(FF_MAYBE_UNUSED FFCameraOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFCameraResult));
const char* error = ffDetectCamera(&result);
if (error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(FFCameraResult, dev, result)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &dev->vendor);
yyjson_mut_obj_add_strbuf(doc, obj, "colorSpace", &dev->colorspace);
yyjson_mut_obj_add_strbuf(doc, obj, "id", &dev->id);
yyjson_mut_obj_add_uint(doc, obj, "width", dev->width);
yyjson_mut_obj_add_uint(doc, obj, "height", dev->height);
}
FF_LIST_FOR_EACH(FFCameraResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->id);
ffStrbufDestroy(&dev->colorspace);
}
}
void ffPrintCameraHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_CAMERA_MODULE_NAME, "{1} ({4}px x {5}px)", FF_CAMERA_NUM_FORMAT_ARGS, (const char* []) {
"Device name",
"Vendor",
"Color space",
"Identifier",
"Width (in px)",
"Height (in px)",
});
}
void ffInitCameraOptions(FFCameraOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_CAMERA_MODULE_NAME,
"Print available cameras",
ffParseCameraCommandOptions,
ffParseCameraJsonObject,
ffPrintCamera,
ffGenerateCameraJsonResult,
ffPrintCameraHelpFormat,
ffGenerateCameraJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs);
}
void ffDestroyCameraOptions(FFCameraOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_CAMERA_MODULE_NAME "Camera"
void ffPrintCamera(FFCameraOptions* options);
void ffInitCameraOptions(FFCameraOptions* options);
void ffDestroyCameraOptions(FFCameraOptions* options);
+11
View File
@@ -0,0 +1,11 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFCameraOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
} FFCameraOptions;
+37 -63
View File
@@ -9,7 +9,7 @@
#pragma GCC diagnostic ignored "-Wformat" // warning: unknown conversion type character 'F' in format #pragma GCC diagnostic ignored "-Wformat" // warning: unknown conversion type character 'F' in format
#define FF_DATETIME_DISPLAY_NAME "Date & Time" #define FF_DATETIME_DISPLAY_NAME "Date & Time"
#define FF_DATETIME_NUM_FORMAT_ARGS 20 #define FF_DATETIME_NUM_FORMAT_ARGS 22
typedef struct FFDateTimeResult typedef struct FFDateTimeResult
{ {
@@ -17,23 +17,25 @@ typedef struct FFDateTimeResult
uint16_t year; //2022 uint16_t year; //2022
uint8_t yearShort; //22 uint8_t yearShort; //22
uint8_t month; //2 uint8_t month; //2
FFstrbuf monthPretty; //02 char monthPretty[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //02
FFstrbuf monthName; //February char monthName[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //February
FFstrbuf monthNameShort; //Feb char monthNameShort[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //Feb
uint8_t week; //8 uint8_t week; //8
FFstrbuf weekday; //Monday char weekday[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //Monday
FFstrbuf weekdayShort; //Mon char weekdayShort[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //Mon
uint16_t dayInYear; //52 uint16_t dayInYear; //52
uint8_t dayInMonth; //21 uint8_t dayInMonth; //21
uint8_t dayInWeek; //1 uint8_t dayInWeek; //1
uint8_t hour; //15 uint8_t hour; //15
FFstrbuf hourPretty; //15 char hourPretty[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //15
uint8_t hour12; //3 uint8_t hour12; //3
FFstrbuf hour12Pretty; //03 char hour12Pretty[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //03
uint8_t minute; //18 uint8_t minute; //18
FFstrbuf minutePretty; //18 char minutePretty[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //18
uint8_t second; //37 uint8_t second; //37
FFstrbuf secondPretty; //37 char secondPretty[FASTFETCH_STRBUF_DEFAULT_ALLOC]; //37
char offsetFromUtc[FASTFETCH_STRBUF_DEFAULT_ALLOC];
char timezoneName[FASTFETCH_STRBUF_DEFAULT_ALLOC];
} FFDateTimeResult; } FFDateTimeResult;
void ffPrintDateTimeFormat(struct tm* tm, const FFModuleArgs* moduleArgs) void ffPrintDateTimeFormat(struct tm* tm, const FFModuleArgs* moduleArgs)
@@ -43,80 +45,50 @@ void ffPrintDateTimeFormat(struct tm* tm, const FFModuleArgs* moduleArgs)
result.year = (uint16_t) (tm->tm_year + 1900); result.year = (uint16_t) (tm->tm_year + 1900);
result.yearShort = (uint8_t) (result.year % 100); result.yearShort = (uint8_t) (result.year % 100);
result.month = (uint8_t) (tm->tm_mon + 1); result.month = (uint8_t) (tm->tm_mon + 1);
strftime(result.monthPretty, sizeof(result.monthPretty), "%m", tm);
ffStrbufInitA(&result.monthPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC); strftime(result.monthName, sizeof(result.monthName), "%B", tm);
result.monthPretty.length = (uint32_t) strftime(result.monthPretty.chars, ffStrbufGetFree(&result.monthPretty), "%m", tm); strftime(result.monthNameShort, sizeof(result.monthNameShort), "%b", tm);
ffStrbufInitA(&result.monthName, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.monthName.length = (uint32_t) strftime(result.monthName.chars, ffStrbufGetFree(&result.monthName), "%B", tm);
ffStrbufInitA(&result.monthNameShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.monthNameShort.length = (uint32_t) strftime(result.monthNameShort.chars, ffStrbufGetFree(&result.monthNameShort), "%b", tm);
result.week = (uint8_t) (tm->tm_yday / 7 + 1); result.week = (uint8_t) (tm->tm_yday / 7 + 1);
strftime(result.weekday, sizeof(result.weekday), "%A", tm);
ffStrbufInitA(&result.weekday, FASTFETCH_STRBUF_DEFAULT_ALLOC); strftime(result.weekdayShort, sizeof(result.weekdayShort), "%a", tm);
result.weekday.length = (uint32_t) strftime(result.weekday.chars, ffStrbufGetFree(&result.weekday), "%A", tm);
ffStrbufInitA(&result.weekdayShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.weekdayShort.length = (uint32_t) strftime(result.weekdayShort.chars, ffStrbufGetFree(&result.weekdayShort), "%a", tm);
result.dayInYear = (uint8_t) (tm->tm_yday + 1); result.dayInYear = (uint8_t) (tm->tm_yday + 1);
result.dayInMonth = (uint8_t) tm->tm_mday; result.dayInMonth = (uint8_t) tm->tm_mday;
result.dayInWeek = tm->tm_wday == 0 ? 7 : (uint8_t) tm->tm_wday; result.dayInWeek = tm->tm_wday == 0 ? 7 : (uint8_t) tm->tm_wday;
result.hour = (uint8_t) tm->tm_hour; result.hour = (uint8_t) tm->tm_hour;
strftime(result.hourPretty, sizeof(result.hourPretty), "%H", tm);
ffStrbufInitA(&result.hourPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.hourPretty.length = (uint32_t) strftime(result.hourPretty.chars, ffStrbufGetFree(&result.hourPretty), "%H", tm);
result.hour12 = (uint8_t) (result.hour % 12); result.hour12 = (uint8_t) (result.hour % 12);
strftime(result.hour12Pretty, sizeof(result.hour12Pretty), "%I", tm);
ffStrbufInitA(&result.hour12Pretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.hour12Pretty.length = (uint32_t) strftime(result.hour12Pretty.chars, ffStrbufGetFree(&result.hour12Pretty), "%I", tm);
result.minute = (uint8_t) tm->tm_min; result.minute = (uint8_t) tm->tm_min;
strftime(result.minutePretty, sizeof(result.minutePretty), "%M", tm);
ffStrbufInitA(&result.minutePretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.minutePretty.length = (uint32_t) strftime(result.minutePretty.chars, ffStrbufGetFree(&result.minutePretty), "%M", tm);
result.second = (uint8_t) tm->tm_sec; result.second = (uint8_t) tm->tm_sec;
strftime(result.secondPretty, sizeof(result.secondPretty), "%S", tm);
ffStrbufInitA(&result.secondPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC); strftime(result.offsetFromUtc, sizeof(result.offsetFromUtc), "%z", tm);
result.secondPretty.length = (uint32_t) strftime(result.secondPretty.chars, ffStrbufGetFree(&result.secondPretty), "%S", tm); strftime(result.timezoneName, sizeof(result.timezoneName), "%Z", tm);
ffPrintFormat(FF_DATETIME_DISPLAY_NAME, 0, moduleArgs, FF_DATETIME_NUM_FORMAT_ARGS, (FFformatarg[]) { ffPrintFormat(FF_DATETIME_DISPLAY_NAME, 0, moduleArgs, FF_DATETIME_NUM_FORMAT_ARGS, (FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_UINT16, &result.year}, // 1 {FF_FORMAT_ARG_TYPE_UINT16, &result.year}, // 1
{FF_FORMAT_ARG_TYPE_UINT8, &result.yearShort}, // 2 {FF_FORMAT_ARG_TYPE_UINT8, &result.yearShort}, // 2
{FF_FORMAT_ARG_TYPE_UINT8, &result.month}, // 3 {FF_FORMAT_ARG_TYPE_UINT8, &result.month}, // 3
{FF_FORMAT_ARG_TYPE_STRBUF, &result.monthPretty}, // 4 {FF_FORMAT_ARG_TYPE_STRING, result.monthPretty}, // 4
{FF_FORMAT_ARG_TYPE_STRBUF, &result.monthName}, // 5 {FF_FORMAT_ARG_TYPE_STRING, result.monthName}, // 5
{FF_FORMAT_ARG_TYPE_STRBUF, &result.monthNameShort}, // 6 {FF_FORMAT_ARG_TYPE_STRING, result.monthNameShort}, // 6
{FF_FORMAT_ARG_TYPE_UINT8, &result.week}, // 7 {FF_FORMAT_ARG_TYPE_UINT8, &result.week}, // 7
{FF_FORMAT_ARG_TYPE_STRBUF, &result.weekday}, // 8 {FF_FORMAT_ARG_TYPE_STRING, result.weekday}, // 8
{FF_FORMAT_ARG_TYPE_STRBUF, &result.weekdayShort}, // 9 {FF_FORMAT_ARG_TYPE_STRING, result.weekdayShort}, // 9
{FF_FORMAT_ARG_TYPE_UINT16, &result.dayInYear}, // 10 {FF_FORMAT_ARG_TYPE_UINT16, &result.dayInYear}, // 10
{FF_FORMAT_ARG_TYPE_UINT8, &result.dayInMonth}, // 11 {FF_FORMAT_ARG_TYPE_UINT8, &result.dayInMonth}, // 11
{FF_FORMAT_ARG_TYPE_UINT8, &result.dayInWeek}, // 12 {FF_FORMAT_ARG_TYPE_UINT8, &result.dayInWeek}, // 12
{FF_FORMAT_ARG_TYPE_UINT8, &result.hour}, // 13 {FF_FORMAT_ARG_TYPE_UINT8, &result.hour}, // 13
{FF_FORMAT_ARG_TYPE_STRBUF, &result.hourPretty}, // 14 {FF_FORMAT_ARG_TYPE_STRING, result.hourPretty}, // 14
{FF_FORMAT_ARG_TYPE_UINT8, &result.hour12}, // 15 {FF_FORMAT_ARG_TYPE_UINT8, &result.hour12}, // 15
{FF_FORMAT_ARG_TYPE_STRBUF, &result.hour12Pretty}, // 16 {FF_FORMAT_ARG_TYPE_STRING, result.hour12Pretty}, // 16
{FF_FORMAT_ARG_TYPE_UINT8, &result.minute}, // 17 {FF_FORMAT_ARG_TYPE_UINT8, &result.minute}, // 17
{FF_FORMAT_ARG_TYPE_STRBUF, &result.minutePretty}, // 18 {FF_FORMAT_ARG_TYPE_STRING, result.minutePretty}, // 18
{FF_FORMAT_ARG_TYPE_UINT8, &result.second}, // 19 {FF_FORMAT_ARG_TYPE_UINT8, &result.second}, // 19
{FF_FORMAT_ARG_TYPE_STRBUF, &result.secondPretty} // 20 {FF_FORMAT_ARG_TYPE_STRING, result.secondPretty}, // 20
{FF_FORMAT_ARG_TYPE_STRING, result.offsetFromUtc}, // 21
{FF_FORMAT_ARG_TYPE_STRING, result.timezoneName}, // 22
}); });
ffStrbufDestroy(&result.hour12Pretty);
ffStrbufDestroy(&result.hourPretty);
ffStrbufDestroy(&result.minutePretty);
ffStrbufDestroy(&result.monthName);
ffStrbufDestroy(&result.monthNameShort);
ffStrbufDestroy(&result.monthPretty);
ffStrbufDestroy(&result.secondPretty);
ffStrbufDestroy(&result.weekday);
ffStrbufDestroy(&result.weekdayShort);
} }
void ffPrintDateTime(FFDateTimeOptions* options) void ffPrintDateTime(FFDateTimeOptions* options)
@@ -205,7 +177,9 @@ void ffPrintDateTimeHelpFormat(void)
"minute", "minute",
"minute with leading zero", "minute with leading zero",
"second", "second",
"second with leading zero" "second with leading zero",
"offset from UTC in the ISO 8601 format",
"locale-dependent timezone name or abbreviation",
}); });
} }
+2
View File
@@ -8,6 +8,7 @@
#include "modules/brightness/brightness.h" #include "modules/brightness/brightness.h"
#include "modules/board/board.h" #include "modules/board/board.h"
#include "modules/break/break.h" #include "modules/break/break.h"
#include "modules/camera/camera.h"
#include "modules/chassis/chassis.h" #include "modules/chassis/chassis.h"
#include "modules/cpu/cpu.h" #include "modules/cpu/cpu.h"
#include "modules/cpuusage/cpuusage.h" #include "modules/cpuusage/cpuusage.h"
@@ -49,6 +50,7 @@
#include "modules/terminal/terminal.h" #include "modules/terminal/terminal.h"
#include "modules/terminalfont/terminalfont.h" #include "modules/terminalfont/terminalfont.h"
#include "modules/terminalsize/terminalsize.h" #include "modules/terminalsize/terminalsize.h"
#include "modules/terminaltheme/terminaltheme.h"
#include "modules/theme/theme.h" #include "modules/theme/theme.h"
#include "modules/title/title.h" #include "modules/title/title.h"
#include "modules/uptime/uptime.h" #include "modules/uptime/uptime.h"
+2
View File
@@ -8,6 +8,7 @@
#include "modules/board/option.h" #include "modules/board/option.h"
#include "modules/break/option.h" #include "modules/break/option.h"
#include "modules/brightness/option.h" #include "modules/brightness/option.h"
#include "modules/camera/option.h"
#include "modules/chassis/option.h" #include "modules/chassis/option.h"
#include "modules/cpu/option.h" #include "modules/cpu/option.h"
#include "modules/cpuusage/option.h" #include "modules/cpuusage/option.h"
@@ -49,6 +50,7 @@
#include "modules/terminal/option.h" #include "modules/terminal/option.h"
#include "modules/terminalfont/option.h" #include "modules/terminalfont/option.h"
#include "modules/terminalsize/option.h" #include "modules/terminalsize/option.h"
#include "modules/terminaltheme/option.h"
#include "modules/theme/option.h" #include "modules/theme/option.h"
#include "modules/title/option.h" #include "modules/title/option.h"
#include "modules/uptime/option.h" #include "modules/uptime/option.h"
-2
View File
@@ -33,8 +33,6 @@ void ffPrintPowerAdapter(FFPowerAdapterOptions* options)
if(result->name.length > 0) if(result->name.length > 0)
puts(result->name.chars); puts(result->name.chars);
else if(result->watts == FF_POWERADAPTER_NOT_CONNECTED)
puts("not connected");
else else
printf("%dW\n", result->watts); printf("%dW\n", result->watts);
} }
+11
View File
@@ -0,0 +1,11 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFTerminalThemeOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
} FFTerminalThemeOptions;
+134
View File
@@ -0,0 +1,134 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "detection/terminaltheme/terminaltheme.h"
#include "modules/terminaltheme/terminaltheme.h"
#include "util/stringUtils.h"
#include <inttypes.h>
#define FF_TERMINALTHEME_DISPLAY_NAME "Terminal Theme"
#define FF_TERMINALTHEME_NUM_FORMAT_ARGS 4
void ffPrintTerminalTheme(FFTerminalThemeOptions* options)
{
FFTerminalThemeResult result = {};
if(!ffDetectTerminalTheme(&result))
{
ffPrintError(FF_TERMINALTHEME_DISPLAY_NAME, 0, &options->moduleArgs, "Failed to detect terminal theme");
}
else
{
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_TERMINALTHEME_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
printf("#%02" PRIX16 "%02" PRIX16 "%02" PRIX16 " (FG) - #%02" PRIX16 "%02" PRIX16 "%02" PRIX16 " (BG) [%s]\n",
result.fg.r, result.fg.g, result.fg.b,
result.bg.r, result.bg.g, result.bg.b,
result.bg.dark ? "Dark" : "Light");
}
else
{
char fg[32], bg[32];
snprintf(fg, sizeof(fg), "#%02" PRIX16 "%02" PRIX16 "%02" PRIX16, result.fg.r, result.fg.g, result.fg.b);
snprintf(bg, sizeof(bg), "#%02" PRIX16 "%02" PRIX16 "%02" PRIX16, result.bg.r, result.bg.g, result.bg.b);
ffPrintFormat(FF_TERMINALTHEME_DISPLAY_NAME, 0, &options->moduleArgs, FF_TERMINALTHEME_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRING, fg},
{FF_FORMAT_ARG_TYPE_STRING, result.fg.dark ? "Dark" : "Light"},
{FF_FORMAT_ARG_TYPE_STRING, bg},
{FF_FORMAT_ARG_TYPE_STRING, result.bg.dark ? "Dark" : "Light"},
});
}
}
}
bool ffParseTerminalThemeCommandOptions(FFTerminalThemeOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_TERMINALTHEME_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
return false;
}
void ffParseTerminalThemeJsonObject(FFTerminalThemeOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
ffPrintError(FF_TERMINALTHEME_DISPLAY_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
void ffGenerateTerminalThemeJsonConfig(FFTerminalThemeOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyTerminalThemeOptions))) FFTerminalThemeOptions defaultOptions;
ffInitTerminalThemeOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
}
void ffGenerateTerminalThemeJsonResult(FF_MAYBE_UNUSED FFTerminalOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FFTerminalThemeResult result = {};
if(!ffDetectTerminalTheme(&result))
{
yyjson_mut_obj_add_str(doc, module, "error", "Failed to detect terminal theme");
return;
}
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
yyjson_mut_val* fg = yyjson_mut_obj_add_obj(doc, obj, "fg");
yyjson_mut_obj_add_uint(doc, fg, "r", result.fg.r);
yyjson_mut_obj_add_uint(doc, fg, "g", result.fg.g);
yyjson_mut_obj_add_uint(doc, fg, "b", result.fg.b);
yyjson_mut_obj_add_bool(doc, fg, "dark", result.fg.dark);
yyjson_mut_val* bg = yyjson_mut_obj_add_obj(doc, obj, "bg");
yyjson_mut_obj_add_uint(doc, bg, "r", result.bg.r);
yyjson_mut_obj_add_uint(doc, bg, "g", result.bg.g);
yyjson_mut_obj_add_uint(doc, bg, "b", result.bg.b);
yyjson_mut_obj_add_bool(doc, bg, "dark", result.bg.dark);
}
void ffPrintTerminalThemeHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_TERMINALTHEME_MODULE_NAME, "{1} (FG) {3} (BG) [{4}]", FF_TERMINALTHEME_NUM_FORMAT_ARGS, (const char* []) {
"Terminal foreground color",
"Terminal foreground type (Dark / Light)",
"Terminal background color",
"Terminal background type (Dark / Light)",
});
}
void ffInitTerminalThemeOptions(FFTerminalThemeOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_TERMINALTHEME_MODULE_NAME,
"Print current terminal theme (foreground and background colors)",
ffParseTerminalThemeCommandOptions,
ffParseTerminalThemeJsonObject,
ffPrintTerminalTheme,
ffGenerateTerminalThemeJsonResult,
ffPrintTerminalThemeHelpFormat,
ffGenerateTerminalThemeJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs);
}
void ffDestroyTerminalThemeOptions(FFTerminalThemeOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_TERMINALTHEME_MODULE_NAME "TerminalTheme"
void ffPrintTerminalTheme(FFTerminalThemeOptions* options);
void ffInitTerminalThemeOptions(FFTerminalThemeOptions* options);
void ffDestroyTerminalThemeOptions(FFTerminalThemeOptions* options);
-7
View File
@@ -29,8 +29,6 @@ const char* ffOptionsParseLibraryJsonConfig(FFOptionsLibrary* options, yyjson_va
ffStrbufSetS(&options->libZ, yyjson_get_str(val)); ffStrbufSetS(&options->libZ, yyjson_get_str(val));
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
else if (ffStrEqualsIgnCase(key, "pci"))
ffStrbufSetS(&options->libPCI, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "freetype")) else if (ffStrEqualsIgnCase(key, "freetype"))
ffStrbufSetS(&options->libfreetype, yyjson_get_str(val)); ffStrbufSetS(&options->libfreetype, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "wayland")) else if (ffStrEqualsIgnCase(key, "wayland"))
@@ -95,8 +93,6 @@ bool ffOptionsParseLibraryCommandLine(FFOptionsLibrary* options, const char* key
ffOptionParseString(key, value, &options->libZ); ffOptionParseString(key, value, &options->libZ);
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
else if(ffStrEqualsIgnCase(subkey, "PCI"))
ffOptionParseString(key, value, &options->libPCI);
else if(ffStrEqualsIgnCase(subkey, "freetype")) else if(ffStrEqualsIgnCase(subkey, "freetype"))
ffOptionParseString(key, value, &options->libfreetype); ffOptionParseString(key, value, &options->libfreetype);
else if(ffStrEqualsIgnCase(subkey, "wayland")) else if(ffStrEqualsIgnCase(subkey, "wayland"))
@@ -183,9 +179,6 @@ void ffOptionsGenerateLibraryJsonConfig(FFOptionsLibrary* options, yyjson_mut_do
yyjson_mut_obj_add_strbuf(doc, obj, "z", &options->libZ); yyjson_mut_obj_add_strbuf(doc, obj, "z", &options->libZ);
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
if (!ffStrbufEqual(&options->libPCI, &defaultOptions.libPCI))
yyjson_mut_obj_add_strbuf(doc, obj, "PCI", &options->libPCI);
if (!ffStrbufEqual(&options->libWayland, &defaultOptions.libWayland)) if (!ffStrbufEqual(&options->libWayland, &defaultOptions.libWayland))
yyjson_mut_obj_add_strbuf(doc, obj, "wayland", &options->libWayland); yyjson_mut_obj_add_strbuf(doc, obj, "wayland", &options->libWayland);
-1
View File
@@ -12,7 +12,6 @@ typedef struct FFOptionsLibrary
FFstrbuf libZ; FFstrbuf libZ;
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
FFstrbuf libPCI;
FFstrbuf libWayland; FFstrbuf libWayland;
FFstrbuf libXcbRandr; FFstrbuf libXcbRandr;
FFstrbuf libXcb; FFstrbuf libXcb;
+6 -2
View File
@@ -9,6 +9,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitBoardOptions(&options->board); ffInitBoardOptions(&options->board);
ffInitBreakOptions(&options->break_); ffInitBreakOptions(&options->break_);
ffInitBrightnessOptions(&options->brightness); ffInitBrightnessOptions(&options->brightness);
ffInitCameraOptions(&options->camera);
ffInitCPUOptions(&options->cpu); ffInitCPUOptions(&options->cpu);
ffInitCPUUsageOptions(&options->cpuUsage); ffInitCPUUsageOptions(&options->cpuUsage);
ffInitChassisOptions(&options->chassis); ffInitChassisOptions(&options->chassis);
@@ -47,9 +48,10 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitShellOptions(&options->shell); ffInitShellOptions(&options->shell);
ffInitSoundOptions(&options->sound); ffInitSoundOptions(&options->sound);
ffInitSwapOptions(&options->swap); ffInitSwapOptions(&options->swap);
ffInitTerminalFontOptions(&options->terminalFont);
ffInitTerminalOptions(&options->terminal); ffInitTerminalOptions(&options->terminal);
ffInitTerminalFontOptions(&options->terminalFont);
ffInitTerminalSizeOptions(&options->terminalSize); ffInitTerminalSizeOptions(&options->terminalSize);
ffInitTerminalThemeOptions(&options->terminalTheme);
ffInitThemeOptions(&options->theme); ffInitThemeOptions(&options->theme);
ffInitTitleOptions(&options->title); ffInitTitleOptions(&options->title);
ffInitUptimeOptions(&options->uptime); ffInitUptimeOptions(&options->uptime);
@@ -71,6 +73,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyBoardOptions(&options->board); ffDestroyBoardOptions(&options->board);
ffDestroyBreakOptions(&options->break_); ffDestroyBreakOptions(&options->break_);
ffDestroyBrightnessOptions(&options->brightness); ffDestroyBrightnessOptions(&options->brightness);
ffDestroyCameraOptions(&options->camera);
ffDestroyCPUOptions(&options->cpu); ffDestroyCPUOptions(&options->cpu);
ffDestroyCPUUsageOptions(&options->cpuUsage); ffDestroyCPUUsageOptions(&options->cpuUsage);
ffDestroyChassisOptions(&options->chassis); ffDestroyChassisOptions(&options->chassis);
@@ -109,9 +112,10 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyShellOptions(&options->shell); ffDestroyShellOptions(&options->shell);
ffDestroySoundOptions(&options->sound); ffDestroySoundOptions(&options->sound);
ffDestroySwapOptions(&options->swap); ffDestroySwapOptions(&options->swap);
ffDestroyTerminalFontOptions(&options->terminalFont);
ffDestroyTerminalOptions(&options->terminal); ffDestroyTerminalOptions(&options->terminal);
ffDestroyTerminalFontOptions(&options->terminalFont);
ffDestroyTerminalSizeOptions(&options->terminalSize); ffDestroyTerminalSizeOptions(&options->terminalSize);
ffDestroyTerminalThemeOptions(&options->terminalTheme);
ffDestroyThemeOptions(&options->theme); ffDestroyThemeOptions(&options->theme);
ffDestroyTitleOptions(&options->title); ffDestroyTitleOptions(&options->title);
ffDestroyUptimeOptions(&options->uptime); ffDestroyUptimeOptions(&options->uptime);
+3 -1
View File
@@ -12,6 +12,7 @@ typedef struct FFOptionsModules
FFBrightnessOptions brightness; FFBrightnessOptions brightness;
FFCPUOptions cpu; FFCPUOptions cpu;
FFCPUUsageOptions cpuUsage; FFCPUUsageOptions cpuUsage;
FFCameraOptions camera;
FFChassisOptions chassis; FFChassisOptions chassis;
FFColorsOptions colors; FFColorsOptions colors;
FFCommandOptions command; FFCommandOptions command;
@@ -48,9 +49,10 @@ typedef struct FFOptionsModules
FFShellOptions shell; FFShellOptions shell;
FFSoundOptions sound; FFSoundOptions sound;
FFSwapOptions swap; FFSwapOptions swap;
FFTerminalFontOptions terminalFont;
FFTerminalOptions terminal; FFTerminalOptions terminal;
FFTerminalFontOptions terminalFont;
FFTerminalSizeOptions terminalSize; FFTerminalSizeOptions terminalSize;
FFTerminalThemeOptions terminalTheme;
FFThemeOptions theme; FFThemeOptions theme;
FFTitleOptions title; FFTitleOptions title;
FFUptimeOptions uptime; FFUptimeOptions uptime;
+16 -8
View File
@@ -17,23 +17,31 @@
static void getExePath(FFPlatform* platform) static void getExePath(FFPlatform* platform)
{ {
FFstrbuf* const exePath = &platform->exePath; char exePath[PATH_MAX + 1];
ffStrbufEnsureFree(exePath, PATH_MAX);
#ifdef __linux__ #ifdef __linux__
ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated - 1); ssize_t exePathLen = readlink("/proc/self/exe", exePath, sizeof(exePath) - 1);
exePath[exePathLen] = '\0';
#elif defined(__APPLE__) #elif defined(__APPLE__)
int exePathLen = proc_pidpath((int) getpid(), exePath->chars, exePath->allocated); int exePathLen = proc_pidpath((int) getpid(), exePath, sizeof(exePath));
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
size_t exePathLen = exePath->allocated; size_t exePathLen = sizeof(exePath);
if(sysctl( if(sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, (int) getpid()}, 4, (int[]){CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, (int) getpid()}, 4,
exePath->chars, &exePathLen, exePath, &exePathLen,
NULL, 0 NULL, 0
)) ) < 0)
exePathLen = 0; exePathLen = 0;
else
exePathLen--; // remove terminating NUL
#endif #endif
if (exePathLen > 0) if (exePathLen > 0)
exePath->length = (uint32_t) exePathLen; {
ffStrbufEnsureFree(&platform->exePath, PATH_MAX);
if (realpath(platform->exePath.chars, exePath))
ffStrbufRecalculateLength(&platform->exePath);
else
ffStrbufSetNS(&platform->exePath, (uint32_t) exePathLen, exePath);
}
} }
static void platformPathAddEnv(FFlist* dirs, const char* env) static void platformPathAddEnv(FFlist* dirs, const char* env)
+23 -3
View File
@@ -18,6 +18,14 @@ static void getExePath(FFPlatform* platform)
DWORD exePathWLen = GetModuleFileNameW(NULL, exePathW, MAX_PATH); DWORD exePathWLen = GetModuleFileNameW(NULL, exePathW, MAX_PATH);
if (exePathWLen == 0 && exePathWLen >= MAX_PATH) return; if (exePathWLen == 0 && exePathWLen >= MAX_PATH) return;
FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW(exePathW, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hPath != INVALID_HANDLE_VALUE)
{
DWORD len = GetFinalPathNameByHandleW(hPath, exePathW, MAX_PATH, FILE_NAME_OPENED);
if (len > 0 && len < MAX_PATH)
exePathWLen = len;
}
ffStrbufSetNWS(&platform->exePath, exePathWLen, exePathW); ffStrbufSetNWS(&platform->exePath, exePathWLen, exePathW);
if (ffStrbufStartsWithS(&platform->exePath, "\\\\?\\")) if (ffStrbufStartsWithS(&platform->exePath, "\\\\?\\"))
ffStrbufSubstrAfter(&platform->exePath, 3); ffStrbufSubstrAfter(&platform->exePath, 3);
@@ -32,8 +40,14 @@ static void getHomeDir(FFPlatform* platform)
ffStrbufSetWS(&platform->homeDir, pPath); ffStrbufSetWS(&platform->homeDir, pPath);
ffStrbufReplaceAllC(&platform->homeDir, '\\', '/'); ffStrbufReplaceAllC(&platform->homeDir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->homeDir, '/'); ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
}
CoTaskMemFree(pPath); CoTaskMemFree(pPath);
}
else
{
ffStrbufSetS(&platform->homeDir, getenv("USERPROFILE"));
ffStrbufReplaceAllC(&platform->homeDir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->homeDir, '/');
}
} }
static void getCacheDir(FFPlatform* platform) static void getCacheDir(FFPlatform* platform)
@@ -44,13 +58,13 @@ static void getCacheDir(FFPlatform* platform)
ffStrbufSetWS(&platform->cacheDir, pPath); ffStrbufSetWS(&platform->cacheDir, pPath);
ffStrbufReplaceAllC(&platform->cacheDir, '\\', '/'); ffStrbufReplaceAllC(&platform->cacheDir, '\\', '/');
ffStrbufEnsureEndsWithC(&platform->cacheDir, '/'); ffStrbufEnsureEndsWithC(&platform->cacheDir, '/');
CoTaskMemFree(pPath);
} }
else else
{ {
ffStrbufAppend(&platform->cacheDir, &platform->homeDir); ffStrbufAppend(&platform->cacheDir, &platform->homeDir);
ffStrbufAppendS(&platform->cacheDir, "AppData/Local/"); ffStrbufAppendS(&platform->cacheDir, "AppData/Local/");
} }
CoTaskMemFree(pPath);
} }
static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId)
@@ -63,8 +77,8 @@ static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId)
ffStrbufEnsureEndsWithC(&buffer, '/'); ffStrbufEnsureEndsWithC(&buffer, '/');
if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual)) if (!ffListContains(dirs, &buffer, (void*) ffStrbufEqual))
ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer); ffStrbufInitMove((FFstrbuf*) ffListAdd(dirs), &buffer);
}
CoTaskMemFree(pPath); CoTaskMemFree(pPath);
}
} }
static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix) static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix)
@@ -122,10 +136,16 @@ static void getDataDirs(FFPlatform* platform)
static void getUserName(FFPlatform* platform) static void getUserName(FFPlatform* platform)
{ {
const char* userName = getenv("USERNAME");
if (ffStrSet(userName))
ffStrbufSetS(&platform->userName, userName);
else
{
wchar_t buffer[128]; wchar_t buffer[128];
DWORD len = sizeof(buffer) / sizeof(*buffer); DWORD len = sizeof(buffer) / sizeof(*buffer);
if(GetUserNameW(buffer, &len)) if(GetUserNameW(buffer, &len))
ffStrbufSetWS(&platform->userName, buffer); ffStrbufSetWS(&platform->userName, buffer);
}
} }
static void getHostName(FFPlatform* platform) static void getHostName(FFPlatform* platform)
+24 -10
View File
@@ -1,16 +1,12 @@
#include <oaidl.h> #include <oaidl.h>
#include <propidl.h>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <string_view> #include <string_view>
struct FFWmiVariant: VARIANT template <typename TVariant>
struct FFBaseVariant: TVariant
{ {
explicit FFWmiVariant() { VariantInit(this); }
~FFWmiVariant() { VariantClear(this); }
FFWmiVariant(const FFWmiVariant&) = delete;
FFWmiVariant(FFWmiVariant&&); // don't define it to enforce NRVO optimization
bool hasValue() { bool hasValue() {
return this->vt != VT_EMPTY; return this->vt != VT_EMPTY;
} }
@@ -33,11 +29,11 @@ struct FFWmiVariant: VARIANT
return this->cVal; return this->cVal;
} }
else if constexpr (std::is_same_v<T, int16_t>) { else if constexpr (std::is_same_v<T, int16_t>) {
assert(vt == VT_I2); assert(this->vt == VT_I2);
return this->iVal; return this->iVal;
} }
else if constexpr (std::is_same_v<T, int32_t>) { else if constexpr (std::is_same_v<T, int32_t>) {
assert(this->vt == VT_I4 || vt == VT_INT); assert(this->vt == VT_I4 || this->vt == VT_INT);
return this->intVal; return this->intVal;
} }
else if constexpr (std::is_same_v<T, int64_t>) { else if constexpr (std::is_same_v<T, int64_t>) {
@@ -55,7 +51,7 @@ struct FFWmiVariant: VARIANT
return this->uiVal; return this->uiVal;
} }
else if constexpr (std::is_same_v<T, uint32_t>) { else if constexpr (std::is_same_v<T, uint32_t>) {
assert(this->vt == VT_UI4 || vt == VT_UINT); assert(this->vt == VT_UI4 || this->vt == VT_UINT);
return this->uintVal; return this->uintVal;
} }
else if constexpr (std::is_same_v<T, uint64_t>) { else if constexpr (std::is_same_v<T, uint64_t>) {
@@ -135,3 +131,21 @@ struct FFWmiVariant: VARIANT
} }
} }
}; };
struct FFWmiVariant: FFBaseVariant<VARIANT>
{
FFWmiVariant(const FFWmiVariant&) = delete;
FFWmiVariant(FFWmiVariant&&); // don't define it to enforce NRVO optimization
explicit FFWmiVariant() { VariantInit(this); }
~FFWmiVariant() { VariantClear(this); }
};
static_assert(sizeof(FFWmiVariant) == sizeof(VARIANT), "");
struct FFPropVariant: FFBaseVariant<PROPVARIANT>
{
FFPropVariant(const FFPropVariant&) = delete;
FFPropVariant(FFPropVariant&&); // don't define it to enforce NRVO optimization
explicit FFPropVariant() { PropVariantInit(this); }
~FFPropVariant() { PropVariantClear(this); }
};
static_assert(sizeof(FFPropVariant) == sizeof(PROPVARIANT), "");