Merge pull request #2012 from fastfetch-cli/dev

Release: v2.54.0
This commit is contained in:
Carter Li
2025-10-18 10:15:23 +08:00
committed by GitHub
53 changed files with 984 additions and 373 deletions
+3
View File
@@ -0,0 +1,3 @@
github: LinusDierheimer
ko_fi: carterli
custom: https://paypal.me/zhangsongcui
+2
View File
@@ -36,3 +36,5 @@ body:
required: true
- label: The ASCII art contains color codes, or the color codes are available in `os-release`
required: true
- label: The ASCII art contains no internal paddings (spaces at the start and the end of lines)
required: true
+116 -18
View File
@@ -89,8 +89,11 @@ jobs:
- name: cat /proc/cpuinfo
run: cat /proc/cpuinfo
- name: add gcc-13 repo
run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- 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 libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev libchafa-dev directx-headers-dev rpm ninja-build
run: sudo apt-get update && sudo apt-get install -y gcc-13 g++-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev libchafa-dev directx-headers-dev rpm ninja-build
- name: install linuxbrew packages
run: |
@@ -104,7 +107,7 @@ jobs:
languages: c
- name: configure project
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: CC=gcc-13 CXX=g++-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
@@ -142,7 +145,10 @@ jobs:
strip fastfetch && ./polyfill-glibc fastfetch --target-glibc=2.17
strip flashfetch && ./polyfill-glibc flashfetch --target-glibc=2.17
echo 'set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-polyfilled")' >> CPackConfig.cmake
cpack
echo 'set(CPACK_PACKAGE_RELOCATABLE OFF)' >> CPackConfig.cmake
echo 'set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17)")' >> CPackConfig.cmake
echo 'set(CPACK_RPM_SPEC_MORE_DEFINE "%global __os_install_post %{nil}")' >> CPackConfig.cmake
cpack -V
- name: upload artifacts
uses: actions/upload-artifact@v4
@@ -150,6 +156,69 @@ jobs:
name: fastfetch-linux-${{ matrix.arch }}
path: ./fastfetch-*.*
linux-i686:
name: Linux-i686
runs-on: ubuntu-22.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v5
- name: uname -a
run: uname -a
- name: cat /etc/os-release
run: cat /etc/os-release
- name: cat /proc/cpuinfo
run: cat /proc/cpuinfo
- name: add gcc-13 repo
run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y gcc-13 gcc-13-multilib libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
- 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 --ignore-dependencies
- name: cmake version
run: cmake --version
- name: configure project
run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DCMAKE_C_FLAGS="-m32 -march=i686 -mtune=i686" -DCMAKE_SYSTEM_PROCESSOR_OVERRIDE=i686 -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_DIRECTX_HEADERS=Off .
- name: build project
run: cmake --build . --target package --verbose -j4
- name: list features
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc --stat false
- 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 --output-on-failure
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-linux-i686
path: ./fastfetch-*.*
linux-armv7l:
name: Linux-armv7l
runs-on: ubuntu-24.04
@@ -169,12 +238,13 @@ jobs:
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y ca-certificates gpg curl
apt-get update && apt-get install -y software-properties-common ca-certificates gpg curl
add-apt-repository -y ppa:ubuntu-toolchain-r/test
curl -L https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null
echo -e 'Acquire::https::Verify-Peer "false";\nAcquire::https::Verify-Host "false";' >> /etc/apt/apt.conf.d/99ignore-certificates
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 libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_DIRECTX_HEADERS=Off -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -209,8 +279,8 @@ jobs:
run: |
uname -a
apt-get update && apt-get install -y wget
apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
apt-get install -y cmake make gcc libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_DIRECTX_HEADERS=Off -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -246,12 +316,14 @@ jobs:
id: runcmd
with:
arch: ${{ matrix.arch }}
distro: ubuntu20.04
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 libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
apt-get update && apt-get install -y software-properties-common
add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev rpm
CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_DIRECTX_HEADERS=Off -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -449,8 +521,9 @@ jobs:
version: '7.7'
run: |
uname -a
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
sudo pkg_add -u
sudo pkg_add -r llvm-19.1.7p3 cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
CC=clang-19 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -485,8 +558,8 @@ jobs:
version: '10.1'
run: |
uname -a
sudo pkgin -y install cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick
CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -518,10 +591,10 @@ jobs:
prepare: |
uname -a
pkg update
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf
pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
env CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -634,17 +707,41 @@ jobs:
- name: run tests
run: ctest --output-on-failure
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
id: upload-unsigned-artifact
name: upload artifacts for signing
uses: actions/upload-artifact@v4
with:
name: fastfetch-windows-${{ matrix.arch }}
path: |
*.dll
fastfetch.exe
flashfetch.exe
- if: github.event_name == 'push' && github.repository == 'fastfetch-cli/fastfetch'
name: submit signing request
uses: signpath/github-action-submit-signing-request@v1
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '${{ vars.SIGNPATH_ORG_ID }}'
project-slug: 'fastfetch'
signing-policy-slug: ${{ github.ref == 'refs/heads/master' && 'release-signing' || 'test-signing' }}
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: '.'
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-${{ matrix.arch }}.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
- name: upload true artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-windows-${{ matrix.arch }}
path: ./fastfetch-windows-${{ matrix.arch }}.*
overwrite: true
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
@@ -652,6 +749,7 @@ jobs:
runs-on: ubuntu-latest
needs:
- linux-hosts
- linux-i686
- linux-armv7l
- linux-armv6l
- linux-vms
+44
View File
@@ -1,3 +1,47 @@
# 2.54.0
Windows binaries in Release page are now signed using SignPath.
Changes:
* Moves macOS and Windows design language detection from the DE module to the Theme module
Features:
* Adds `--json` and `-j` command line flags as a shortcut for `--format json`
* Various improvements to the OS module (OS)
* Displays point releases for Debian
* Displays code names for Ubuntu
* Displays build ID for macOS
* Displays code names for Windows (previously shown in the Kernel module)
* Adds basic support for Wine (Windows)
* Adds basic support for hppa and sh architectures (CPU, Linux)
* Improves T-Head SoC name detection from the device tree (#1997, CPU, Linux)
* Supports glob patterns in `Disk.hideFolders` (Disk)
* For example, `/boot/*` will match both `/boot/efi` and `/boot/firmware`
* Adds brightness-level detection for external monitor support on Intel macOS (Brightness, macOS)
* Adds configurable spacing between icon and text in keys
* `display.key.type: "both-N"` where N is `0-4`
* Useful for non-monospaced Nerd Fonts
* Adds detection support for modern Samsung Exynos SoCs (CPU, Android)
* Adds a new CMake option `-DENABLE_WORDEXP=<ON|OFF>` to enable or disable using `wordexp(3)` for acquiring logo file paths (`logo.source`)
* Enabled by default for compatibility
* Disabling this option reverts to using `glob(3)`, which is less functional but more secure
Bugfixes:
* Avoids integer overflow when calculating swap size (#1988, Swap, Windows)
* Trims whitespace from full user name (Title, macOS)
* Fixes default font size for Ghostty (#1986, TerminalFont, Linux)
* Works around an issue that could report impossibly high memory usage in rare cases (#1988, Memory, Linux)
* Fixes incorrect glibc dependency in polyfilled DEB packages (#1983, Linux)
* Fixes corrupted binaries in polyfilled RPM packages (#1990, Linux)
* Fixes crashes on ancient Android kernels (#1993, Disk, Android)
* Fixes incorrect usage of `glob(3)` (OpenBSD)
* Prefers resolutions reported by RandR mode info, fixing incorrect resolutions on XFCE when DPI scaling is enabled (Display, Linux)
* Various code cleanups and minor fixes
Logos:
* Adds secureblue, PrismLinux, EmperorOS and Zraxyl
* Updates T2
# 2.53.0
Changes:
+35 -28
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.53.0
VERSION 2.54.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -9,6 +9,17 @@ project(fastfetch
set(PROJECT_LICENSE "MIT license")
if(DEFINED CMAKE_SYSTEM_PROCESSOR_OVERRIDE) # Used by github actions for i686 build
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR_OVERRIDE} CACHE INTERNAL "")
endif()
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" CMAKE_SYSTEM_PROCESSOR)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CMAKE_SYSTEM_PROCESSOR "amd64")
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(CMAKE_SYSTEM_PROCESSOR "aarch64")
endif()
message(STATUS "Build for system processor: ${CMAKE_SYSTEM_PROCESSOR}")
###################
# Target Platform #
###################
@@ -95,6 +106,7 @@ option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
option(ENABLE_EMBEDDED_AMDGPUIDS "Embed amdgpu.ids into fastfetch, requires `python`" OFF)
option(ENABLE_WORDEXP "Enable using of wordexp(3) if available, instead of glob(3)" ON)
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
@@ -963,7 +975,7 @@ elseif(APPLE)
src/detection/terminalfont/terminalfont_apple.m
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/theme/theme_apple.c
src/detection/tpm/tpm_apple.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
@@ -1024,7 +1036,7 @@ elseif(WIN32)
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/netio/netio_windows.c
src/detection/opengl/opengl_windows.c
src/detection/os/os_windows.c
src/detection/os/os_windows.cpp
src/detection/packages/packages_windows.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_windows.c
@@ -1033,7 +1045,7 @@ elseif(WIN32)
src/detection/terminalfont/terminalfont_windows.c
src/detection/terminalshell/terminalshell_windows.c
src/detection/terminalsize/terminalsize_windows.c
src/detection/theme/theme_nosupport.c
src/detection/theme/theme_windows.c
src/detection/tpm/tpm_windows.c
src/detection/uptime/uptime_windows.c
src/detection/users/users_windows.c
@@ -1678,11 +1690,10 @@ elseif(WIN32)
PRIVATE "wtsapi32"
PRIVATE "imagehlp"
PRIVATE "cfgmgr32"
PRIVATE "winbrand"
PRIVATE "propsys"
PRIVATE "secur32"
)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
# WoA only works on Windows 10 or higher
target_link_libraries(libfastfetch
PRIVATE "mincore"
@@ -1733,17 +1744,20 @@ elseif(ANDROID)
target_link_libraries(libfastfetch
PRIVATE "m"
)
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
if(HAVE_LIBANDROID_WORDEXP_STATIC)
target_link_libraries(libfastfetch
PRIVATE -l:libandroid-wordexp.a
)
else()
CHECK_LIBRARY_EXISTS(android-wordexp wordexp "" HAVE_LIBANDROID_WORDEXP)
if(HAVE_LIBANDROID_WORDEXP)
if(ENABLE_WORDEXP)
# https://github.com/termux/termux-packages/pull/7056
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
if(HAVE_LIBANDROID_WORDEXP_STATIC)
target_link_libraries(libfastfetch
PRIVATE android-wordexp
PRIVATE -l:libandroid-wordexp.a
)
else()
CHECK_LIBRARY_EXISTS(android-wordexp wordexp "" HAVE_LIBANDROID_WORDEXP)
if(HAVE_LIBANDROID_WORDEXP)
target_link_libraries(libfastfetch
PRIVATE android-wordexp
)
endif()
endif()
endif()
elseif(Haiku)
@@ -1805,13 +1819,11 @@ if(NOT WIN32)
if(HAVE_UTMPX)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX=1)
endif()
CHECK_INCLUDE_FILE("wordexp.h" HAVE_WORDEXP)
if(HAVE_WORDEXP)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WORDEXP=1)
endif()
CHECK_INCLUDE_FILE("glob.h" HAVE_GLOB)
if(HAVE_GLOB)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_GLOB=1)
if(ENABLE_WORDEXP)
CHECK_INCLUDE_FILE("wordexp.h" HAVE_WORDEXP)
if(HAVE_WORDEXP)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WORDEXP=1)
endif()
endif()
if(ENABLE_THREADS AND CMAKE_USE_PTHREADS_INIT)
CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP)
@@ -2020,11 +2032,6 @@ install(
##################
set(CPACK_GENERATOR "TGZ;ZIP")
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(CMAKE_SYSTEM_PROCESSOR "amd64")
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(CMAKE_SYSTEM_PROCESSOR "aarch64")
endif()
if(APPLE)
string(TOLOWER "${CMAKE_PROJECT_NAME}-macos-${CMAKE_SYSTEM_PROCESSOR}" CPACK_PACKAGE_FILE_NAME) # use macos instead of darwin
elseif(IS_MUSL)
@@ -2071,7 +2078,7 @@ endif()
set(CPACK_SET_DESTDIR ON)
set(CPACK_PACKAGE_CONTACT "Linus Dierheimer <Linus@Dierheimer.de>")
set(CPACK_PACKAGE_CONTACT "Carter Li <zhangsongcui@live.cn>")
set(CPACK_PACKAGE_DESCRIPTION "\
fastfetch is a neofetch-like tool for fetching system information and displaying them in a pretty way. \
It is written mostly in C to achieve much better performance.\
+75
View File
@@ -0,0 +1,75 @@
# Fastfetch
Fastfetch 是一款类似 neofetch 的系统信息展示工具,主要用 C 编写,强调性能和可定制性。支持 Linux、macOS、Windows 7+、Android、FreeBSD、OpenBSD、NetBSD、DragonFly、Haiku、SunOS。
示例配置见 presets/examples,更多截图与平台说明见 Wiki。
## 安装
Linux(部分):
- Debian 13+ / Ubuntu: apt install fastfetch
- Arch: pacman -S fastfetch
- Fedora: dnf install fastfetch
- openSUSE: zypper install fastfetch
- Linuxbrew:brew install fastfetch
- 各发行版打包状态:https://repology.org/project/fastfetch/versions
macOS:
- Homebrew:brew install fastfetch
- MacPorts:sudo port install fastfetch
Windows:
- scoop install fastfetch
- choco install fastfetch
- winget install fastfetch
- MSYS2:pacman -S mingw-w64-<subsystem>-<arch>-fastfetch
BSD:
- FreeBSD:pkg install fastfetch
- NetBSD:pkgin in fastfetch
- OpenBSD:pkg_add fastfetch
Android(Termux):
- pkg install fastfetch
Nightly 构建:
- https://nightly.link/fastfetch-cli/fastfetch/workflows/ci/dev?preview
## 源码构建
基本上是 `cmake . && make`。详见 Wiki:https://github.com/fastfetch-cli/fastfetch/wiki/Building
## 使用
- 默认运行:`fastfetch`
- 查看所有可用模块示例:`fastfetch -c all.jsonc`
- 以 JSON 输出指定模块:`fastfetch -s <module1>[:<module2>] --format json`
- 完整命令行帮助:`fastfetch --help`
- 生成最小配置:`fastfetch --gen-config [</path/to/config.jsonc>]`
- 生成完整配置:`fastfetch --gen-config-full`
- 请使用支持 JSON schema 的编辑器(如 VSCode)编辑配置文件!
- 如果你连接 Github 有网络困难(智能提示不生效),可将配置文件中的 `$schema` 的值替换为 `https://gitee.com/carterl/fastfetch/raw/dev/doc/json_schema.json`
## 定制
- 配置使用 JSONC,语法与选项见 Wiki:https://github.com/fastfetch-cli/fastfetch/wiki/Configuration
- 预设示例位于 presets,可用 `-c <filename>` 加载
- Logo 选项与图像显示见文档:https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options
- 模块格式化(示例,仅显示 GPU 名称):
```jsonc
{
"modules": [
{ "type": "gpu", "format": "{name}" }
]
}
```
详见:https://github.com/fastfetch-cli/fastfetch/wiki/Format-String-Guide
## 反馈与支持
- 使用问题:Discussions https://github.com/fastfetch-cli/fastfetch/discussions
- 疑似缺陷:Issues https://github.com/fastfetch-cli/fastfetch/issues(请填写模版)
## 赞助
<img src="https://github.com/user-attachments/assets/a36a6501-e8b0-4a10-9061-b9206d12ffba" width="220">
+5
View File
@@ -11,6 +11,7 @@
[![latest packaged version(s)](https://repology.org/badge/latest-versions/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
[![Packaging status](https://repology.org/badge/tiny-repos/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/fastfetch-cli/fastfetch)
[![中文README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-red)](README-cn.md)
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku, and SunOS.
@@ -103,6 +104,10 @@ Fastfetch uses JSONC (JSON with comments) for configuration. [See the Wiki for d
Logos can also be heavily customized; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
### WARNING
Fastfetch supports a `Command` module that can run arbitrary shell commands. If you copy-paste a config file from an untrusted source, it may contain malicious commands that can harm your system or compromise your privacy. Please always review the config file before using it.
## FAQ
### Q: Neofetch is good enough. Why do I need fastfetch?
+24 -3
View File
@@ -1024,9 +1024,30 @@
},
{
"const": "both",
"description": "Show both icon and string keys"
"description": "Show both icon and string keys (alias of `both-1`)"
},
{
"const": "both-0",
"description": "Show both icon and string with no spaces between them"
},
{
"const": "both-1",
"description": "Show both icon and string with a space between them"
},
{
"const": "both-2",
"description": "Show both icon and string with 2 spaces between them"
},
{
"const": "both-3",
"description": "Show both icon and string with 3 spaces between them"
},
{
"const": "both-4",
"description": "Show both icon and string with 4 spaces between them"
}
],
],
"default": "string"
},
"paddingLeft": {
@@ -2326,7 +2347,7 @@
]
},
"hideFolders": {
"description": "A list of folder paths to hide from the disk output",
"description": "A list of folder paths (or glob patterns) to hide from the disk output",
"oneOf": [
{
"type": "string",
@@ -2342,7 +2363,7 @@
"uniqueItems": true
}
],
"default": "/efi:/boot:/boot/efi:/boot/firmware"
"default": "/efi:/boot:/boot/*"
},
"hideFS": {
"description": "A list of file systems to hide from the disk output",
+16 -11
View File
@@ -15,11 +15,9 @@
#if FF_HAVE_WORDEXP
#include <wordexp.h>
#elif FF_HAVE_GLOB
#warning "<wordexp.h> is not available, use <glob.h> instead"
#include <glob.h>
#else
#warning "Neither <wordexp.h> nor <glob.h> is available"
#warning "<wordexp.h> is not available, use glob(3) instead"
#include <glob.h>
#endif
static void createSubfolders(const char* fileName)
@@ -136,14 +134,14 @@ bool ffAppendFileBufferRelative(int dfd, const char* fileName, FFstrbuf* buffer)
return ffAppendFDBuffer(fd, buffer);
}
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
{
bool result = false;
#if FF_HAVE_WORDEXP // https://github.com/termux/termux-packages/pull/7056
#if FF_HAVE_WORDEXP
wordexp_t exp;
if (wordexp(in, &exp, 0) != 0)
if (wordexp(in, &exp, 0) != 0) // WARN: 0 = no safety flags; command substitution allowed
return false;
if (exp.we_wordc >= 1)
@@ -154,16 +152,23 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
wordfree(&exp);
#elif FF_HAVE_GLOB
#else
glob_t gb;
if (glob(in, GLOB_NOSORT | GLOB_TILDE, NULL, &gb) != 0)
if (glob(in, GLOB_NOSORT
#ifdef GLOB_TILDE
| GLOB_TILDE
#endif
#ifdef GLOB_BRACE
| GLOB_BRACE
#endif
, NULL, &gb) != 0)
return false;
if (gb.gl_matchc >= 1)
if (gb.gl_pathc >= 1)
{
result = true;
ffStrbufSetS(out, gb.gl_pathv[gb.gl_matchc > 1 ? ffTimeGetNow() % gb.gl_matchc : 0]);
ffStrbufSetS(out, gb.gl_pathv[gb.gl_pathc > 1 ? ffTimeGetNow() % (unsigned) gb.gl_pathc : 0]);
}
globfree(&gb);
+7 -1
View File
@@ -44,7 +44,13 @@ typedef enum __attribute__((__packed__)) FFModuleKeyType
FF_MODULE_KEY_TYPE_NONE = 0,
FF_MODULE_KEY_TYPE_STRING = 1 << 0,
FF_MODULE_KEY_TYPE_ICON = 1 << 1,
FF_MODULE_KEY_TYPE_BOTH = FF_MODULE_KEY_TYPE_STRING | FF_MODULE_KEY_TYPE_ICON,
FF_MODULE_KEY_TYPE_SPACE_SHIFT = 4,
FF_MODULE_KEY_TYPE_BOTH_0 = FF_MODULE_KEY_TYPE_STRING | FF_MODULE_KEY_TYPE_ICON,
FF_MODULE_KEY_TYPE_BOTH_1 = FF_MODULE_KEY_TYPE_BOTH_0 | (1 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
FF_MODULE_KEY_TYPE_BOTH = FF_MODULE_KEY_TYPE_BOTH_1, // alias
FF_MODULE_KEY_TYPE_BOTH_2 = FF_MODULE_KEY_TYPE_BOTH_0 | (2 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
FF_MODULE_KEY_TYPE_BOTH_3 = FF_MODULE_KEY_TYPE_BOTH_0 | (3 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
FF_MODULE_KEY_TYPE_BOTH_4 = FF_MODULE_KEY_TYPE_BOTH_0 | (4 << FF_MODULE_KEY_TYPE_SPACE_SHIFT),
FF_MODULE_KEY_TYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFModuleKeyType;
+7 -6
View File
@@ -28,17 +28,12 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
ffPrintColor(&instance.config.display.colorKeys);
}
bool hasIcon = false;
if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_ICON && moduleArgs && moduleArgs->keyIcon.length > 0)
{
ffStrbufWriteTo(&moduleArgs->keyIcon, stdout);
hasIcon = true;
}
if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_STRING)
{
if(hasIcon)
putchar(' ');
ffPrintCharTimes(' ', instance.config.display.keyType >> FF_MODULE_KEY_TYPE_SPACE_SHIFT);
//NULL check is required for modules with custom keys, e.g. disk with the folder path
if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
@@ -136,6 +131,12 @@ void ffPrintCharTimes(char c, uint32_t times)
if(times == 0)
return;
if(times == 1)
{
putchar(c);
return;
}
char str[32];
memset(str, c, sizeof(str)); //2 instructions when compiling with AVX2 enabled
for(uint32_t i = sizeof(str); i <= times; i += (uint32_t)sizeof(str))
+1 -1
View File
@@ -2,7 +2,7 @@
#include "common/processing.h"
#include "common/io/io.h"
#include <Windows.h>
#include <windows.h>
#include <ntstatus.h>
#include <winternl.h>
+17 -1
View File
@@ -63,6 +63,17 @@
},
"default": "default"
}
},
{
"long": "json",
"short": "j",
"arg": {
"type": "bool",
"default": false,
"optional": true
},
"desc": "Enable or disable JSON output",
"remark": "Shortcut for `--format json`"
}
],
"Config": [
@@ -555,7 +566,12 @@
"none": "Disable keys",
"string": "Show string",
"icon": "Show icon (requires newest nerd font)",
"both": "Show both icon and string"
"both": "Show both icon and string (alias of `both-1`)",
"both-0": "Show both icon and string with no spaces between them",
"both-1": "Show both icon and string with a space between them",
"both-2": "Show both icon and string with 2 spaces between them",
"both-3": "Show both icon and string with 3 spaces between them",
"both-4": "Show both icon and string with 4 spaces between them"
},
"default": "string"
}
+28 -42
View File
@@ -5,69 +5,55 @@
const char* ffDetectBios(FFBiosResult* bios)
{
io_registry_entry_t registryEntry;
#ifndef __aarch64__
//https://github.com/osquery/osquery/blob/master/osquery/tables/system/darwin/smbios_tables.cpp
//For Intel
if((registryEntry = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/rom")))
{
CFMutableDictionaryRef properties;
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
{
IOObjectRelease(registryEntry);
return "IORegistryEntryCreateCFProperties(registryEntry) failed";
}
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceRom = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/rom");
if (!deviceRom)
return "IODeviceTree:/rom not found";
ffCfDictGetString(properties, CFSTR("vendor"), &bios->vendor);
ffCfDictGetString(properties, CFSTR("version"), &bios->version);
ffCfDictGetString(properties, CFSTR("release-date"), &bios->date);
ffStrbufSetStatic(&bios->type, "UEFI");
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef deviceRomProps = NULL;
if(IORegistryEntryCreateCFProperties(deviceRom, &deviceRomProps, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
return "IORegistryEntryCreateCFProperties(deviceRom) failed";
CFRelease(properties);
IOObjectRelease(registryEntry);
return NULL;
}
ffCfDictGetString(deviceRomProps, CFSTR("vendor"), &bios->vendor);
ffCfDictGetString(deviceRomProps, CFSTR("version"), &bios->version);
ffCfDictGetString(deviceRomProps, CFSTR("release-date"), &bios->date);
ffStrbufSetStatic(&bios->type, "UEFI");
#else
//For arm64
if((registryEntry = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/")))
{
CFMutableDictionaryRef properties;
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) == kIOReturnSuccess)
{
ffCfDictGetString(properties, CFSTR("manufacturer"), &bios->vendor);
ffCfDictGetString(properties, CFSTR("time-stamp"), &bios->date);
CFRelease(properties);
}
IOObjectRelease(registryEntry);
}
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t device = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/");
if (!device)
return "IODeviceTree:/ not found";
if((registryEntry = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen")))
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef deviceProps = NULL;
if(IORegistryEntryCreateCFProperties(device, &deviceProps, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
return "IORegistryEntryCreateCFProperties(device) failed";
ffCfDictGetString(deviceProps, CFSTR("manufacturer"), &bios->vendor);
ffCfDictGetString(deviceProps, CFSTR("time-stamp"), &bios->date);
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t deviceChosen = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen");
if (deviceChosen)
{
CFMutableDictionaryRef properties;
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) == kIOReturnSuccess)
FF_CFTYPE_AUTO_RELEASE CFStringRef systemFirmWareVersion = IORegistryEntryCreateCFProperty(deviceChosen, CFSTR("system-firmware-version"), kCFAllocatorDefault, kNilOptions);
if (systemFirmWareVersion)
{
ffCfDictGetString(properties, CFSTR("system-firmware-version"), &bios->version);
ffCfStrGetString(systemFirmWareVersion, &bios->version);
uint32_t index = ffStrbufFirstIndexC(&bios->version, '-');
if (index != bios->version.length)
{
ffStrbufAppendNS(&bios->type, index, bios->version.chars);
ffStrbufRemoveSubstr(&bios->version, 0, index + 1);
}
else
{
ffStrbufSetStatic(&bios->type, "iBoot");
}
CFRelease(properties);
}
IOObjectRelease(registryEntry);
return NULL;
}
if (!bios->type.length)
ffStrbufSetStatic(&bios->type, "iBoot");
#endif
return "Failed to query bios info";
return NULL;
}
+82 -47
View File
@@ -55,7 +55,7 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
// Works for Apple Silicon and USB-C adapter connection ( but not HTMI )
static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
{
if (!IOAVServiceCreate || !IOAVServiceReadI2C)
if (!IOAVServiceCreate || !IOAVServiceReadI2C || !IOAVServiceWriteI2C)
return "IOAVService is not available";
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL;
@@ -123,65 +123,100 @@ static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult*
return NULL;
}
#else
static IOOptionBits getSupportedTransactionType(void)
{
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL;
if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceNameMatching("IOFramebufferI2CInterface"), &iterator) != KERN_SUCCESS)
return kIOI2CNoTransactionType;
io_registry_entry_t registryEntry;
while ((registryEntry = IOIteratorNext(iterator)) != MACH_PORT_NULL)
{
FF_IOOBJECT_AUTO_RELEASE io_service_t io_service = registryEntry;
FF_CFTYPE_AUTO_RELEASE CFNumberRef IOI2CTransactionTypes = IORegistryEntryCreateCFProperty(io_service, CFSTR(kIOI2CTransactionTypesKey), kCFAllocatorDefault, kNilOptions);
if (IOI2CTransactionTypes)
{
int64_t types = 0;
ffCfNumGetInt64(IOI2CTransactionTypes, &types);
if (types) {
if ((1 << kIOI2CDDCciReplyTransactionType) & (uint64_t) types)
return kIOI2CDDCciReplyTransactionType;
if ((1 << kIOI2CSimpleTransactionType) & (uint64_t) types)
return kIOI2CSimpleTransactionType;
}
}
break;
}
return kIOI2CNoTransactionType;
}
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
{
if (!CGSServiceForDisplayNumber) return "CGSServiceForDisplayNumber is not available";
IOOptionBits transactionType = getSupportedTransactionType();
if (transactionType == kIOI2CNoTransactionType)
return "No supported IOI2C transaction type found";
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
{
if (display->type == FF_DISPLAY_TYPE_EXTERNAL)
{
io_service_t framebuffer = 0;
FF_IOOBJECT_AUTO_RELEASE io_service_t framebuffer = IO_OBJECT_NULL;
CGSServiceForDisplayNumber((CGDirectDisplayID)display->id, &framebuffer);
if (framebuffer == 0) continue;
if (framebuffer == IO_OBJECT_NULL) continue;
IOItemCount count;
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0) continue;
io_service_t interface = 0;
if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue;
uint8_t i2cOut[12] = {};
IOI2CConnectRef connect;
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
{
IOObjectRelease(interface);
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0)
continue;
for (IOItemCount bus = 0; bus < count; ++bus)
{
FF_IOOBJECT_AUTO_RELEASE io_service_t interface = IO_OBJECT_NULL;
if (IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface) != KERN_SUCCESS) continue;
uint8_t i2cOut[12] = {};
IOI2CConnectRef connect = NULL;
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
continue;
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
IOI2CRequest request = {
.commFlags = kNilOptions,
.sendAddress = 0x6e,
.sendTransactionType = kIOI2CSimpleTransactionType,
.sendBuffer = (vm_address_t) i2cIn,
.sendBytes = ARRAY_SIZE(i2cIn),
.minReplyDelay = options->ddcciSleep * 1000ULL,
.replyAddress = 0x6F,
.replySubAddress = 0x51,
.replyTransactionType = transactionType,
.replyBytes = ARRAY_SIZE(i2cOut),
.replyBuffer = (vm_address_t) i2cOut,
};
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
IOI2CInterfaceClose(connect, kNilOptions);
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess || request.replyBytes < 10) continue;
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9];
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInitCopy(&brightness->name, &display->name);
brightness->builtin = false;
break;
}
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
IOI2CRequest request = {
.commFlags = kNilOptions,
.sendAddress = 0x6e,
.sendTransactionType = kIOI2CSimpleTransactionType,
.sendBuffer = (vm_address_t) i2cIn,
.sendBytes = ARRAY_SIZE(i2cIn),
.minReplyDelay = options->ddcciSleep,
.replyAddress = 0x6F,
.replySubAddress = 0x51,
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
.replyBytes = ARRAY_SIZE(i2cOut),
.replyBuffer = (vm_address_t) i2cOut,
};
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
IOI2CInterfaceClose(connect, kNilOptions);
IOObjectRelease(interface);
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess) continue;
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9];
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInitCopy(&brightness->name, &display->name);
brightness->builtin = false;
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ static const char* detectFrequency(FFCPUResult* cpu)
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceNameMatching("pmgr"));
if (!entryDevice)
return "IOServiceGetMatchingServices() failed";
return "IOServiceGetMatchingService() failed";
if (!IOObjectConformsTo(entryDevice, "AppleARMIODevice"))
return "\"pmgr\" should conform to \"AppleARMIODevice\"";
+108 -15
View File
@@ -145,6 +145,7 @@ static void detectQualcomm(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips
assert(cpu->name.length >= 2);
uint32_t code = (uint32_t) strtoul(cpu->name.chars + 2, NULL, 10);
const char* name = NULL;
@@ -189,6 +190,7 @@ static void detectMediaTek(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/List_of_MediaTek_systems_on_chips
assert(cpu->name.length >= 2);
uint32_t code = (uint32_t) strtoul(cpu->name.chars + 2, NULL, 10);
const char* name = NULL;
@@ -219,25 +221,78 @@ static void detectMediaTek(FFCPUResult* cpu)
}
}
static void detectExynos(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/Exynos
assert(cpu->name.length > 3);
uint32_t code = (uint32_t) strtoul(cpu->name.chars + 3, NULL, 10);
const char* name = NULL;
switch (code)
{
case 9955: name = "2500"; break;
case 9945: name = "2400"; break;
// No 2300
case 9925: name = "2200"; break;
case 9840: name = "2100"; break;
case 8855: name = "1580"; break;
case 8845: name = "1480"; break;
case 8835: name = "1380"; break;
case 8535: name = "1330"; break;
case 8825: name = "1280"; break;
case 9815: name = "1080"; break;
case 9830: name = "990"; break;
case 9630: name = "980"; break;
case 8805: name = "880"; break;
case 3830: name = "850"; break;
}
if (name)
{
char str[32];
ffStrCopy(str, cpu->name.chars, sizeof(str));
ffStrbufSetF(&cpu->name, "Samsung Exynos %s [%s]", name, str);
return;
}
}
static void detectAndroid(FFCPUResult* cpu)
{
if (cpu->name.length == 0)
{
if (ffSettingsGetAndroidProperty("ro.soc.model", &cpu->name))
ffStrbufClear(&cpu->vendor); // We usually detect the vendor of CPU core as ARM, but instead we want the vendor of SOC
else if(ffSettingsGetAndroidProperty("ro.mediatek.platform", &cpu->name))
ffStrbufSetStatic(&cpu->vendor, "MTK");
}
if (cpu->vendor.length == 0)
{
if (!ffSettingsGetAndroidProperty("ro.soc.manufacturer", &cpu->vendor))
ffSettingsGetAndroidProperty("ro.product.product.manufacturer", &cpu->vendor);
if (!ffSettingsGetAndroidProperty("ro.product.product.manufacturer", &cpu->vendor))
if (!ffSettingsGetAndroidProperty("ro.product.vendor.manufacturer", &cpu->vendor))
if(ffSettingsGetAndroidProperty("ro.mediatek.platform", &cpu->name))
ffStrbufSetStatic(&cpu->vendor, "MediaTek");
}
if (ffStrbufEqualS(&cpu->vendor, "QTI") && ffStrbufStartsWithS(&cpu->name, "SM"))
if (ffStrbufEqualS(&cpu->vendor, "QTI"))
ffStrbufSetStatic(&cpu->vendor, "Qualcomm");
else if (ffStrbufIgnCaseEqualS(&cpu->vendor, "MediaTek")) // sometimes "Mediatek"
ffStrbufSetStatic(&cpu->vendor, "MediaTek");
else if (cpu->vendor.length > 0)
cpu->vendor.chars[0] = (char) toupper(cpu->vendor.chars[0]);
if (ffStrbufEqualS(&cpu->vendor, "Qualcomm") && ffStrbufStartsWithS(&cpu->name, "SM"))
detectQualcomm(cpu);
else if (ffStrbufEqualS(&cpu->vendor, "MTK") && ffStrbufStartsWithS(&cpu->name, "MT"))
else if (ffStrbufEqualS(&cpu->vendor, "MediaTek") && ffStrbufStartsWithS(&cpu->name, "MT"))
detectMediaTek(cpu);
else if (ffStrbufEqualS(&cpu->vendor, "Samsung") && ffStrbufStartsWithS(&cpu->name, "s5e"))
{
cpu->name.chars[0] = 'S';
cpu->name.chars[2] = 'E';
detectExynos(cpu);
}
}
#endif
@@ -360,6 +415,10 @@ static const char* parseCpuInfo(
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor :", &cpu->vendor)) ||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) ||
#elif __hppa__
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) ||
#elif __sh__
(cpu->name.length == 0 && ffParsePropLine(line, "cpu type :", &cpu->name)) ||
#else
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
(cpu->name.length == 0 && ffParsePropLine(line, "model :", &cpu->name)) ||
@@ -617,19 +676,46 @@ FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu)
if (cpu->name.length > 0)
return;
// device-vendor,device-model\0soc-vendor,soc-model\0
char content[256];
// [x-vendor,x-model\0]*N
char content[512];
ssize_t length = ffReadFileData("/proc/device-tree/compatible", ARRAY_SIZE(content), content);
if (length <= 2) return;
if (length < 4) return; // v,m\0
// get the second NUL terminated string if it exists
char* vendor = memchr(content, '\0', (size_t) length) + 1;
if (!vendor || vendor - content >= length) vendor = content;
if (content[length - 1] != '\0') return; // must end with \0
char* model = strchr(vendor, ',');
if (!model) return;
*model = '\0';
++model;
--length;
char* vendor = NULL;
char* model = NULL;
for (char* p; length > 0; length = p ? (ssize_t) (p - content) - 1 : 0)
{
p = memrchr(content, '\0', (size_t) length);
vendor = p /* first entry */ ? p + 1 : content;
size_t partLen = (size_t) (length - (vendor - content));
if (partLen < 3) continue;
char* comma = memchr(vendor, ',', partLen);
if (!comma) continue;
size_t vendorLen = (size_t) (comma - vendor);
if (vendorLen == 0) continue;
model = comma + 1;
size_t modelLen = (size_t) (partLen - (size_t) (model - vendor));
if (modelLen == 0) continue;
if ((modelLen >= strlen("-platform") && ffStrEndsWith(model, "-platform")) ||
(modelLen >= strlen("-soc") && ffStrEndsWith(model, "-soc")))
continue;
*comma = '\0';
break;
}
if (!length) return;
if (false) {}
#if __aarch64__
@@ -685,6 +771,13 @@ FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu)
for (const char* p = model; *p; ++p)
ffStrbufAppendC(&cpu->name, (char) toupper(*p));
}
else if (ffStrEquals(vendor, "thead"))
{
// Lichee Pi?
ffStrbufSetStatic(&cpu->vendor, "T-Head");
for (const char* p = model; *p; ++p)
ffStrbufAppendC(&cpu->name, (char) toupper(*p));
}
else
{
ffStrbufSetS(&cpu->name, model);
+1 -1
View File
@@ -10,7 +10,7 @@
#include <sys/stat.h>
#include <sys/statvfs.h>
#ifdef STATX_BTIME
#if defined(STATX_BTIME) && !defined(__ANDROID__)
#include <sys/syscall.h>
#endif
@@ -45,6 +45,7 @@ FFDisplayResult* ffdsAppendDisplay(
display->manufactureYear = 0;
display->manufactureWeek = 0;
display->serial = 0;
display->drrStatus = FF_DISPLAY_DRR_STATUS_UNKNOWN;
return display;
}
@@ -60,6 +60,13 @@ typedef enum __attribute__((__packed__)) FFDisplayHdrStatus
FF_DISPLAY_HDR_STATUS_ENABLED,
} FFDisplayHdrStatus;
typedef enum __attribute__((__packed__)) FFDisplayVrrStatus
{
FF_DISPLAY_DRR_STATUS_UNKNOWN,
FF_DISPLAY_DRR_STATUS_DISABLED,
FF_DISPLAY_DRR_STATUS_ENABLED,
} FFDisplayVrrStatus;
typedef struct FFDisplayResult
{
uint32_t width; // in px
@@ -83,6 +90,7 @@ typedef struct FFDisplayResult
uint16_t manufactureYear;
uint16_t manufactureWeek;
uint32_t serial;
FFDisplayVrrStatus drrStatus;
} FFDisplayResult;
typedef struct FFDisplayServerResult
@@ -196,21 +196,5 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
}
}
const FFOSResult* os = ffDetectOS();
char* str_end;
const char* version = os->version.chars;
unsigned long osNum = strtoul(version, &str_end, 10);
if (str_end != version)
{
if (osNum > 15) { // Tahoe
ffStrbufSetStatic(&ds->dePrettyName, "Liquid Glass");
} else if (osNum < 10) {
ffStrbufSetStatic(&ds->dePrettyName, "Platinum");
} else {
ffStrbufSetStatic(&ds->dePrettyName, "Aqua");
}
}
detectDisplays(ds);
}
@@ -1,12 +1,9 @@
#include "displayserver.h"
#include "detection/os/os.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
#include "util/mallocHelper.h"
#include "util/edidHelper.h"
#include <dwmapi.h>
#include <WinUser.h>
#include <winuser.h>
#include <wchar.h>
typedef struct FFMonitorInfo
@@ -232,6 +229,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
}
if (edidLength > 0)
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
display->drrStatus = path->flags & DISPLAYCONFIG_PATH_BOOST_REFRESH_RATE ? FF_DISPLAY_DRR_STATUS_ENABLED : FF_DISPLAY_DRR_STATUS_DISABLED;
}
}
}
@@ -254,27 +252,4 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
}
detectDisplays(ds);
//https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067
const FFOSResult* os = ffDetectOS();
uint32_t ver = (uint32_t) ffStrbufToUInt(&os->version, 0);
if (ver > 1000)
{
// Windows Server
if (ver >= 2016)
ffStrbufSetStatic(&ds->dePrettyName, "Fluent");
else if (ver >= 2012)
ffStrbufSetStatic(&ds->dePrettyName, "Metro");
else
ffStrbufSetStatic(&ds->dePrettyName, "Aero");
}
else
{
if (ver >= 10)
ffStrbufSetStatic(&ds->dePrettyName, "Fluent");
else if (ver >= 8)
ffStrbufSetStatic(&ds->dePrettyName, "Metro");
else
ffStrbufSetStatic(&ds->dePrettyName, "Aero");
}
}
+3 -3
View File
@@ -215,8 +215,8 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
FFDisplayResult* item = ffdsAppendDisplay(
data->result,
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
(uint32_t) (currentMode ? currentMode->width : crtcInfoReply->width),
(uint32_t) (currentMode ? currentMode->height : crtcInfoReply->height),
currentMode ? (double) currentMode->dot_clock / (double) ((uint32_t) currentMode->htotal * currentMode->vtotal) : 0,
(uint32_t) (crtcInfoReply->width / scaleFactor + .5),
(uint32_t) (crtcInfoReply->height / scaleFactor + .5),
@@ -230,7 +230,7 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
0,
(uint32_t) outputInfoReply->mm_width,
(uint32_t) outputInfoReply->mm_height,
"xcb-randr-crtc"
currentMode ? "xcb-randr-mode" : "xcb-randr-crtc"
);
if (item && edidLength)
{
+3 -3
View File
@@ -134,8 +134,8 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
FFDisplayResult* item = ffdsAppendDisplay(
data->result,
(uint32_t) crtcInfo->width,
(uint32_t) crtcInfo->height,
(uint32_t) (currentMode ? currentMode->width : crtcInfo->width),
(uint32_t) (currentMode ? currentMode->height : crtcInfo->height),
currentMode ? (double) currentMode->dotClock / (double) ((uint32_t) currentMode->hTotal * currentMode->vTotal) : 0,
(uint32_t) (crtcInfo->width / scaleFactor + .5),
(uint32_t) (crtcInfo->height / scaleFactor + .5),
@@ -149,7 +149,7 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
0,
(uint32_t) output->mm_width,
(uint32_t) output->mm_height,
"xlib-randr-crtc"
currentMode ? "xlib-randr-mode" : "xlib-randr-crtc"
);
if (item)
+1 -1
View File
@@ -28,7 +28,7 @@ const char* ffDetectMemory(FFMemoryResult* ram)
if((token = strstr(buf, "MemAvailable:")) != NULL)
memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
else
if (memAvailable == 0 || memAvailable >= memTotal) // MemAvailable can be unreasonable. #1988
{
if((token = strstr(buf, "MemFree:")) != NULL)
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
+1 -1
View File
@@ -2,7 +2,7 @@
#include "common/library.h"
#include "common/printing.h"
#include <Windows.h>
#include <windows.h>
#include <GL/gl.h>
typedef struct WGLData
+12 -27
View File
@@ -8,14 +8,14 @@
#include <string.h>
#import <Foundation/Foundation.h>
static void parseSystemVersion(FFOSResult* os)
static bool parseSystemVersion(FFOSResult* os)
{
NSError* error;
NSString* fileName = @"file:///System/Library/CoreServices/SystemVersion.plist";
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
error:&error];
if(error)
return;
return false;
NSString* value;
@@ -30,6 +30,8 @@ static void parseSystemVersion(FFOSResult* os)
// macOS 26 Tahoe. #1809
os->version.chars[0] = '2';
}
return true;
}
static bool detectOSCodeName(FFOSResult* os)
@@ -80,41 +82,24 @@ static bool detectOSCodeName(FFOSResult* os)
return false;
}
static void parseOSXSoftwareLicense(FFOSResult* os)
{
FF_AUTO_CLOSE_FILE FILE* rtf = fopen("/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf", "r");
if(rtf == NULL)
return;
FF_AUTO_FREE char* line = NULL;
size_t len = 0;
const char* searchStr = "\\f0\\b SOFTWARE LICENSE AGREEMENT FOR macOS ";
while(getline(&line, &len, rtf) != EOF)
{
if (ffStrStartsWith(line, searchStr))
{
ffStrbufAppendS(&os->codename, line + strlen(searchStr));
ffStrbufTrimRight(&os->codename, '\n');
ffStrbufTrimRight(&os->codename, '\\');
break;
}
}
}
void ffDetectOSImpl(FFOSResult* os)
{
parseSystemVersion(os);
ffStrbufSetStatic(&os->id, "macos");
if(os->version.length == 0)
if(__builtin_expect(os->name.length == 0, 0))
ffStrbufSetStatic(&os->name, "macOS");
if(__builtin_expect(os->version.length == 0, 0))
ffSysctlGetString("kern.osproductversion", &os->version);
if(os->buildID.length == 0)
if(__builtin_expect(os->buildID.length == 0, 0))
ffSysctlGetString("kern.osversion", &os->buildID);
ffStrbufAppend(&os->versionID, &os->version);
if(!detectOSCodeName(os))
parseOSXSoftwareLicense(os);
detectOSCodeName(os);
ffStrbufSetF(&os->prettyName, "%s %s %s (%s)", os->name.chars, os->codename.chars, os->version.chars, os->buildID.chars);
}
+30 -27
View File
@@ -59,17 +59,18 @@ FF_MAYBE_UNUSED static bool detectArmbianVersion(FFOSResult* result)
return true;
}
FF_MAYBE_UNUSED static void getUbuntuFlavour(FFOSResult* result)
// Returns false if PrettyName should be updated by caller
FF_MAYBE_UNUSED static bool getUbuntuFlavour(FFOSResult* result)
{
if (detectArmbianVersion(result))
return;
return true;
else if(ffStrbufStartsWithS(&result->prettyName, "Linux Lite "))
{
ffStrbufSetStatic(&result->name, "Linux Lite");
ffStrbufSetStatic(&result->id, "linuxlite");
ffStrbufSetStatic(&result->idLike, "ubuntu");
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Linux Lite "));
return;
return true;
}
else if(ffStrbufStartsWithS(&result->prettyName, "Rhino Linux "))
{
@@ -77,12 +78,13 @@ FF_MAYBE_UNUSED static void getUbuntuFlavour(FFOSResult* result)
ffStrbufSetStatic(&result->id, "rhinolinux");
ffStrbufSetStatic(&result->idLike, "ubuntu");
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Rhino Linux "));
return;
return true;
}
else if(ffStrbufStartsWithS(&result->prettyName, "VanillaOS "))
{
ffStrbufSetStatic(&result->id, "vanilla");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return true;
}
if (ffPathExists("/usr/bin/lliurex-version", FF_PATHTYPE_FILE))
@@ -97,93 +99,86 @@ FF_MAYBE_UNUSED static void getUbuntuFlavour(FFOSResult* result)
ffStrbufTrimRightSpace(&result->version);
ffStrbufSetF(&result->prettyName, "LliureX %s", result->version.chars);
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return true;
}
const char* xdgConfigDirs = getenv("XDG_CONFIG_DIRS");
if(!ffStrSet(xdgConfigDirs))
return;
return false;
if(ffStrContains(xdgConfigDirs, "kde") || ffStrContains(xdgConfigDirs, "plasma") || ffStrContains(xdgConfigDirs, "kubuntu"))
{
ffStrbufSetStatic(&result->name, "Kubuntu");
ffStrbufSetF(&result->prettyName, "Kubuntu %s", result->version.chars);
ffStrbufSetStatic(&result->id, "kubuntu");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "xfce") || ffStrContains(xdgConfigDirs, "xubuntu"))
{
ffStrbufSetStatic(&result->name, "Xubuntu");
ffStrbufSetF(&result->prettyName, "Xubuntu %s", result->version.chars);
ffStrbufSetStatic(&result->id, "xubuntu");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "lxqt") || ffStrContains(xdgConfigDirs, "lubuntu"))
{
ffStrbufSetStatic(&result->name, "Lubuntu");
ffStrbufSetF(&result->prettyName, "Lubuntu %s", result->version.chars);
ffStrbufSetStatic(&result->id, "lubuntu");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "budgie"))
{
ffStrbufSetStatic(&result->name, "Ubuntu Budgie");
ffStrbufSetF(&result->prettyName, "Ubuntu Budgie %s", result->version.chars);
ffStrbufSetStatic(&result->id, "ubuntu-budgie");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "cinnamon"))
{
ffStrbufSetStatic(&result->name, "Ubuntu Cinnamon");
ffStrbufSetF(&result->prettyName, "Ubuntu Cinnamon %s", result->version.chars);
ffStrbufSetStatic(&result->id, "ubuntu-cinnamon");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "mate"))
{
ffStrbufSetStatic(&result->name, "Ubuntu MATE");
ffStrbufSetF(&result->prettyName, "Ubuntu MATE %s", result->version.chars);
ffStrbufSetStatic(&result->id, "ubuntu-mate");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "studio"))
{
ffStrbufSetStatic(&result->name, "Ubuntu Studio");
ffStrbufSetF(&result->prettyName, "Ubuntu Studio %s", result->version.chars);
ffStrbufSetStatic(&result->id, "ubuntu-studio");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "sway"))
{
ffStrbufSetStatic(&result->name, "Ubuntu Sway");
ffStrbufSetF(&result->prettyName, "Ubuntu Sway %s", result->version.chars);
ffStrbufSetStatic(&result->id, "ubuntu-sway");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
if(ffStrContains(xdgConfigDirs, "touch"))
{
ffStrbufSetStatic(&result->name, "Ubuntu Touch");
ffStrbufSetF(&result->prettyName, "Ubuntu Touch %s", result->version.chars);
ffStrbufSetStatic(&result->id, "ubuntu-touch");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return;
return false;
}
return false;
}
FF_MAYBE_UNUSED static void getDebianVersion(FFOSResult* result)
@@ -192,8 +187,10 @@ FF_MAYBE_UNUSED static void getDebianVersion(FFOSResult* result)
ffAppendFileBuffer("/etc/debian_version", &debianVersion);
ffStrbufTrimRightSpace(&debianVersion);
if (!debianVersion.length) return;
ffStrbufSet(&result->version, &debianVersion);
ffStrbufSet(&result->versionID, &debianVersion);
ffStrbufDestroy(&result->versionID);
ffStrbufInitMove(&result->versionID, &debianVersion);
ffStrbufSetF(&result->prettyName, "%s %s (%s)", result->name.chars, result->versionID.chars, result->codename.chars);
}
FF_MAYBE_UNUSED static bool detectDebianDerived(FFOSResult* result)
@@ -372,7 +369,13 @@ void ffDetectOSImpl(FFOSResult* os)
#if __linux__ || __GNU__
if(ffStrbufEqualS(&os->id, "ubuntu"))
getUbuntuFlavour(os);
{
if (!getUbuntuFlavour(os))
{
if (!ffStrbufEndsWithS(&os->prettyName, " (development branch)"))
ffStrbufSetF(&os->prettyName, "%s %s", os->name.chars, os->version.chars); // os->version contains code name
}
}
else if(ffStrbufEqualS(&os->id, "debian"))
{
if (!detectDebianDerived(os))
@@ -1,25 +1,76 @@
extern "C" {
#include "os.h"
#include "common/library.h"
#include "util/windows/unicode.h"
#include "util/stringUtils.h"
#include "util/windows/registry.h"
}
#include "util/windows/unicode.hpp"
#include "util/windows/wmi.hpp"
#include <windows.h>
static const char* getOsNameByWmi(FFstrbuf* osName)
{
FFWmiQuery query(L"SELECT Caption FROM Win32_OperatingSystem");
if(!query)
return "Query WMI service failed";
if(FFWmiRecord record = query.next())
{
if(auto vtCaption = record.get(L"Caption"))
{
ffStrbufSetWSV(osName, vtCaption.get<std::wstring_view>());
ffStrbufTrimRight(osName, ' ');
return NULL;
}
return "Get Caption failed";
}
return "No WMI result returned";
}
PWSTR WINAPI BrandingFormatString(PCWSTR format);
void ffDetectOSImpl(FFOSResult* os)
static bool getCodeName(FFOSResult* os)
{
FF_HKEY_AUTO_DESTROY hKey = NULL;
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hKey, NULL))
return false;
if(!ffRegReadStrbuf(hKey, L"DisplayVersion", &os->codename, NULL))
{
if (!ffRegReadStrbuf(hKey, L"CSDVersion", &os->codename, NULL)) // For Windows 7 and Windows 8
if (!ffRegReadStrbuf(hKey, L"ReleaseId", &os->codename, NULL)) // For old Windows 10
return false;
}
return true;
}
static const char* getOsNameByWinbrand(FFstrbuf* osName)
{
//https://dennisbabkin.com/blog/?t=how-to-tell-the-real-version-of-windows-your-app-is-running-on#ver_string
const wchar_t* rawName = BrandingFormatString(L"%WINDOWS_LONG%");
ffStrbufSetWS(&os->variant, rawName);
FF_LIBRARY_LOAD(winbrand, "dlopen winbrand" FF_LIBRARY_EXTENSION " failed", "winbrand" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(winbrand, BrandingFormatString);
const wchar_t* rawName = ffBrandingFormatString(L"%WINDOWS_LONG%");
ffStrbufSetWS(osName, rawName);
GlobalFree((HGLOBAL)rawName);
ffStrbufSet(&os->prettyName, &os->variant);
return NULL;
}
extern "C"
void ffDetectOSImpl(FFOSResult* os)
{
if(getOsNameByWinbrand(&os->variant) && getOsNameByWmi(&os->variant))
return;
ffStrbufTrimRight(&os->variant, ' ');
//WMI returns the "Microsoft" prefix while BrandingFormatString doesn't. Make them consistent.
if(ffStrbufStartsWithS(&os->variant, "Microsoft "))
ffStrbufSubstrAfter(&os->variant, strlen("Microsoft ") - 1);
ffStrbufSet(&os->prettyName, &os->variant);
if(ffStrbufStartsWithS(&os->variant, "Windows "))
{
ffStrbufAppendS(&os->name, "Windows");
@@ -57,4 +108,7 @@ void ffDetectOSImpl(FFOSResult* os)
ffStrbufAppendF(&os->id, "%s %s", os->name.chars, os->version.chars);
ffStrbufSetStatic(&os->idLike, "Windows");
if (getCodeName(os) && os->codename.length > 0)
ffStrbufAppendF(&os->prettyName, " (%s)", os->codename.chars);
}
@@ -124,7 +124,7 @@ const char* ffDetectPhysicalMemory(FFlist* result)
ffStrbufSetS(&device->locator, ldevice);
const char* formFactorNames[] = {
NULL, // 0x00 (用于索引,实际上没有0x00的类型)
NULL, // 0x00 (Placeholder for indexing)
"Other", // 0x01
"Unknown", // 0x02
"SIMM", // 0x03
@@ -148,7 +148,7 @@ const char* ffDetectPhysicalMemory(FFlist* result)
ffStrbufSetF(&device->formFactor, "Unknown (%d)", (int) data->FormFactor);
const char* memoryTypeNames[] = {
NULL, // 0x00 (用于索引,实际上没有0x00的类型)
NULL, // 0x00 (Placeholder for indexing)
"Other", // 0x01
"Unknown", // 0x02
"DRAM", // 0x03
+2 -2
View File
@@ -21,8 +21,8 @@ const char* ffDetectSwap(FFlist* result)
ffStrbufInitNWS(&swap->name, current->FileName.Length / sizeof(wchar_t), current->FileName.Buffer);
if (ffStrbufStartsWithS(&swap->name, "\\??\\"))
ffStrbufSubstrAfter(&swap->name, strlen("\\??\\") - 1);
swap->bytesUsed = current->TotalUsed * pageSize;
swap->bytesTotal = current->CurrentSize * pageSize;
swap->bytesUsed = (uint64_t) current->TotalUsed * pageSize;
swap->bytesTotal = (uint64_t) current->CurrentSize * pageSize;
if (current->NextEntryOffset == 0)
break;
}
+7 -1
View File
@@ -105,7 +105,13 @@ static void detectGhostty(const FFstrbuf* exe, FFTerminalFontResult* terminalFon
}
if (fontSize.length == 0) {
ffStrbufAppendS(&fontSize, "13");
ffStrbufAppendS(&fontSize,
#if __APPLE__
"13"
#else
"12"
#endif
);
FF_DEBUG("using default size='%s'", fontSize.chars);
}
+24
View File
@@ -0,0 +1,24 @@
#include "theme.h"
#include "detection/os/os.h"
const char* ffDetectTheme(FFThemeResult* result)
{
const FFOSResult* os = ffDetectOS();
char* str_end;
const char* version = os->version.chars;
unsigned long osNum = strtoul(version, &str_end, 10);
if (str_end != version)
{
if (osNum > 15) { // Tahoe
ffStrbufSetStatic(&result->theme1, "Liquid Glass");
} else if (osNum < 10) {
ffStrbufSetStatic(&result->theme1, "Platinum");
} else {
ffStrbufSetStatic(&result->theme1, "Aqua");
}
}
return NULL;
}
+29
View File
@@ -0,0 +1,29 @@
#include "theme.h"
#include "detection/os/os.h"
const char* ffDetectTheme(FFThemeResult* result)
{
const FFOSResult* os = ffDetectOS();
uint32_t ver = (uint32_t) ffStrbufToUInt(&os->version, 0);
if (ver > 1000)
{
// Windows Server
if (ver >= 2016)
ffStrbufSetStatic(&result->theme1, "Fluent");
else if (ver >= 2012)
ffStrbufSetStatic(&result->theme1, "Metro");
else
ffStrbufSetStatic(&result->theme1, "Aero");
}
else
{
if (ver >= 10)
ffStrbufSetStatic(&result->theme1, "Fluent");
else if (ver >= 8)
ffStrbufSetStatic(&result->theme1, "Metro");
else
ffStrbufSetStatic(&result->theme1, "Aero");
}
return NULL;
}
+2
View File
@@ -26,6 +26,8 @@
#define FF_ARCHITECTURE "alpha"
#elif defined(__hppa__)
#define FF_ARCHITECTURE "hppa"
#elif defined(__sh__)
#define FF_ARCHITECTURE "sh"
#elif defined(__m68k__)
#define FF_ARCHITECTURE "m68k"
#else
+1 -1
View File
@@ -12,7 +12,7 @@ extern "C"
#include <windows.h>
#include <tlhelp32.h>
#include <shlobj.h>
#include <Propkey.h>
#include <propkey.h>
template <typename Fn>
struct on_scope_exit {
+26 -20
View File
@@ -549,6 +549,26 @@ static void printVersion()
printf("%s %s%s%s (%s)\n", result->projectName, result->version, result->versionTweak, result->debugMode ? "-debug" : "", result->architecture);
}
static void enableJsonOutput(bool enable)
{
if (!enable)
{
if (instance.state.resultDoc)
{
yyjson_mut_doc_free(instance.state.resultDoc);
instance.state.resultDoc = NULL;
}
}
else
{
if (!instance.state.resultDoc)
{
instance.state.resultDoc = yyjson_mut_doc_new(NULL);
yyjson_mut_doc_set_root(instance.state.resultDoc, yyjson_mut_arr(instance.state.resultDoc));
}
}
}
static void parseCommand(FFdata* data, char* key, char* value)
{
if(ffStrEqualsIgnCase(key, "-h") || ffStrEqualsIgnCase(key, "--help"))
@@ -640,29 +660,15 @@ static void parseCommand(FFdata* data, char* key, char* value)
generateConfigFile(true, value, true);
else if(ffStrEqualsIgnCase(key, "-c") || ffStrEqualsIgnCase(key, "--config"))
optionParseConfigFile(data, key, value);
else if(ffStrEqualsIgnCase(key, "-j") || ffStrEqualsIgnCase(key, "--json"))
enableJsonOutput(ffOptionParseBoolean(value));
else if(ffStrEqualsIgnCase(key, "--format"))
{
switch (ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "default", 0},
{ "json", 1 },
enableJsonOutput(!!ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "default", false},
{ "json", true },
{},
}))
{
case 0:
if (instance.state.resultDoc)
{
yyjson_mut_doc_free(instance.state.resultDoc);
instance.state.resultDoc = NULL;
}
break;
case 1:
if (!instance.state.resultDoc)
{
instance.state.resultDoc = yyjson_mut_doc_new(NULL);
yyjson_mut_doc_set_root(instance.state.resultDoc, yyjson_mut_arr(instance.state.resultDoc));
}
break;
}
}));
}
else
return;
+13
View File
@@ -0,0 +1,13 @@
!!
!!!!
llllll
llllll
IIIIIIIIII
IIIIIIIIIIIIIIIIIIII
;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;
:;;::;:;::
::::::
,,,,,,
,,,,
""
+17
View File
@@ -0,0 +1,17 @@
.;oo;.
.;ldddol;.
.:cldddddolc:.
':lloddddoooolcc:'
':lllodddddooooolccc:,
,:lllloddddooooollllccccc,.
.,clllllddddooooollllllccc::::,.
.,clllllloodoooooooollllccc:::::::,.
'cllllllllllllloooooollcccc::::::::::,
,lllllllllllllooooolllccc::::::::::,
,cllllllllllllloollllcc::::::::::;
'clllllllllllllllcccc::::::::;:,
.clllllllccccc::cc:::::::::;:'
.cllllccccc:;;;:cc::::::;;:.
.cccccccc;;;:::::cc:::;;:.
.:cccc;;;:::::::::c::;:.
.;::::;;;;;;;;;;;;;::.
+20
View File
@@ -0,0 +1,20 @@
==++++++++++
:========++++++++++++:
===============+++++++++++
====================++++++++++
:=============$3#%@@%$1======++++++++-
-============$3%@%+++*$3@@$1========+++++=
-============$3%@#======$3@@$1==========+++-
=============$3%@+======$3@@$1==============.
$2--$1=========$3+@@@@@@@@@@@@@@@%+$1==========-
$2------$1=====$3%@@@@@@@@@@@@@@@@*$1===========
$2---------$1==$3%@@@@@@@%%@@@@@@@*$1===========
$2:----------$3%@@@@@#$1===$3+%@@@@@*$1==========-
$2----------$3%@@@@@%$1===$3*@@@@@@*$1==========.
$2:---------$3%@@@@@@@@@@@@@@@@*$1=========-
$2:--------$3%@@@@@@@@@@@@@@@@*$1========-
$2:--------$3+##############+$1========:
$2-------------------------$1====-
$2--------------------------
.--------------------.
------------
+13 -13
View File
@@ -1,14 +1,14 @@
$3//$2
$3//$2
$1TTTTTTTTTTTTTTT$2 $3//$2 $1..::$2 $4:-:.$2
$4ttt$2 $3//$2 $1.::.$2 $4.:-:$2
$4ttt$2 $3//$2 $1.:.$2 $4--$2
$4ttt$2 $3//$2 $4:-:$2
$4ttt$2 $3//$2 $4.:-:$2
$4ttt$2 $3//$2 $4:-:.$2
$4ttt$2 $3//$2 $4.--.$2
$4ttt$2 $3//$2 $4.:-:$2
$4ttt$2 $3//$2 $4...$2
$4ttt$2 $3//$2
$3//$2 $3.:::::::::::.$2
$3//$2
$1TTTTTTTTTTTTTTT$2 $3//$2
$1TTTTTTTTTTTTTTT$2 $3//$2 $1..::$2 $4:-:.$2
$4ttt$2 $3//$2 $1.::.$2 $4.:-:$2
$4ttt$2 $3//$2 $1.:.$2 $4--$2
$4ttt$2 $3//$2 $4:-:$2
$4ttt$2 $3//$2 $4.:-:$2
$4ttt$2 $3//$2 $4:-:.$2
$4ttt$2 $3//$2 $4.--.$2
$4ttt$2 $3//$2 $4.:-:$2
$4ttt$2 $3//$2 $4...$2
$4ttt$2 $3//$2
$3//$2 $3.:::::::::::.$2
$3//$2
+10
View File
@@ -0,0 +1,10 @@
__________
/ __________ \
/ / \ \
/ / .-"````"-. \ \
| | |/ \| | |
| | Z R A X Y L | |
| | \ ¯¯¯¯¯¯¯¯¯¯¯¯ / | |
\ \ `-.___..___.-' / /
'.'._ _.' .'
'-.| M - C | .-'
+38
View File
@@ -1558,6 +1558,15 @@ static const FFlogo E[] = {
.colorKeys = FF_COLOR_FG_DEFAULT,
.colorTitle = FF_COLOR_FG_CYAN,
},
// EmperorOS
{
.names = {"Emperor"},
.lines = FASTFETCH_DATATEXT_LOGO_EMPEROROS,
.colors = {
FF_COLOR_FG_YELLOW,
FF_COLOR_FG_DEFAULT,
},
},
// EncryptOS
{
.names = {"EncryptOS"},
@@ -3998,6 +4007,15 @@ static const FFlogo P[] = {
FF_COLOR_FG_WHITE,
},
},
// PrismLinux
{
.names = {"PrismLinux"},
.lines = FASTFETCH_DATATEXT_LOGO_PRISMLINUX,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_BLUE,
},
},
// LAST
{},
};
@@ -4379,6 +4397,16 @@ static const FFlogo S[] = {
FF_COLOR_FG_RED,
},
},
// Secureblue
{
.names = {"secureblue"},
.lines = FASTFETCH_DATATEXT_LOGO_SECUREBLUE,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_MAGENTA,
FF_COLOR_FG_DEFAULT,
},
},
// Serpent OS
{
.names = {"Serpent OS"},
@@ -5461,6 +5489,16 @@ static const FFlogo Z[] = {
FF_COLOR_FG_BLUE,
},
},
// Zraxyl
{
.names = {"Zraxyl" },
.lines = FASTFETCH_DATATEXT_LOGO_ZRAXYL,
.colors = {
FF_COLOR_FG_BLUE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// LAST
{},
};
+30 -3
View File
@@ -5,7 +5,10 @@
#include "common/time.h"
#include "detection/disk/disk.h"
#include "modules/disk/disk.h"
#include "util/stringUtils.h"
#ifndef _WIN32
#include <fnmatch.h>
#endif
#pragma GCC diagnostic ignored "-Wsign-conversion"
@@ -186,6 +189,30 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index
}
}
static inline bool isMatchFolders(FFstrbuf* folders, const FFstrbuf* path, char separator)
{
#ifndef _WIN32
uint32_t startIndex = 0;
while(startIndex < folders->length)
{
uint32_t colonIndex = ffStrbufNextIndexC(folders, startIndex, separator);
char savedColon = folders->chars[colonIndex]; // Can be '\0' if at end
folders->chars[colonIndex] = '\0';
bool matched = fnmatch(&folders->chars[startIndex], path->chars, 0) == 0;
folders->chars[colonIndex] = savedColon;
if (matched) return true;
startIndex = colonIndex + 1;
}
return false;
#else
return ffStrbufSeparatedContain(folders, path, separator);
#endif
}
bool ffPrintDisk(FFDiskOptions* options)
{
FF_LIST_AUTO_DESTROY disks = ffListCreate(sizeof (FFDisk));
@@ -203,7 +230,7 @@ bool ffPrintDisk(FFDiskOptions* options)
if(__builtin_expect(options->folders.length == 0, 1) && (disk->type & ~options->showTypes))
continue;
if (options->hideFolders.length && ffStrbufSeparatedContain(&options->hideFolders, &disk->mountpoint, FF_DISK_FOLDER_SEPARATOR))
if (options->hideFolders.length && isMatchFolders(&options->hideFolders, &disk->mountpoint, FF_DISK_FOLDER_SEPARATOR))
continue;
if (options->hideFS.length && ffStrbufSeparatedContain(&options->hideFS, &disk->filesystem, ':'))
@@ -452,7 +479,7 @@ void ffInitDiskOptions(FFDiskOptions* options)
#if _WIN32 || __APPLE__ || __ANDROID__
ffStrbufInit(&options->hideFolders);
#else
ffStrbufInitStatic(&options->hideFolders, "/efi:/boot:/boot/efi:/boot/firmware");
ffStrbufInitS(&options->hideFolders, "/efi:/boot:/boot/*");
#endif
ffStrbufInit(&options->hideFS);
options->showTypes = FF_DISK_VOLUME_TYPE_REGULAR_BIT | FF_DISK_VOLUME_TYPE_EXTERNAL_BIT | FF_DISK_VOLUME_TYPE_READONLY_BIT;
+15
View File
@@ -348,6 +348,21 @@ bool ffGenerateDisplayJsonResult(FF_MAYBE_UNUSED FFDisplayOptions* options, yyjs
yyjson_mut_obj_add_uint(doc, output, "height", item->height);
yyjson_mut_obj_add_real(doc, output, "refreshRate", item->refreshRate);
if (item->drrStatus == FF_DISPLAY_DRR_STATUS_UNKNOWN)
yyjson_mut_obj_add_null(doc, output, "drrStatus");
else switch (item->drrStatus)
{
case FF_DISPLAY_DRR_STATUS_DISABLED:
yyjson_mut_obj_add_str(doc, output, "drrStatus", "Disabled");
break;
case FF_DISPLAY_DRR_STATUS_ENABLED:
yyjson_mut_obj_add_str(doc, output, "drrStatus", "Enabled");
break;
default:
yyjson_mut_obj_add_str(doc, output, "drrStatus", "Unknown");
break;
}
yyjson_mut_val* scaled = yyjson_mut_obj_add_obj(doc, obj, "scaled");
yyjson_mut_obj_add_uint(doc, scaled, "width", item->scaledWidth);
yyjson_mut_obj_add_uint(doc, scaled, "height", item->scaledHeight);
+1 -8
View File
@@ -10,12 +10,7 @@ bool ffPrintKernel(FFKernelOptions* options)
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
printf("%s %s", info->name.chars, info->release.chars);
if(info->displayVersion.length > 0)
printf(" (%s)\n", info->displayVersion.chars);
else
putchar('\n');
printf("%s %s\n", info->name.chars, info->release.chars);
}
else
{
@@ -26,7 +21,6 @@ bool ffPrintKernel(FFKernelOptions* options)
FF_FORMAT_ARG(info->release, "release"),
FF_FORMAT_ARG(info->version, "version"),
FF_FORMAT_ARG(info->architecture, "arch"),
FF_FORMAT_ARG(info->displayVersion, "display-version"),
FF_FORMAT_ARG(str, "page-size"),
}));
}
@@ -61,7 +55,6 @@ bool ffGenerateKernelJsonResult(FF_MAYBE_UNUSED FFKernelOptions* options, yyjson
yyjson_mut_obj_add_strbuf(doc, obj, "name", &info->name);
yyjson_mut_obj_add_strbuf(doc, obj, "release", &info->release);
yyjson_mut_obj_add_strbuf(doc, obj, "version", &info->version);
yyjson_mut_obj_add_strbuf(doc, obj, "displayVersion", &info->displayVersion);
yyjson_mut_obj_add_uint(doc, obj, "pageSize", info->pageSize);
return true;
+10
View File
@@ -451,6 +451,11 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
{ "string", FF_MODULE_KEY_TYPE_STRING },
{ "icon", FF_MODULE_KEY_TYPE_ICON },
{ "both", FF_MODULE_KEY_TYPE_BOTH },
{ "both-0", FF_MODULE_KEY_TYPE_BOTH_0 },
{ "both-1", FF_MODULE_KEY_TYPE_BOTH_1 },
{ "both-2", FF_MODULE_KEY_TYPE_BOTH_2 },
{ "both-3", FF_MODULE_KEY_TYPE_BOTH_3 },
{ "both-4", FF_MODULE_KEY_TYPE_BOTH_4 },
{}
});
if (error) return error;
@@ -612,6 +617,11 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
{ "string", FF_MODULE_KEY_TYPE_STRING },
{ "icon", FF_MODULE_KEY_TYPE_ICON },
{ "both", FF_MODULE_KEY_TYPE_BOTH },
{ "both-0", FF_MODULE_KEY_TYPE_BOTH_0 },
{ "both-1", FF_MODULE_KEY_TYPE_BOTH_1 },
{ "both-2", FF_MODULE_KEY_TYPE_BOTH_2 },
{ "both-3", FF_MODULE_KEY_TYPE_BOTH_3 },
{ "both-4", FF_MODULE_KEY_TYPE_BOTH_4 },
{}
});
}
+3 -6
View File
@@ -1,5 +1,5 @@
#include "fastfetch.h"
#include "smc_temps.h"
#include "util/apple/cf_helpers.h"
#include "util/stringUtils.h"
#include <stdint.h>
@@ -137,14 +137,11 @@ static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV
static const char *smcOpen(io_connect_t *conn)
{
io_object_t device = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMC"));
FF_IOOBJECT_AUTO_RELEASE io_object_t device = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceMatching("AppleSMC"));
if (!device)
return "No SMC device found";
kern_return_t result = IOServiceOpen(device, mach_task_self(), 0, conn);
IOObjectRelease(device);
if (result != kIOReturnSuccess)
if (IOServiceOpen(device, mach_task_self(), 0, conn) != kIOReturnSuccess)
return "IOServiceOpen() failed";
return NULL;
-1
View File
@@ -56,7 +56,6 @@ void ffPlatformDestroy(FFPlatform* platform)
ffStrbufDestroy(&info->name);
ffStrbufDestroy(&info->release);
ffStrbufDestroy(&info->version);
ffStrbufDestroy(&info->displayVersion);
}
void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path)
-1
View File
@@ -9,7 +9,6 @@ typedef struct FFPlatformSysinfo
FFstrbuf release;
FFstrbuf version;
FFstrbuf architecture;
FFstrbuf displayVersion;
uint32_t pageSize;
} FFPlatformSysinfo;
+6 -2
View File
@@ -1,4 +1,5 @@
#include "FFPlatform_private.h"
#include "util/FFstrbuf.h"
#include "util/stringUtils.h"
#include "fastfetch_config.h"
#include "common/io/io.h"
@@ -182,7 +183,11 @@ static void getUserName(FFPlatform* platform, const struct passwd* pwd)
ffStrbufAppendS(&platform->userName, user);
if (pwd) ffStrbufAppendS(&platform->fullUserName, pwd->pw_gecos);
if (pwd)
{
ffStrbufAppendS(&platform->fullUserName, pwd->pw_gecos);
ffStrbufTrimSpace(&platform->fullUserName);
}
}
static void getHostName(FFPlatform* platform, const struct utsname* uts)
@@ -211,7 +216,6 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts)
else
#endif
ffStrbufAppendS(&info->architecture, uts->machine);
ffStrbufInit(&info->displayVersion);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
size_t length = sizeof(info->pageSize);
+21 -26
View File
@@ -6,7 +6,7 @@
#include "util/windows/registry.h"
#include "util/windows/nt.h"
#include <Windows.h>
#include <windows.h>
#include <shlobj.h>
#define SECURITY_WIN32 1 // For secext.h
@@ -168,15 +168,14 @@ static void getUserShell(FFPlatform* platform)
ffStrbufReplaceAllC(&platform->userShell, '\\', '/');
}
static void detectWine(FFstrbuf* buf)
static const char* detectWine(void)
{
const char * __cdecl wine_get_version(void);
HMODULE hntdll = GetModuleHandleW(L"ntdll.dll");
if (!hntdll) return;
if (!hntdll) return NULL;
FF_LIBRARY_LOAD_SYMBOL_LAZY(hntdll, wine_get_version);
if (!ffwine_get_version) return;
ffStrbufAppendS(buf, buf->length ? " - wine " : "wine ");
ffStrbufAppendS(buf, ffwine_get_version());
if (!ffwine_get_version) return NULL;
return ffwine_get_version();
}
static void getSystemReleaseAndVersion(FFPlatformSysinfo* info)
@@ -199,29 +198,25 @@ static void getSystemReleaseAndVersion(FFPlatformSysinfo* info)
(unsigned) osVersion.dwBuildNumber,
(unsigned) ubr);
ffStrbufInit(&info->displayVersion);
if(!ffRegReadStrbuf(hKey, L"DisplayVersion", &info->displayVersion, NULL))
{
if (osVersion.szCSDVersion[0])
ffStrbufSetWS(&info->displayVersion, osVersion.szCSDVersion);
else
ffRegReadStrbuf(hKey, L"ReleaseId", &info->displayVersion, NULL); // For old Windows 10
}
detectWine(&info->displayVersion);
ffRegReadStrbuf(hKey, L"BuildLabEx", &info->version, NULL);
switch (osVersion.dwPlatformId)
const char* wineVersion = detectWine();
if (wineVersion)
ffStrbufSetF(&info->name, "Wine_%s", wineVersion);
else
{
case VER_PLATFORM_WIN32s:
ffStrbufSetStatic(&info->name, "WIN32s");
break;
case VER_PLATFORM_WIN32_WINDOWS:
ffStrbufSetStatic(&info->name, "WIN32_WINDOWS");
break;
case VER_PLATFORM_WIN32_NT:
ffStrbufSetStatic(&info->name, "WIN32_NT");
break;
switch (osVersion.dwPlatformId)
{
case VER_PLATFORM_WIN32s:
ffStrbufSetStatic(&info->name, "WIN32s");
break;
case VER_PLATFORM_WIN32_WINDOWS:
ffStrbufSetStatic(&info->name, "WIN32_WINDOWS");
break;
case VER_PLATFORM_WIN32_NT:
ffStrbufSetStatic(&info->name, "WIN32_NT");
break;
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ extern "C" {
}
#include <initguid.h>
#include <Wbemidl.h>
#include <wbemidl.h>
#include <cassert>
#include "variant.hpp"