mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:14:37 +02:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cec38b9501 | |||
| 3453b72f0c | |||
| 060544b899 | |||
| 14c6b6d7e2 | |||
| 9df394bba3 | |||
| b25ffda90b | |||
| db9cf4ef29 | |||
| 7b2d4b7a0d | |||
| 64cdb3f058 | |||
| 66e7924fa3 | |||
| 84540250f7 | |||
| 96e7f65902 | |||
| 321d3e5574 | |||
| 2bba2eaa16 | |||
| 58ebde422a | |||
| 06f3b9a96d | |||
| fa5aaa692f | |||
| 9d2c4f52d2 | |||
| 9946a5d758 | |||
| a749014e7c | |||
| 2cd421fc2e | |||
| 4db6aebcc9 | |||
| 3b156e819b | |||
| 7ffed9e911 | |||
| 9042950ee8 | |||
| 7aad0dc32f | |||
| 01d04a8fa2 | |||
| d3e50fe595 | |||
| ecd69370ab | |||
| abd2522268 | |||
| 2e1261bc21 | |||
| 0e597a2ded | |||
| 2781a0ab93 | |||
| 02d7f2693b | |||
| b001ea409b | |||
| f97a9fdfc0 | |||
| 2c8d5292d7 | |||
| 88e4579f1e | |||
| 8f97e61f67 | |||
| 0b943bb25e | |||
| 19590003e1 | |||
| 27a1d9f8c6 | |||
| d50ebc86c7 | |||
| 74616c79f5 | |||
| 0c1462898b | |||
| b94a322dfc | |||
| adb6dc537c | |||
| debcc3ca7f | |||
| 3d7d02b5c5 | |||
| 3f0ae13505 | |||
| 4370c0944b | |||
| a9df048d49 | |||
| 09782d67e5 | |||
| 165aa93fd3 | |||
| d979f55c8e | |||
| 4f261509a0 | |||
| 6413656cea | |||
| a334b805fd | |||
| f940ef0592 | |||
| 963b5c6c4e | |||
| 4a74f69c96 | |||
| 18d36c5054 | |||
| a4614ec412 | |||
| e257f876ae | |||
| e9031171c0 | |||
| 47a9cf0450 | |||
| 1704dc62e0 | |||
| abf6c403d4 | |||
| 0606cde061 | |||
| 0bc9149a23 | |||
| 071be4794f | |||
| b5e199d2b2 | |||
| a210128592 | |||
| 63a28cc8f4 | |||
| a6c006221d | |||
| 42b84161d9 | |||
| 88e075ad9d | |||
| e37ad26729 | |||
| b500e9c09b | |||
| 77fbfd3fbd | |||
| 63cdc47d18 | |||
| edf24d9820 | |||
| becd9b7f26 | |||
| 672604081a | |||
| 3185969974 | |||
| ddbafd1cca | |||
| 16d70eed03 | |||
| bf15adf57a | |||
| dbd1f96353 | |||
| 8b3cff33da | |||
| 146c9b2bc6 | |||
| 3c7cb339e2 | |||
| 6318668d0b | |||
| 6737896038 | |||
| 96fc1db85e | |||
| 03e6b47eda | |||
| 067396d3a0 | |||
| a8c3979696 | |||
| 786b23ef52 |
@@ -0,0 +1,21 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- keepalive
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
@@ -375,7 +375,6 @@ jobs:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- name: run VM
|
||||
uses: vmactions/omnios-vm@v1
|
||||
with:
|
||||
@@ -494,7 +493,7 @@ jobs:
|
||||
with:
|
||||
msystem: CLANG64
|
||||
update: true
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-cppwinrt
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
@@ -508,6 +507,9 @@ jobs:
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: download amd_ags
|
||||
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x64.dll
|
||||
|
||||
- name: list features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
@@ -527,10 +529,10 @@ jobs:
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: create 7z archive
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-amd64.7z *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-amd64.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -556,7 +558,7 @@ jobs:
|
||||
with:
|
||||
msystem: CLANG32
|
||||
update: true
|
||||
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd
|
||||
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-opencl-headers
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
@@ -578,6 +580,9 @@ jobs:
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: download amd_ags
|
||||
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x86.dll
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
@@ -594,10 +599,10 @@ jobs:
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: create 7z archive
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
+77
-3
@@ -1,3 +1,77 @@
|
||||
# 2.17.2
|
||||
|
||||
Changes:
|
||||
* Flatpak package count no longer takes runtime packages into account (Packages, Linux)
|
||||
|
||||
Bugfixes:
|
||||
* Fix formattion with multiple batteries (Battery)
|
||||
* Fix incorrect size value for large memory sticks (PhysicalMemory)
|
||||
* Fix spelling of `Qt` and `LXQt`
|
||||
* Fix building on SunOS if imagemagick support is enabled (Logo, SunOS)
|
||||
* Fix typos
|
||||
|
||||
Features:
|
||||
* Support Ptyxis terminal version and font detection (Terminal / TerminalFont, Linux)
|
||||
* Improve Cinnamon version detection (DE)
|
||||
* Support `cinnamon-wayland` (WMTheme)
|
||||
* `--ts-version false` will disable editor version detection (Editor)
|
||||
|
||||
# 2.17.1
|
||||
|
||||
Hotfix for a regression that breaks Qt font detection
|
||||
|
||||
Bugfixes:
|
||||
* Don't generate and install `libffwinrt.dll.a` on MinGW (Windows)
|
||||
* Fix building on Windows when imagemagick support is enabled (Logo, Windows)
|
||||
* Don't print GPU frequency with `--gpu-temp` for Nvidia cards (#1052, GPU)
|
||||
* `--gpu-driver-specific` needs to be specified
|
||||
* Print formatted size when `--gpu-format` is used (#1052, GPU)
|
||||
* Ignore QVariant format; fix unreadable Qt font (#1053, Theme, Linux)
|
||||
* Fix segfaults with `--show-errors` and an invalid module (#1055)
|
||||
|
||||
# 2.17.0
|
||||
|
||||
Changes:
|
||||
* CMake option `ENABLE_PROPRIETARY_GPU_DRIVER_API` is removed. The GPU driver APIs are now enabled by default.
|
||||
* The option was introduced to reduce the license concerns. Since all non MIT proprietary code has been rewritten manually from scratch, it is no longer necessary.
|
||||
* See <https://github.com/fastfetch-cli/fastfetch/issues/533#issuecomment-2122830958> for detail
|
||||
* Option `--logo-separate true` is changed to `--logo-position top` for better readability
|
||||
* Builtin ascii logos can be positioned on the right side now with`--logo-position right`
|
||||
|
||||
Features:
|
||||
* Add support for `--gpu-detection-method opencl` which uses OpenCL to detect GPUs.
|
||||
* Support detecting CPU cache size by using SMBIOS as fallback (CPUCache)
|
||||
* Support GPU detection (SunOS)
|
||||
* Support GPU type detection with AMD GPU driver (GPU, Windows)
|
||||
* Add fast path of version and font detection for kitty (Terminal / TerminalFont)
|
||||
* Make sure `stdin` and `stdout` are TTYs when querying terminal
|
||||
* So modules like `TerminalSize` should work when `stdin` or `stdout` is redirected
|
||||
* Support argument truncation in `--<module>-format` (#1043)
|
||||
* See `fastfetch --help format` for detail
|
||||
* Improve Qt theme detection (#1047, Theme, Linux)
|
||||
* Add new JSON config option `general.preRun`, which is executed before fastfetch prints output.
|
||||
* It can be used to generate a temp logo file. For example
|
||||
```jsonc
|
||||
{
|
||||
"general": {
|
||||
"preRun": "kitten icat --align=left /path/to/image > /tmp/logo.kitty"
|
||||
},
|
||||
"logo": {
|
||||
"source": "/tmp/logo.kitty",
|
||||
"type": "raw"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Bugfixes:
|
||||
* Fix invalid path (#1031, LM, Linux)
|
||||
* Fix VMEM detection for Nvidia GPU (requires `--gpu-driver-specific`) (GPU)
|
||||
* Fix AMD `--gpu-driver-specific` for AMD cards (#1032, GPU, Windows)
|
||||
* Use Coordinated Universal Time rather than timezone-varying local date (#1046)
|
||||
|
||||
Logo:
|
||||
* Fix colors of Asahi Linux
|
||||
|
||||
# 2.16.0
|
||||
|
||||
This release added basic support for SunOS (Solaris, illumos). The binaries provided in the release lack a few useful features (such as Display detection). People who use SunOS should consider building fastfetch themselves.
|
||||
@@ -1005,7 +1079,7 @@ Bugfixes:
|
||||
This release backports some changes from dev branch, and fixes 2 crashing issues
|
||||
|
||||
Features:
|
||||
* Support KDE / LXQT / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
|
||||
* Support KDE / LXQt / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
|
||||
* Support QTerminal version & terminal font detection
|
||||
* Support MATE Terminal version & terminal font detection
|
||||
* Set `--pipe true` automatically if stdout is not a tty
|
||||
@@ -1051,7 +1125,7 @@ Bugfixes:
|
||||
* Fix Windows drives detection in WSL (Disk)
|
||||
|
||||
Changes:
|
||||
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / QT icon params.
|
||||
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / Qt icon params.
|
||||
* `--theme-format` no longer supports individual GTK / plasma theme params.
|
||||
* `--local-ip-*` and `--public-ip-*` have been changed to `--localip-*` and `--publicip-*`
|
||||
* `--localip-compact-type` is no longer supported. Fastfetch now display IPs as `--localip-compat-type multiline` by default, with `--local-compact true` can be set as an alias of `--localip-compact-type oneline`
|
||||
@@ -1425,7 +1499,7 @@ Fixes build on android (#205)
|
||||
# 1.6.0
|
||||
|
||||
Features:
|
||||
* Detect QT on more DEs than just KDE Plasma. The [Plasma] category was therefore renamed to [QT]
|
||||
* Detect Qt on more DEs than just KDE Plasma. The [Plasma] category was therefore renamed to [Qt]
|
||||
* Alacritty font detection
|
||||
* Load `/etc/fastfetch/config.conf` before user config
|
||||
* Disk: print one decimal point if size < 100GB
|
||||
|
||||
+30
-25
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.16.0
|
||||
VERSION 2.17.2
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -64,7 +64,7 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB
|
||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32 OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32 OR ANDROID OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBNM "Enable libnm" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
||||
@@ -74,7 +74,7 @@ cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND"
|
||||
|
||||
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_PROPRIETARY_GPU_DRIVER_API "Enable proprietary GPU driver API (NVML, IGCL and AGS)" ON)
|
||||
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
|
||||
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
||||
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
|
||||
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
|
||||
@@ -140,7 +140,7 @@ if(NOT WIN32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -rdynamic")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
if(ENABLE_LTO AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(STATUS "Enabling LTO")
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED)
|
||||
@@ -256,7 +256,7 @@ if(APPLE)
|
||||
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
|
||||
endif()
|
||||
|
||||
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y")
|
||||
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC)
|
||||
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
|
||||
|
||||
####################
|
||||
@@ -549,7 +549,7 @@ elseif(BSD)
|
||||
src/detection/brightness/brightness_bsd.c
|
||||
src/detection/chassis/chassis_bsd.c
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/cpucache/cpucache_nosupport.c
|
||||
src/detection/cpucache/cpucache_shared.c
|
||||
src/detection/cpuusage/cpuusage_bsd.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
@@ -749,7 +749,7 @@ elseif(SunOS)
|
||||
src/detection/brightness/brightness_nosupport.c
|
||||
src/detection/chassis/chassis_windows.c
|
||||
src/detection/cpu/cpu_sunos.c
|
||||
src/detection/cpucache/cpucache_nosupport.c
|
||||
src/detection/cpucache/cpucache_shared.c
|
||||
src/detection/cpuusage/cpuusage_sunos.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
@@ -813,15 +813,13 @@ if(ENABLE_DIRECTX_HEADERS)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_wsl.cpp)
|
||||
endif()
|
||||
|
||||
if(ENABLE_PROPRIETARY_GPU_DRIVER_API AND (LINUX OR BSD OR WIN32))
|
||||
message(STATUS "Enabling proprietary GPU driver API")
|
||||
if(LINUX OR BSD OR WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
|
||||
endif()
|
||||
# Proprietary GPU driver APIs
|
||||
if(LINUX OR BSD OR WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
|
||||
endif()
|
||||
|
||||
include(CheckFunctionExists)
|
||||
@@ -850,10 +848,6 @@ add_library(libfastfetch OBJECT
|
||||
${LIBFASTFETCH_SRC}
|
||||
)
|
||||
|
||||
if(ENABLE_PROPRIETARY_GPU_DRIVER_API AND (LINUX OR BSD OR WIN32))
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_PROPRIETARY_GPU_DRIVER_API)
|
||||
endif()
|
||||
|
||||
if(yyjson_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_SYSTEM_YYJSON)
|
||||
target_link_libraries(libfastfetch PRIVATE yyjson::yyjson)
|
||||
@@ -1082,7 +1076,6 @@ if(LINUX)
|
||||
)
|
||||
elseif(APPLE)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "resolv"
|
||||
PRIVATE "-framework AVFoundation"
|
||||
PRIVATE "-framework Cocoa"
|
||||
PRIVATE "-framework CoreFoundation"
|
||||
@@ -1164,7 +1157,7 @@ if(WIN32)
|
||||
include(CheckIncludeFileCXX)
|
||||
CHECK_INCLUDE_FILE_CXX("winrt/Windows.Foundation.h" HAVE_WINRT)
|
||||
if(HAVE_WINRT)
|
||||
add_library(ffwinrt SHARED src/detection/media/media_windows.dll.cpp)
|
||||
add_library(ffwinrt MODULE src/detection/media/media_windows.dll.cpp)
|
||||
target_link_libraries(ffwinrt PRIVATE "RuntimeObject")
|
||||
target_compile_definitions(ffwinrt PRIVATE WIN32_LEAN_AND_MEAN=1 WINRT_LEAN_AND_MEAN=1)
|
||||
target_link_options(ffwinrt
|
||||
@@ -1267,6 +1260,13 @@ install(
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
|
||||
if (TARGET ffwinrt)
|
||||
install(
|
||||
TARGETS ffwinrt
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.bash"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions"
|
||||
@@ -1323,12 +1323,17 @@ if(LINUX)
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
|
||||
if(NOT IS_MUSL)
|
||||
EXECUTE_PROCESS (
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND getconf GNU_LIBC_VERSION
|
||||
OUTPUT_VARIABLE GLIBC_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
STRING (REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
|
||||
if(GLIBC_VERSION)
|
||||
STRING(REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
|
||||
message(STATUS "found glibc ${GLIBC_VERSION}")
|
||||
else()
|
||||
message(WARNING "Could not determine glibc version. If `musl` is used, `-DIS_MUSL=ON` should be set")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Linus Dierheimer
|
||||
Copyright (c) 2021-2023 Linus Dierheimer
|
||||
Copyright (c) 2022-2024 Carter Li
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/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. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, macOS, SunOS and Windows 7+ are supported.
|
||||
|
||||
<img src="screenshots/example1.png" width="49%" align="left" />
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
|
||||
@@ -21,15 +21,16 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
|
||||
<img src="screenshots/example3.png" width="48%" align="top" />
|
||||
<img src="screenshots/example5.png" height="15%" align="top" />
|
||||
|
||||
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
|
||||
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki).
|
||||
|
||||
## Installation
|
||||
|
||||
### Linux
|
||||
|
||||
Some distros packaged an outdated fastfetch version. Older version is not supported, please always ensure that the latest version is used.
|
||||
Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version.
|
||||
|
||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||
* Debian: `sudo apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
@@ -56,7 +57,7 @@ If fastfetch is not packaged for your distro or an outdated version is packaged,
|
||||
* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch`
|
||||
* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
|
||||
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
|
||||
You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file.
|
||||
|
||||
### FreeBSD
|
||||
|
||||
@@ -80,7 +81,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
|
||||
## Customization
|
||||
|
||||
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. They may also serve as a good example for format arguments.
|
||||
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. Those files can serve as examples of the configuration syntax.
|
||||
|
||||
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||
|
||||
@@ -102,10 +103,10 @@ Logos can be heavily customized too; see the [logo documentation](https://github
|
||||
|
||||
1. Fastfetch is actively maintained.
|
||||
2. Fastfetch is faster. As the name suggests.
|
||||
3. Fastfetch is more feature-rich. By default fastfetch only has a few modules enabled. Use `fastfetch -c all` to find what you want.
|
||||
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>
|
||||
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module (notibily the difference of `MiB` and `G`), while fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
|
||||
6. Fastfetch is more accurate. For example, [neofetch never actually supports Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
|
||||
3. Fastfetch has a greater number of features, though by default fastfetch only has a few modules enabled; use `fastfetch -c all` to find what you want.
|
||||
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>.
|
||||
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
|
||||
6. Fastfetch is more accurate. For example, [neofetch never actually supports the Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
|
||||
|
||||
### Q: Fastfetch shows my local IP address. It leaks my privacy!
|
||||
|
||||
@@ -117,7 +118,7 @@ If you really don't like it, you can disable the `Local IP` module in `config.js
|
||||
|
||||
### Q: Where is the config file? I can't find it.
|
||||
|
||||
`Fastfetch` don't generate config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See [Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration).
|
||||
`Fastfetch` does not generate config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See [Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration).
|
||||
|
||||
### Q: The configuration is so complex. Where is the documentation?
|
||||
|
||||
@@ -131,7 +132,7 @@ Alternatively, you can refer to the presets in [`presets` directory](https://git
|
||||
|
||||
### Q: How can I customize the module output?
|
||||
|
||||
Fastfetch uses `format` to generate output. For example to make `GPU` module show GPU name only and ignore other information, you can use
|
||||
Fastfetch uses `format` to generate output. For example, to make the `GPU` module show only the GPU name (leaving other information undisplayed), you can use
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -144,15 +145,15 @@ Fastfetch uses `format` to generate output. For example to make `GPU` module sho
|
||||
}
|
||||
```
|
||||
|
||||
which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
|
||||
. . which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
|
||||
|
||||
See `fastfetch -h format` for basic usage. For module specific formattion, see `fastfetch -h <module>-format`
|
||||
See `fastfetch -h format` for information on basic usage. For module specific formattion, see `fastfetch -h <module>-format`
|
||||
|
||||
### Q: I have my own ascii-art / image file. How can I show it with fastfetch?
|
||||
|
||||
Try `fastfetch -l /path/to/logo`. See [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for detail.
|
||||
|
||||
If you just want to display distro name in [FIGlet text](https://github.com/pwaller/pyfiglet)
|
||||
If you just want to display distro name in [FIGlet text](https://github.com/pwaller/pyfiglet):
|
||||
|
||||
```bash
|
||||
# install pyfiglet and jq first
|
||||
|
||||
@@ -347,6 +347,7 @@ __fastfetch_completion()
|
||||
"--users-key"
|
||||
"--users-format"
|
||||
"--users-key-color"
|
||||
"--users-myself-only"
|
||||
"--bluetooth-key"
|
||||
"--bluetooth-format"
|
||||
"--bluetooth-key-color"
|
||||
|
||||
Vendored
+18
@@ -1,3 +1,21 @@
|
||||
fastfetch (2.17.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.17.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 01 Jul 2024 08:56:29 +0800
|
||||
|
||||
fastfetch (2.17.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.17.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 28 Jun 2024 13:43:18 +0800
|
||||
|
||||
fastfetch (2.16.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.16.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 19 Jun 2024 14:53:43 +0800
|
||||
|
||||
fastfetch (2.15.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.15.0
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.15.0_source.buildinfo universe/utils optional
|
||||
fastfetch_2.17.1_source.buildinfo universe/utils optional
|
||||
|
||||
+35
-7
@@ -23,7 +23,7 @@
|
||||
"default": 0
|
||||
},
|
||||
"format": {
|
||||
"description": "Output format of the module. See `-h <module>-format` for detail",
|
||||
"description": "Output format of the module. See `-h <module>-format` for detail. I.e: fastfetch -h disk-format",
|
||||
"type": "string"
|
||||
},
|
||||
"outputColor": {
|
||||
@@ -89,10 +89,12 @@
|
||||
"default": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"
|
||||
},
|
||||
"logo": {
|
||||
"description": "Fastfetch logo configurations\nSee also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Disable logo",
|
||||
"type": "null"
|
||||
"type": "null",
|
||||
"const": null
|
||||
},
|
||||
{
|
||||
"description": "Set the source file of the logo",
|
||||
@@ -217,10 +219,15 @@
|
||||
"description": "If true, regenerate image logo cache",
|
||||
"default": false
|
||||
},
|
||||
"separate": {
|
||||
"type": "boolean",
|
||||
"description": "If true, print modules at bottom of the logo",
|
||||
"default": false
|
||||
"position": {
|
||||
"type": "string",
|
||||
"description": "Set the position of the logo should be displayed",
|
||||
"enum": [
|
||||
"left",
|
||||
"top",
|
||||
"right"
|
||||
],
|
||||
"default": "left"
|
||||
},
|
||||
"chafa": {
|
||||
"type": "object",
|
||||
@@ -327,6 +334,11 @@
|
||||
"type": "integer",
|
||||
"description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
|
||||
"default": 1000
|
||||
},
|
||||
"preRun": {
|
||||
"type": "string",
|
||||
"description": "Set the command to be executed before printing logos",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -564,7 +576,7 @@
|
||||
},
|
||||
"tsVersion": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to detect and display the version of terminal and shell. Mainly for benchmarking",
|
||||
"description": "Whether to detect and display the version of terminal, shell and editor. Mainly for benchmarking",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
@@ -1133,6 +1145,21 @@
|
||||
"type": "boolean",
|
||||
"description": "Display CPU usage per CPU logical core, instead of an average result",
|
||||
"default": false
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1523,6 +1550,7 @@
|
||||
"auto",
|
||||
"pci",
|
||||
"vulkan",
|
||||
"opencl",
|
||||
"opengl"
|
||||
],
|
||||
"default": "auto"
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
{
|
||||
"type": "font",
|
||||
"key": "FONT",
|
||||
"format": "{?1}{1} [QT]{?}{/1}Unknown", // Remove "[QT]" if not using Qt
|
||||
"format": "{?1}{1} [Qt]{?}{/1}Unknown", // Remove "[Qt]" if not using Qt
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
|
||||
+47
-34
@@ -52,24 +52,28 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
* @param placeholderValue the string to parse
|
||||
* @return uint32_t the parsed value
|
||||
*/
|
||||
static uint32_t getArgumentIndex(const FFstrbuf* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
|
||||
static uint32_t getArgumentIndex(const char* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
char firstChar = placeholderValue->chars[0];
|
||||
char firstChar = placeholderValue[0];
|
||||
if (firstChar == '\0')
|
||||
return 0; // use arg counter
|
||||
|
||||
if(firstChar >= '1' && firstChar <= '9')
|
||||
if (firstChar >= '0' && firstChar <= '9')
|
||||
{
|
||||
char* pEnd = NULL;
|
||||
unsigned long result = strtoul(placeholderValue->chars, &pEnd, 10);
|
||||
if (pEnd != placeholderValue->chars + placeholderValue->length || result > numArgs)
|
||||
uint32_t result = (uint32_t) strtoul(placeholderValue, &pEnd, 10);
|
||||
if (result > numArgs)
|
||||
return UINT32_MAX;
|
||||
return (uint32_t) result;
|
||||
if (*pEnd != '\0')
|
||||
return UINT32_MAX;
|
||||
return result;
|
||||
}
|
||||
else if (ffCharIsEnglishAlphabet(firstChar))
|
||||
{
|
||||
for (uint32_t i = 0; i < numArgs; ++i)
|
||||
{
|
||||
const FFformatarg* arg = &arguments[i];
|
||||
if(arg->name && ffStrbufIgnCaseEqualS(placeholderValue, arg->name))
|
||||
if (arg->name && strcasecmp(placeholderValue, arg->name) == 0)
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
@@ -86,16 +90,6 @@ static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start,
|
||||
ffStrbufAppendC(buffer, '}');
|
||||
}
|
||||
|
||||
static inline void appendEmptyPlaceholder(FFstrbuf* buffer, const char* placeholder, uint32_t* argCounter, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
if(*argCounter >= numArgs)
|
||||
ffStrbufAppendS(buffer, placeholder);
|
||||
else
|
||||
ffFormatAppendFormatArg(buffer, arguments + *argCounter);
|
||||
|
||||
(*argCounter)++;
|
||||
}
|
||||
|
||||
static inline bool formatArgSet(const FFformatarg* arg)
|
||||
{
|
||||
return arg->value != NULL && (
|
||||
@@ -128,13 +122,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we have an { at the end handle it as {}
|
||||
if(i == formatstr->length - 1)
|
||||
{
|
||||
appendEmptyPlaceholder(buffer, "{", &argCounter, numArgs, arguments);
|
||||
continue;
|
||||
}
|
||||
|
||||
// jump to next char, the start of the placeholder value
|
||||
++i;
|
||||
|
||||
@@ -145,13 +132,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
// placeholder is {}
|
||||
if(formatstr->chars[i] == '}')
|
||||
{
|
||||
appendEmptyPlaceholder(buffer, "{}", &argCounter, numArgs, arguments);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufClear(&placeholderValue);
|
||||
|
||||
{
|
||||
@@ -205,7 +185,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
{
|
||||
ffStrbufSubstrAfter(&placeholderValue, 0);
|
||||
|
||||
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
|
||||
// testing for an invalid index
|
||||
if (index > numArgs)
|
||||
@@ -231,7 +211,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
{
|
||||
ffStrbufSubstrAfter(&placeholderValue, 0);
|
||||
|
||||
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
|
||||
// testing for an invalid index
|
||||
if (index > numArgs)
|
||||
@@ -264,16 +244,49 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
|
||||
int32_t truncLength = INT32_MAX;
|
||||
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
|
||||
if (pColon != NULL)
|
||||
{
|
||||
char* pEnd = NULL;
|
||||
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
|
||||
if (*pEnd != '\0')
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
*pColon = '\0';
|
||||
}
|
||||
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
|
||||
// test for invalid index
|
||||
if (index == 0)
|
||||
index = ++argCounter;
|
||||
|
||||
if (index > numArgs)
|
||||
{
|
||||
if (pColon) *pColon = ':';
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ellipsis = false;
|
||||
if (truncLength < 0)
|
||||
{
|
||||
ellipsis = true;
|
||||
truncLength = -truncLength;
|
||||
}
|
||||
|
||||
uint32_t oldLength = buffer->length;
|
||||
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
|
||||
if (buffer->length - oldLength > (uint32_t) truncLength)
|
||||
{
|
||||
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
if (ellipsis)
|
||||
ffStrbufAppendS(buffer, "…");
|
||||
}
|
||||
}
|
||||
|
||||
if (!instance.config.display.pipe)
|
||||
|
||||
@@ -254,9 +254,6 @@ void ffListFeatures(void)
|
||||
#ifdef FF_HAVE_DIRECTX_HEADERS
|
||||
"Directx Headers\n"
|
||||
#endif
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
"Proprietary GPU driver API\n"
|
||||
#endif
|
||||
#ifdef FF_USE_SYSTEM_YYJSON
|
||||
"System yyjson\n"
|
||||
#endif
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#include <handleapi.h>
|
||||
#include <io.h>
|
||||
typedef HANDLE FFNativeFD;
|
||||
#define FF_INVALID_FD INVALID_HANDLE_VALUE
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
typedef int FFNativeFD;
|
||||
#define FF_INVALID_FD (-1)
|
||||
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
||||
// one safe way to read correct data is reading the whole file in a single read syscall
|
||||
// 8192 comes from procps-ng: https://gitlab.com/procps-ng/procps/-/blob/master/library/meminfo.c?ref_type=heads#L39
|
||||
|
||||
+26
-14
@@ -133,32 +133,44 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
if (instance.config.display.pipe)
|
||||
return "Not supported in --pipe mode";
|
||||
int fin = STDIN_FILENO, fout = STDOUT_FILENO;
|
||||
FF_AUTO_CLOSE_FD int ftty = -1;
|
||||
|
||||
struct termios oldTerm, newTerm;
|
||||
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
|
||||
if (!isatty(STDIN_FILENO))
|
||||
{
|
||||
if (ftty < 0)
|
||||
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
fin = ftty;
|
||||
}
|
||||
if (!isatty(STDOUT_FILENO))
|
||||
{
|
||||
if (ftty < 0)
|
||||
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
fout = ftty;
|
||||
}
|
||||
|
||||
struct termios oldTerm;
|
||||
if(tcgetattr(fin, &oldTerm) == -1)
|
||||
return "tcgetattr(STDIN_FILENO, &oldTerm) failed";
|
||||
|
||||
newTerm = oldTerm;
|
||||
struct termios newTerm = oldTerm;
|
||||
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
|
||||
if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1)
|
||||
return "tcsetattr(STDIN_FILENO, TCSANOW, &newTerm)";
|
||||
if(tcsetattr(fin, TCSAFLUSH, &newTerm) == -1)
|
||||
return "tcsetattr(STDIN_FILENO, TCSAFLUSH, &newTerm)";
|
||||
|
||||
fputs(request, stdout);
|
||||
fflush(stdout);
|
||||
ffWriteFDData(fout, strlen(request), request);
|
||||
|
||||
//Give the terminal 35ms to respond
|
||||
if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
|
||||
//Give the terminal some time to respond
|
||||
if(poll(&(struct pollfd) { .fd = fin, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
tcsetattr(fin, TCSANOW, &oldTerm);
|
||||
return "poll() timeout or failed";
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
|
||||
ssize_t bytesRead = read(fin, buffer, sizeof(buffer) - 1);
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
tcsetattr(fin, TCSANOW, &oldTerm);
|
||||
|
||||
if(bytesRead <= 0)
|
||||
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
|
||||
|
||||
+57
-12
@@ -114,8 +114,40 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
||||
|
||||
bool ffSuppressIO(bool suppress)
|
||||
{
|
||||
(void) suppress; //Not implemented.
|
||||
return false;
|
||||
static bool init = false;
|
||||
static HANDLE hOrigOut = INVALID_HANDLE_VALUE;
|
||||
static HANDLE hOrigErr = INVALID_HANDLE_VALUE;
|
||||
static HANDLE hNullFile = INVALID_HANDLE_VALUE;
|
||||
static int fOrigOut = -1;
|
||||
static int fOrigErr = -1;
|
||||
static int fNullFile = -1;
|
||||
|
||||
if (!init)
|
||||
{
|
||||
if(!suppress)
|
||||
return true;
|
||||
|
||||
hOrigOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
hOrigErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
hNullFile = CreateFileW(L"NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
|
||||
fOrigOut = _dup(STDOUT_FILENO);
|
||||
fOrigErr = _dup(STDERR_FILENO);
|
||||
fNullFile = _open_osfhandle((intptr_t) hNullFile, 0);
|
||||
|
||||
init = true;
|
||||
}
|
||||
if (hNullFile == INVALID_HANDLE_VALUE || fNullFile == -1)
|
||||
return false;
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, suppress ? hNullFile : hOrigOut);
|
||||
SetStdHandle(STD_ERROR_HANDLE, suppress ? hNullFile : hOrigErr);
|
||||
_dup2(suppress ? fNullFile : fOrigOut, STDOUT_FILENO);
|
||||
_dup2(suppress ? fNullFile : fOrigErr, STDERR_FILENO);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
|
||||
@@ -175,24 +207,37 @@ void ffListFilesRecursively(const char* path, bool pretty)
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
if (instance.config.display.pipe)
|
||||
return "Not supported in --pipe mode";
|
||||
|
||||
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD prev_mode;
|
||||
GetConsoleMode(hInput, &prev_mode);
|
||||
FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE;
|
||||
DWORD inputMode;
|
||||
if (!GetConsoleMode(hInput, &inputMode))
|
||||
{
|
||||
hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL);
|
||||
hInput = hConin;
|
||||
}
|
||||
SetConsoleMode(hInput, 0);
|
||||
|
||||
FlushConsoleInputBuffer(hInput);
|
||||
|
||||
DWORD bytes = 0;
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), request, (DWORD) strlen(request), &bytes, NULL);
|
||||
{
|
||||
DWORD bytes = 0;
|
||||
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
|
||||
DWORD outputMode;
|
||||
if (!GetConsoleMode(hOutput, &outputMode))
|
||||
{
|
||||
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
|
||||
hOutput = hConout;
|
||||
}
|
||||
WriteFile(hOutput, "TEST\n", 5, &bytes, NULL);
|
||||
WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, NULL);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (WaitForSingleObjectEx(hInput, FF_IO_TERM_RESP_WAIT_MS, TRUE) != WAIT_OBJECT_0)
|
||||
{
|
||||
SetConsoleMode(hInput, prev_mode);
|
||||
SetConsoleMode(hInput, inputMode);
|
||||
return "WaitForSingleObject() failed or timeout";
|
||||
}
|
||||
|
||||
@@ -213,10 +258,10 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
bytes = 0;
|
||||
DWORD bytes = 0;
|
||||
ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL);
|
||||
|
||||
SetConsoleMode(hInput, prev_mode);
|
||||
SetConsoleMode(hInput, inputMode);
|
||||
|
||||
if(bytes <= 0)
|
||||
return "ReadFile() failed";
|
||||
|
||||
@@ -148,6 +148,14 @@ bool ffOptionParseBoolean(const char* str)
|
||||
|
||||
void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
|
||||
{
|
||||
// If value is already an ANSI escape code, use it
|
||||
if (value[0] == '\e' && value[1] == '[')
|
||||
{
|
||||
ffStrbufAppendS(buffer, value + 2);
|
||||
ffStrbufTrimRight(buffer, 'm');
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufEnsureFree(buffer, 63);
|
||||
|
||||
while(*value != '\0')
|
||||
|
||||
@@ -64,7 +64,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
if(!instance.config.display.pipe)
|
||||
{
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
if (moduleArgs->outputColor.length)
|
||||
if (moduleArgs && moduleArgs->outputColor.length)
|
||||
ffPrintColor(&moduleArgs->outputColor);
|
||||
else if (instance.config.display.colorOutput.length)
|
||||
ffPrintColor(&instance.config.display.colorOutput);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
typedef enum FFPrintType {
|
||||
FF_PRINT_TYPE_DEFAULT = 0,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0, // key has been formatted outside
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH = 1 << 2,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_OUTPUT_FORMAT = 1 << 3, // reserved
|
||||
|
||||
+13
-9
@@ -154,7 +154,7 @@
|
||||
{
|
||||
"short": "l",
|
||||
"long": "logo",
|
||||
"desc": "Set the logo source",
|
||||
"desc": "Set the logo source. Use \"none\" to disable the logo",
|
||||
"remark": "Should be the name of a builtin logo, or a path to an image file. See also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
|
||||
"arg": {
|
||||
"type": "logo"
|
||||
@@ -257,12 +257,15 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "logo-separate",
|
||||
"desc": "If true, print modules at bottom of the logo",
|
||||
"long": "logo-position",
|
||||
"desc": "Set the position of the logo should be displayed",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": false
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"left": "Left",
|
||||
"top": "Top",
|
||||
"right": "Right"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -438,7 +441,7 @@
|
||||
},
|
||||
{
|
||||
"long": "pipe",
|
||||
"desc": "Disable logo and all escape sequences",
|
||||
"desc": "Disable colors",
|
||||
"remark": "Auto detection based on isatty(1)",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
@@ -725,7 +728,7 @@
|
||||
},
|
||||
{
|
||||
"long": "ts-version",
|
||||
"desc": "Whether to detect and display the version of terminal and shell",
|
||||
"desc": "Whether to detect and display the version of terminal, shell and editor",
|
||||
"remark": "Mainly for benchmarking",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
@@ -1251,7 +1254,8 @@
|
||||
"enum": {
|
||||
"auto": "Query platform specific graphic APIs. Requires proper GPU drivers installed. Not supported on FreeBSD",
|
||||
"pci": "Search PCI devices, which do not requires GPU driver installed. Not supported on Windows and macOS",
|
||||
"vulkan": "Use Vulkan API. Slow and requires vulkan driver installed. Used for Android",
|
||||
"vulkan": "Use Vulkan API. Slow and requires proper vulkan driver installed. Used for Android",
|
||||
"opencl": "Use OpenCL API. Slow and requires proper OpenCL driver installed",
|
||||
"opengl": "Use OpenGL API. Slow and only detects one GPU"
|
||||
},
|
||||
"default": "auto"
|
||||
|
||||
@@ -8,6 +8,11 @@ In 2.14.0 or newer, the value indices can be meaningful named tags.
|
||||
For example: "--title-format '{user-name-colored}{at-symbol-colored}{host-name-colored}'" is equivalent to "--title-format '{6}{7}{8}'"
|
||||
See "fastfetch -h title-format" for all supported tags.
|
||||
|
||||
In 2.17.0 or newer, a truncation length can be specified using syntax '<arg>:<trunc-length>`
|
||||
For example: "--title-format '{user-name:5}'" will truncate user name into 5-length string.
|
||||
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
|
||||
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
|
||||
|
||||
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
|
||||
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
|
||||
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
|
||||
|
||||
@@ -172,7 +172,7 @@ typedef struct FFSmbiosPortableBattery
|
||||
static_assert(offsetof(FFSmbiosPortableBattery, OEMSpecific) == 0x16,
|
||||
"FFSmbiosPortableBattery: Wrong struct alignment");
|
||||
|
||||
const char* detectBySmbios(FFBatteryResult* battery)
|
||||
static const char* detectBySmbios(FFBatteryResult* battery)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "cpucache.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
typedef struct FFSmbiosCacheInfo
|
||||
{
|
||||
FFSmbiosHeader Header;
|
||||
|
||||
uint8_t SocketDesignation; // string
|
||||
uint16_t CacheConfiguration; // varies
|
||||
uint16_t MaximumCacheSize; // varies
|
||||
uint16_t InstalledSize; // varies
|
||||
uint16_t SupportedSramType; // bit field
|
||||
uint16_t CurrentSramType; // bit field
|
||||
|
||||
// 2.1+
|
||||
uint8_t CacheSpeed; // varies
|
||||
uint8_t ErrorCorrectionType; // enum
|
||||
uint8_t SystemCacheType; // enum
|
||||
uint8_t Associativity; // enum
|
||||
|
||||
// 3.1+
|
||||
uint32_t MaximumCacheSize2; // bit field
|
||||
uint32_t InstalledCacheSize2; // bit field
|
||||
} __attribute__((__packed__)) FFSmbiosCacheInfo;
|
||||
|
||||
static_assert(offsetof(FFSmbiosCacheInfo, InstalledCacheSize2) == 0x17,
|
||||
"FFSmbiosCacheInfo: Wrong struct alignment");
|
||||
|
||||
const char* ffDetectCPUCache(FFCPUCacheResult* result)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosCacheInfo* data = (const FFSmbiosCacheInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_CACHE_INFO];
|
||||
if (!data)
|
||||
return "Cache information is not found in SMBIOS data";
|
||||
|
||||
for (; data->Header.Type == FF_SMBIOS_TYPE_CACHE_INFO;
|
||||
data = (const FFSmbiosCacheInfo*) ffSmbiosNextEntry(&data->Header))
|
||||
{
|
||||
bool enabled = !!(data->CacheConfiguration & (1 << 7));
|
||||
if (!enabled)
|
||||
continue;
|
||||
|
||||
uint32_t size = data->InstalledSize;
|
||||
if (size == 0)
|
||||
continue;
|
||||
|
||||
if (data->InstalledSize != 0xFFFF)
|
||||
{
|
||||
size *= (size >> 15 ? 64 : 1) * 1024u;
|
||||
}
|
||||
else if (data->Header.Length > offsetof(FFSmbiosCacheInfo, InstalledCacheSize2))
|
||||
{
|
||||
size = data->InstalledCacheSize2;
|
||||
size *= (size >> 31 ? 64 : 1) * 1024u;
|
||||
}
|
||||
|
||||
uint32_t level = (data->CacheConfiguration & 0b111u) + 1;
|
||||
|
||||
FFCPUCacheType type;
|
||||
switch (data->SystemCacheType)
|
||||
{
|
||||
case 3: type = FF_CPU_CACHE_TYPE_INSTRUCTION; break;
|
||||
case 4: type = FF_CPU_CACHE_TYPE_DATA; break;
|
||||
default: type = FF_CPU_CACHE_TYPE_UNIFIED; break;
|
||||
}
|
||||
|
||||
ffCPUCacheAddItem(result, level, size, 0, type);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -74,7 +74,20 @@ static void getGnome(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
|
||||
static void getCinnamon(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
|
||||
ffStrbufSetS(result, getenv("CINNAMON_VERSION"));
|
||||
|
||||
if (result->length == 0)
|
||||
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
|
||||
|
||||
if (result->length == 0 && options->slowVersionDetection)
|
||||
{
|
||||
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||
"cinnamon",
|
||||
"--version",
|
||||
NULL
|
||||
}) == NULL) // Cinnamon 6.2.2
|
||||
ffStrbufSubstrAfterLastC(result, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
static void getMate(FFstrbuf* result, FFDEOptions* options)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define FF_DE_PRETTY_CINNAMON "Cinnamon"
|
||||
#define FF_DE_PRETTY_MATE "Mate"
|
||||
#define FF_DE_PRETTY_LXDE "LXDE"
|
||||
#define FF_DE_PRETTY_LXQT "LXQT"
|
||||
#define FF_DE_PRETTY_LXQT "LXQt"
|
||||
#define FF_DE_PRETTY_BUDGIE "Budgie"
|
||||
#define FF_DE_PRETTY_CDE "CDE"
|
||||
#define FF_DE_PRETTY_UNITY "Unity"
|
||||
|
||||
@@ -23,7 +23,6 @@ static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreate();
|
||||
ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed.
|
||||
ffReadFileBuffer(procPath.chars, &result->wmProcessName);
|
||||
ffStrbufTrimRightSpace(&result->wmProcessName);
|
||||
ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments
|
||||
ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path
|
||||
}
|
||||
|
||||
@@ -71,11 +71,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
|
||||
return;
|
||||
|
||||
if(
|
||||
ffStrEqualsIgnCase(name, "kwin_wayland") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_wayland_wrapper") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_x11") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_x11_wrapper") ||
|
||||
ffStrEqualsIgnCase(name, "kwin") ||
|
||||
ffStrStartsWithIgnCase(name, "kwin_") ||
|
||||
ffStrEndsWithIgnCase(name, "-kwin_wayland") ||
|
||||
ffStrEndsWithIgnCase(name, "-kwin_x11")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
|
||||
@@ -86,7 +83,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
|
||||
ffStrEqualsIgnCase(name, "Mutter")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
|
||||
else if(
|
||||
ffStrEqualsIgnCase(name, "cinnamon-session") ||
|
||||
ffStrEqualsIgnCase(name, "cinnamon") ||
|
||||
ffStrStartsWithIgnCase(name, "cinnamon-") ||
|
||||
ffStrEqualsIgnCase(name, "Muffin") ||
|
||||
ffStrEqualsIgnCase(name, "Mutter (Muffin)")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
|
||||
@@ -207,7 +205,7 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
|
||||
else if(
|
||||
ffStrEqualsIgnCase(name, "LXQt") ||
|
||||
ffStrEqualsIgnCase(name, "X-LXQT") ||
|
||||
ffStrEqualsIgnCase(name, "X-LXQt") ||
|
||||
ffStrEqualsIgnCase(name, "lxqt-session")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "lxqt-session");
|
||||
|
||||
@@ -26,6 +26,8 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
return "$VISUAL or $EDITOR not set";
|
||||
}
|
||||
|
||||
if (!instance.config.display.tsVersion) return NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
if (result->name.chars[0] != '/')
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
typedef struct FFFontResult
|
||||
{
|
||||
/**
|
||||
* Linux / BSD: QT, GTK2, GTK3, GTK4
|
||||
* Linux / BSD: Qt, GTK2, GTK3, GTK4
|
||||
* MacOS: System, User, System Mono, User Mono
|
||||
* Windows: Caption, Menu, Message, Status
|
||||
* Other: Unset, Unset, Unset, Unset
|
||||
|
||||
@@ -9,7 +9,7 @@ static void generateString(FFFontResult* font)
|
||||
if(font->fonts[0].length > 0)
|
||||
{
|
||||
ffStrbufAppend(&font->display, &font->fonts[0]);
|
||||
ffStrbufAppendS(&font->display, " [QT]");
|
||||
ffStrbufAppendS(&font->display, " [Qt]");
|
||||
|
||||
for(uint8_t i = 1; i < sizeof(font->fonts) / sizeof(font->fonts[0]); i++)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "gpu.h"
|
||||
#include "detection/vulkan/vulkan.h"
|
||||
#include "detection/opencl/opencl.h"
|
||||
#include "detection/opengl/opengl.h"
|
||||
|
||||
const char* FF_GPU_VENDOR_NAME_APPLE = "Apple";
|
||||
@@ -94,6 +95,16 @@ const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENCL)
|
||||
{
|
||||
FFOpenCLResult* opencl = ffDetectOpenCL();
|
||||
if (!opencl->error && opencl->gpus.length > 0)
|
||||
{
|
||||
ffListDestroy(result);
|
||||
ffListInitMove(result, &opencl->gpus);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENGL)
|
||||
{
|
||||
if (detectByOpenGL(result) == NULL)
|
||||
|
||||
@@ -19,13 +19,12 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
inited = true;
|
||||
FF_LIBRARY_LOAD(libags, NULL, "dlopen amd_ags failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsInitialize)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsDeInitialize)
|
||||
|
||||
struct AGSContext* apiHandle;
|
||||
if (ffagsInitialize(AGS_CURRENT_VERSION, NULL, &apiHandle, &gpuInfo) != AGS_SUCCESS)
|
||||
return "loading ags library failed";
|
||||
|
||||
ffagsDeInitialize(apiHandle);
|
||||
// agsDeInitialize will free pointers allocated in gpuInfo. Just leak them.
|
||||
}
|
||||
|
||||
if (gpuInfo.numDevices == 0)
|
||||
@@ -63,5 +62,8 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
if (result.frequency)
|
||||
*result.frequency = device->coreClock / 1000.; // Maximum frequency
|
||||
|
||||
if (result.type)
|
||||
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
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) {
|
||||
@@ -98,7 +97,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
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;
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
#include "detection/vulkan/vulkan.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
#include "detection/cpu/cpu.h"
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#endif
|
||||
|
||||
#define FF_STR_INDIR(x) #x
|
||||
#define FF_STR(x) FF_STR_INDIR(x)
|
||||
|
||||
@@ -261,7 +258,6 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
}
|
||||
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
|
||||
{
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
if (options->temp || options->driverSpecific)
|
||||
{
|
||||
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
|
||||
@@ -277,10 +273,9 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
|
||||
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.type = &gpu->type,
|
||||
.frequency = &gpu->frequency,
|
||||
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
|
||||
}, "libnvidia-ml.so");
|
||||
}
|
||||
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
|
||||
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
|
||||
{
|
||||
|
||||
@@ -17,12 +17,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!ffStrbufStartsWithS(&buffer, "\npci domain 0x"))
|
||||
if (!ffStrbufStartsWithS(&buffer, "\npci "))
|
||||
return "Invalid scanpci result";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
|
||||
|
||||
// pci domain 0x354b bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
|
||||
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
|
||||
// Device unknown
|
||||
// CardVendor 0x0000 card 0x0000 (Card unknown)
|
||||
// STATUS 0x0010 COMMAND 0x0007
|
||||
@@ -42,9 +42,9 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
pstart = memrchr(buffer.chars, '\n', (size_t) (pstart - buffer.chars - 1));
|
||||
++pstart;
|
||||
|
||||
uint32_t pciDomain, pciBus, pciDev, pciFunc, vendorId, deviceId;
|
||||
if (sscanf(pstart, "pci domain %x bus %x cardnum %x function %x: vendor %x device %x",
|
||||
&pciDomain, &pciBus, &pciDev, &pciFunc, &vendorId, &deviceId) != 6)
|
||||
uint32_t vendorId, deviceId;
|
||||
if (sscanf(pstart, "pci %*[^:]: vendor %x device %x",
|
||||
&vendorId, &deviceId) != 2)
|
||||
return "PCI info not found, invalid scanpci result";
|
||||
|
||||
pclass += strlen("\n CLASS 0x03 ");
|
||||
@@ -61,7 +61,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
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) | (pciDev << 2) | pciFunc;
|
||||
gpu->deviceId = 0;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
#include "gpu.h"
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/windows/registry.h"
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
|
||||
@@ -13,7 +10,6 @@ static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
|
||||
return ffStrbufEqual(&gpu->name, name);
|
||||
}
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&ffDetectNvidiaGpuInfo)* pDetectFn, const char** pDllName)
|
||||
{
|
||||
if (vendor == FF_GPU_VENDOR_NAME_NVIDIA)
|
||||
@@ -48,7 +44,6 @@ static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
|
||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
@@ -144,13 +139,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
__typeof__(&ffDetectNvidiaGpuInfo) detectFn;
|
||||
const char* dllName;
|
||||
|
||||
if (getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName) && (options->temp || options->driverSpecific))
|
||||
{
|
||||
if (vendorId && deviceId && subSystemId && revId)
|
||||
if (vendorId && deviceId && subSystemId)
|
||||
{
|
||||
detectFn(
|
||||
&(FFGpuDriverCondition) {
|
||||
@@ -168,13 +162,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
|
||||
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.type = &gpu->type,
|
||||
.frequency = &gpu->frequency,
|
||||
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
|
||||
},
|
||||
dllName
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -104,7 +104,6 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
|
||||
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
|
||||
ffStrbufSetStatic(&gpu->vendor, vendorStr);
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA && (options->driverSpecific || options->temp))
|
||||
{
|
||||
FFGpuDriverCondition cond = {
|
||||
@@ -121,10 +120,9 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
|
||||
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
|
||||
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.type = &gpu->type,
|
||||
.frequency = &gpu->frequency,
|
||||
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
|
||||
}, "/usr/lib/wsl/lib/libnvidia-ml.so");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ typedef struct {
|
||||
// Allocated device memory (in bytes)
|
||||
unsigned long long used;
|
||||
} nvmlMemory_v2_t;
|
||||
enum { nvmlMemory_v2 = 2 };
|
||||
// https://github.com/NVIDIA/nvidia-settings/issues/78#issuecomment-1012837988
|
||||
enum { nvmlMemory_v2 = (unsigned int)(sizeof(nvmlMemory_v2_t) | (2 << 24U)) };
|
||||
|
||||
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64
|
||||
// Clock types
|
||||
|
||||
@@ -135,6 +135,34 @@ static void detectLXQt(FFQtResult* result)
|
||||
ffParsePropFileConfig("pcmanfm-qt/lxqt/settings.conf", "Wallpaper=", &result->wallpaper);
|
||||
}
|
||||
|
||||
static void detectQtCt(char qver, FFQtResult* result)
|
||||
{
|
||||
// qt5ct and qt6ct are technically separate applications, but they're both
|
||||
// by the same author and qt6ct understands qt5ct in qt6 applications as well.
|
||||
char file[] = "qtXct/qtXct.conf";
|
||||
file[2] = file[8] = qver;
|
||||
ffParsePropFileConfigValues(file, 3, (FFpropquery[]) {
|
||||
{"style=", &result->widgetStyle},
|
||||
{"icon_theme=", &result->icons},
|
||||
{"general=", &result->font}
|
||||
});
|
||||
|
||||
if (ffStrbufStartsWithC(&result->font, '@'))
|
||||
{
|
||||
// See QVariant notes on https://doc.qt.io/qt-5/qsettings.html and
|
||||
// https://github.com/fastfetch-cli/fastfetch/issues/1053#issuecomment-2197254769
|
||||
// Thankfully, newer versions use the more common font encoding.
|
||||
ffStrbufSetNS(&result->font, 5, file);
|
||||
}
|
||||
}
|
||||
|
||||
static void detectKvantum(FFQtResult* result)
|
||||
{
|
||||
ffParsePropFileConfigValues("Kvantum/kvantum.kvconfig", 1, (FFpropquery[]) {
|
||||
{"theme=", &result->widgetStyle},
|
||||
});
|
||||
}
|
||||
|
||||
const FFQtResult* ffDetectQt(void)
|
||||
{
|
||||
static FFQtResult result;
|
||||
@@ -151,11 +179,20 @@ const FFQtResult* ffDetectQt(void)
|
||||
ffStrbufInit(&result.wallpaper);
|
||||
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
const char *qplatformtheme = getenv("QT_QPA_PLATFORMTHEME");
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA))
|
||||
detectPlasma(&result);
|
||||
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT))
|
||||
detectLXQt(&result);
|
||||
else if(ffStrSet(qplatformtheme) && (ffStrEquals(qplatformtheme, "qt5ct") || ffStrEquals(qplatformtheme, "qt6ct")))
|
||||
detectQtCt(qplatformtheme[2], &result);
|
||||
|
||||
if(ffStrbufEqualS(&result.widgetStyle, "kvantum") || ffStrbufEqualS(&result.widgetStyle, "kvantum-dark"))
|
||||
{
|
||||
ffStrbufClear(&result.widgetStyle);
|
||||
detectKvantum(&result);
|
||||
}
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const char* ffDetectIcons(FFIconsResult* result)
|
||||
if(plasma->length > 0)
|
||||
{
|
||||
ffStrbufAppend(&result->icons1, plasma);
|
||||
ffStrbufAppendS(&result->icons1, " [QT]");
|
||||
ffStrbufAppendS(&result->icons1, " [Qt]");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define FF_SYSTEMD_SESSIONS_PATH "/var/run/systemd/sessions/"
|
||||
#define FF_SYSTEMD_SESSIONS_PATH "/run/systemd/sessions/"
|
||||
#define FF_SYSTEMD_USERS_PATH "/run/systemd/users/"
|
||||
|
||||
static const char* getGdmVersion(FFstrbuf* version)
|
||||
@@ -143,7 +143,7 @@ const char* ffDetectLM(FFLMResult* result)
|
||||
{
|
||||
// On some incorrectly configured systems, $XDG_SESSION_ID is not set. Try finding it ourself
|
||||
// WARNING: This is private data. Do not parse
|
||||
ffStrbufAppendF(&path, "/run/systemd/users/%d", getuid());
|
||||
ffStrbufSetF(&path, FF_SYSTEMD_USERS_PATH "%d", getuid());
|
||||
|
||||
// This is actually buggy, and assumes current user is using DE
|
||||
// `sd_pid_get_session` can be a better option, but we need to find a pid to use
|
||||
@@ -151,10 +151,9 @@ const char* ffDetectLM(FFLMResult* result)
|
||||
{"DISPLAY=", &sessionId},
|
||||
}))
|
||||
return "Failed to get $XDG_SESSION_ID";
|
||||
ffStrbufClear(&path);
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&path, "/var/run/systemd/sessions/");
|
||||
ffStrbufSetS(&path, FF_SYSTEMD_SESSIONS_PATH);
|
||||
ffStrbufAppend(&path, &sessionId);
|
||||
|
||||
// WARNING: This is private data. Do not parse
|
||||
@@ -162,7 +161,7 @@ const char* ffDetectLM(FFLMResult* result)
|
||||
{"SERVICE=", &result->service},
|
||||
{"TYPE=", &result->type},
|
||||
}))
|
||||
return "Failed to parse /run/systemd/sessions/$XDG_SESSION_ID";
|
||||
return "Failed to parse " FF_SYSTEMD_SESSIONS_PATH "$XDG_SESSION_ID";
|
||||
|
||||
if (ffStrbufStartsWithS(&result->service, "gdm"))
|
||||
getGdmVersion(&result->version);
|
||||
|
||||
@@ -95,7 +95,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
continue;
|
||||
|
||||
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
|
||||
char addressBuffer[INET_ADDRSTRLEN + 4];
|
||||
char addressBuffer[INET_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
@@ -105,7 +105,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
if (cidr != 0)
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 4, "/%d", cidr);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
continue;
|
||||
|
||||
struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 4];
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
@@ -130,7 +130,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
if (cidr != 0)
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 4, "/%d", cidr);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
+ vmstat.compressor_page_count
|
||||
- vmstat.purgeable_count
|
||||
- vmstat.external_page_count
|
||||
) * instance.state.platform.pageSize;
|
||||
) * instance.state.platform.sysinfo.pageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
+ ffSysctlGetInt("vm.stats.vm.v_inactive_count", 0)
|
||||
+ ffSysctlGetInt("vm.stats.vm.v_cache_count", 0);
|
||||
|
||||
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.pageSize;
|
||||
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "pagestotal");
|
||||
ram->bytesTotal = kn->value.ui64 * instance.state.platform.pageSize;
|
||||
ram->bytesTotal = kn->value.ui64 * instance.state.platform.sysinfo.pageSize;
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "pagesfree");
|
||||
ram->bytesUsed = ram->bytesTotal - kn->value.ui64 * instance.state.platform.pageSize;
|
||||
ram->bytesUsed = ram->bytesTotal - kn->value.ui64 * instance.state.platform.sysinfo.pageSize;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
+137
-50
@@ -1,21 +1,19 @@
|
||||
#include "detection/opencl/opencl.h"
|
||||
#include "detection/gpu/gpu.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <AvailabilityMacros.h>
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED > 1050) && !defined(__ppc__)
|
||||
#define MACOS_HAS_OPENCL
|
||||
#endif
|
||||
#if !defined(FF_HAVE_OPENCL) && defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_15)
|
||||
#define FF_HAVE_OPENCL 1
|
||||
#endif
|
||||
|
||||
#if defined(FF_HAVE_OPENCL) || defined(MACOS_HAS_OPENCL)
|
||||
#ifdef FF_HAVE_OPENCL
|
||||
|
||||
#include "common/library.h"
|
||||
#include "common/parsing.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include <string.h>
|
||||
|
||||
#define CL_TARGET_OPENCL_VERSION 100
|
||||
#ifdef FF_HAVE_OPENCL
|
||||
#define CL_TARGET_OPENCL_VERSION 110
|
||||
#ifndef __APPLE__
|
||||
#include <CL/cl.h>
|
||||
#else
|
||||
#include <OpenCL/cl.h>
|
||||
@@ -24,86 +22,175 @@
|
||||
typedef struct OpenCLData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(clGetPlatformIDs)
|
||||
FF_LIBRARY_SYMBOL(clGetDeviceIDs)
|
||||
FF_LIBRARY_SYMBOL(clGetPlatformInfo)
|
||||
FF_LIBRARY_SYMBOL(clGetDeviceInfo)
|
||||
FF_LIBRARY_SYMBOL(clGetDeviceIDs)
|
||||
} OpenCLData;
|
||||
|
||||
static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
|
||||
{
|
||||
cl_platform_id platformID = NULL;
|
||||
cl_platform_id platforms[32];
|
||||
cl_uint numPlatforms = 0;
|
||||
data->ffclGetPlatformIDs(1, &platformID, &numPlatforms);
|
||||
if (data->ffclGetPlatformIDs(sizeof(platforms) / sizeof(platforms[0]), platforms, &numPlatforms) != CL_SUCCESS)
|
||||
return "clGetPlatformIDs() failed";
|
||||
|
||||
if(numPlatforms == 0)
|
||||
if (numPlatforms == 0)
|
||||
return "clGetPlatformIDs returned 0 platforms";
|
||||
|
||||
cl_device_id deviceID = NULL;
|
||||
cl_uint numDevices = 0;
|
||||
data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_GPU, 1, &deviceID, &numDevices);
|
||||
char buffer[1024];
|
||||
for (cl_uint iplat = 0; iplat < numPlatforms; ++iplat)
|
||||
{
|
||||
if (data->ffclGetPlatformInfo(platforms[iplat], CL_PLATFORM_VERSION, sizeof(buffer), buffer, NULL) != CL_SUCCESS)
|
||||
return "clGetPlatformInfo() failed";
|
||||
|
||||
if(numDevices == 0)
|
||||
data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_ALL, 1, &deviceID, &numDevices);
|
||||
// Use the newest supported OpenCL version
|
||||
if (ffStrbufCompS(&result->version, buffer) < 0)
|
||||
{
|
||||
const char* versionPretty = buffer;
|
||||
if(ffStrStartsWithIgnCase(buffer, "OpenCL "))
|
||||
versionPretty = buffer + strlen("OpenCL ");
|
||||
ffStrbufSetS(&result->version, versionPretty);
|
||||
ffStrbufTrim(&result->version, ' ');
|
||||
|
||||
if(numDevices == 0)
|
||||
return "clGetDeviceIDs returned 0 devices";
|
||||
if (data->ffclGetPlatformInfo(platforms[iplat], CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
|
||||
ffStrbufSetS(&result->name, buffer);
|
||||
|
||||
char version[64] = "";
|
||||
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(version), version, NULL);
|
||||
if(!ffStrSet(version))
|
||||
return "clGetDeviceInfo returned NULL or empty string";
|
||||
if (data->ffclGetPlatformInfo(platforms[iplat], CL_PLATFORM_VENDOR, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
|
||||
ffStrbufSetS(&result->vendor, buffer);
|
||||
}
|
||||
|
||||
const char* versionPretty = version;
|
||||
if(ffStrStartsWithIgnCase(version, "OpenCL "))
|
||||
versionPretty = version + strlen("OpenCL ");
|
||||
ffStrbufSetS(&result->version, versionPretty);
|
||||
ffStrbufTrim(&result->version, ' ');
|
||||
cl_device_id deviceIDs[32];
|
||||
cl_uint numDevices = (cl_uint) (sizeof(deviceIDs) / sizeof(deviceIDs[0]));
|
||||
if (data->ffclGetDeviceIDs(platforms[iplat], CL_DEVICE_TYPE_GPU, numDevices, deviceIDs, &numDevices) != CL_SUCCESS)
|
||||
continue;
|
||||
|
||||
ffStrbufEnsureFree(&result->device, 128);
|
||||
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_NAME, result->device.allocated, result->device.chars, NULL);
|
||||
ffStrbufRecalculateLength(&result->device);
|
||||
ffStrbufTrim(&result->device, ' ');
|
||||
for (cl_uint idev = 0; idev < numDevices; ++idev)
|
||||
{
|
||||
cl_device_id deviceID = deviceIDs[idev];
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_NAME, sizeof(buffer), buffer, NULL) != CL_SUCCESS)
|
||||
continue;
|
||||
|
||||
ffStrbufEnsureFree(&result->vendor, 32);
|
||||
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR, result->vendor.allocated, result->vendor.chars, NULL);
|
||||
ffStrbufRecalculateLength(&result->vendor);
|
||||
ffStrbufTrim(&result->vendor, ' ');
|
||||
FFGPUResult* gpu = ffListAdd(&result->gpus);
|
||||
ffStrbufInitS(&gpu->name, buffer);
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
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 = (size_t) deviceID;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
|
||||
{
|
||||
ffStrbufSetS(&gpu->platformApi, buffer);
|
||||
ffStrbufTrimRight(&gpu->platformApi, ' ');
|
||||
}
|
||||
else
|
||||
ffStrbufSetStatic(&gpu->platformApi, "OpenCL");
|
||||
|
||||
{
|
||||
cl_uint vendorId;
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR_ID, sizeof(vendorId), &vendorId, NULL) == CL_SUCCESS)
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
if (gpu->vendor.length == 0 && data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
|
||||
ffStrbufSetS(&gpu->vendor, buffer);
|
||||
}
|
||||
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DRIVER_VERSION, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
|
||||
{
|
||||
const char* versionPretty = strchr(buffer, ' ');
|
||||
if (versionPretty && *versionPretty)
|
||||
ffStrbufSetS(&gpu->driver, versionPretty + 1);
|
||||
else
|
||||
ffStrbufSetS(&gpu->driver, buffer);
|
||||
}
|
||||
|
||||
{
|
||||
cl_uint value;
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(value), &value, NULL) == CL_SUCCESS)
|
||||
gpu->coreCount = (int32_t) value;
|
||||
}
|
||||
|
||||
{
|
||||
cl_uint value;
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(value), &value, NULL) == CL_SUCCESS)
|
||||
gpu->frequency = value / 1000.;
|
||||
}
|
||||
|
||||
{
|
||||
cl_bool value;
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof(value), &value, NULL) == CL_SUCCESS)
|
||||
{
|
||||
gpu->type = value ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
|
||||
cl_ulong memSize;
|
||||
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(memSize), &memSize, NULL) == CL_SUCCESS)
|
||||
{
|
||||
if (gpu->type == FF_GPU_TYPE_INTEGRATED)
|
||||
gpu->shared.total = memSize;
|
||||
else
|
||||
gpu->dedicated.total = memSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // defined(FF_HAVE_OPENCL) || defined(MACOS_HAS_OPENCL)
|
||||
|
||||
const char* ffDetectOpenCL(FFOpenCLResult* result)
|
||||
static const char* detectOpenCL(FFOpenCLResult* result)
|
||||
{
|
||||
#ifdef FF_HAVE_OPENCL
|
||||
|
||||
OpenCLData data;
|
||||
|
||||
FF_LIBRARY_LOAD(opencl, &instance.config.library.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed",
|
||||
#ifndef __APPLE__
|
||||
|
||||
FF_LIBRARY_LOAD(opencl, &instance.config.library.libOpenCL, "dlopen libOpenCL" FF_LIBRARY_EXTENSION" failed",
|
||||
#ifdef _WIN32
|
||||
"OpenCL"FF_LIBRARY_EXTENSION, -1,
|
||||
#endif
|
||||
"libOpenCL"FF_LIBRARY_EXTENSION, 1
|
||||
);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetPlatformIDs);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetPlatformInfo);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceIDs);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceInfo);
|
||||
|
||||
return openCLHandleData(&data, result);
|
||||
|
||||
#elif defined(MACOS_HAS_OPENCL) // FF_HAVE_OPENCL
|
||||
#else
|
||||
|
||||
OpenCLData data;
|
||||
data.ffclGetPlatformIDs = clGetPlatformIDs;
|
||||
data.ffclGetPlatformInfo = clGetPlatformInfo;
|
||||
data.ffclGetDeviceIDs = clGetDeviceIDs;
|
||||
data.ffclGetDeviceInfo = clGetDeviceInfo;
|
||||
|
||||
return openCLHandleData(&data, result);
|
||||
|
||||
#else
|
||||
|
||||
FF_UNUSED(result);
|
||||
return "Fastfetch was build without OpenCL support";
|
||||
|
||||
#endif // FF_HAVE_OPENCL
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // defined(FF_HAVE_OPENCL)
|
||||
|
||||
FFOpenCLResult* ffDetectOpenCL(void)
|
||||
{
|
||||
static FFOpenCLResult result;
|
||||
|
||||
if (result.gpus.elementSize == 0)
|
||||
{
|
||||
ffStrbufInit(&result.version);
|
||||
ffStrbufInit(&result.name);
|
||||
ffStrbufInit(&result.vendor);
|
||||
ffListInit(&result.gpus, sizeof(FFGPUResult));
|
||||
|
||||
#ifdef FF_HAVE_OPENCL
|
||||
result.error = detectOpenCL(&result);
|
||||
#else
|
||||
result.error = "fastfetch was compiled without OpenCL support";
|
||||
#endif
|
||||
}
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
typedef struct FFOpenCLResult
|
||||
{
|
||||
FFstrbuf version;
|
||||
FFstrbuf device;
|
||||
FFstrbuf name;
|
||||
FFstrbuf vendor;
|
||||
FFlist gpus; //List of FFGPUResult, see detection/gpu/gpu.h
|
||||
const char* error;
|
||||
} FFOpenCLResult;
|
||||
|
||||
const char* ffDetectOpenCL(FFOpenCLResult* result);
|
||||
FFOpenCLResult* ffDetectOpenCL();
|
||||
|
||||
+14
-13
@@ -54,18 +54,18 @@ static bool detectOSCodeName(FFOSResult* os)
|
||||
case 14: ffStrbufSetStatic(&os->codename, "Mojave"); return true;
|
||||
case 13: ffStrbufSetStatic(&os->codename, "High Sierra"); return true;
|
||||
case 12: ffStrbufSetStatic(&os->codename, "Sierra"); return true;
|
||||
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); return true;
|
||||
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); return true;
|
||||
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); return true;
|
||||
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); return true;
|
||||
case 7: ffStrbufSetStatic(&os->codename, "Lion"); return true;
|
||||
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); return true;
|
||||
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); return true;
|
||||
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); return true;
|
||||
case 3: ffStrbufSetStatic(&os->codename, "Panther"); return true;
|
||||
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); return true;
|
||||
case 1: ffStrbufSetStatic(&os->codename, "Puma"); return true;
|
||||
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); return true;
|
||||
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
|
||||
case 7: ffStrbufSetStatic(&os->codename, "Lion"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 3: ffStrbufSetStatic(&os->codename, "Panther"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 1: ffStrbufSetStatic(&os->codename, "Puma"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,8 @@ void ffDetectOSImpl(FFOSResult* os)
|
||||
if(os->buildID.length == 0)
|
||||
ffSysctlGetString("kern.osversion", &os->buildID);
|
||||
|
||||
ffStrbufAppend(&os->prettyName, &os->name);
|
||||
if(os->prettyName.length == 0)
|
||||
ffStrbufSetStatic(&os->prettyName, "macOS");
|
||||
ffStrbufAppend(&os->versionID, &os->version);
|
||||
|
||||
if(!detectOSCodeName(os))
|
||||
|
||||
@@ -313,19 +313,6 @@ static uint32_t getSnap(FFstrbuf* baseDir)
|
||||
return result > 0 ? result - 1 : 0;
|
||||
}
|
||||
|
||||
static uint32_t getFlatpak(FFstrbuf* baseDir, const char* dirname)
|
||||
{
|
||||
uint32_t baseDirLength = baseDir->length;
|
||||
ffStrbufAppendS(baseDir, dirname);
|
||||
|
||||
uint32_t result =
|
||||
getNumElements(baseDir, "/app", DT_DIR) +
|
||||
getNumElements(baseDir, "/runtime", DT_DIR);
|
||||
|
||||
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_RPM
|
||||
#include "common/library.h"
|
||||
#include <rpm/rpmlib.h>
|
||||
@@ -459,7 +446,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_EMERGE_BIT)) packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_EOPKG_BIT)) packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getFlatpak(baseDir, "/var/lib/flatpak");
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR);
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_NIX_BIT))
|
||||
{
|
||||
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
|
||||
@@ -587,5 +574,5 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
|
||||
}
|
||||
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT))
|
||||
result->flatpakUser = getFlatpak(&baseDir, "/.local/share/flatpak");
|
||||
result->flatpakUser = getNumElements(&baseDir, "/.local/share/flatpak/app", DT_DIR);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "physicaldisk.h"
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
const char* ffDetectPhysicalDisk(FF_MAYBE_UNUSED FFlist* result, FF_MAYBE_UNUSED FFPhysicalDiskOptions* options)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
|
||||
@@ -100,11 +100,11 @@ const char* ffDetectPhysicalMemory(FFlist* result)
|
||||
if (data->Size != 0xFFFF)
|
||||
{
|
||||
if (data->Size == 0x7FFF)
|
||||
device->size = (data->ExtendedSize & ~(1 << 31)) * 1024 * 1024;
|
||||
device->size = (data->ExtendedSize & ~(1ULL << 31)) * 1024ULL * 1024ULL;
|
||||
else if (data->Size & (1 << 15))
|
||||
{
|
||||
// in kB
|
||||
device->size = (data->Size & ~(1u << 15)) * 1024ULL;
|
||||
device->size = (data->Size & ~(1ULL << 15)) * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@ const char* ffDetectSwap(FFSwapResult* swap)
|
||||
swap->bytesTotal += (uint64_t) xsw.xsw_nblks;
|
||||
}
|
||||
|
||||
swap->bytesUsed *= instance.state.platform.pageSize;
|
||||
swap->bytesTotal *= instance.state.platform.pageSize;
|
||||
swap->bytesUsed *= instance.state.platform.sysinfo.pageSize;
|
||||
swap->bytesTotal *= instance.state.platform.sysinfo.pageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ const char* ffDetectSwap(FFSwapResult* swap)
|
||||
swap->bytesUsed += (uint64_t) table->swt_ent[i].ste_free;
|
||||
}
|
||||
swap->bytesUsed = swap->bytesTotal - swap->bytesUsed;
|
||||
swap->bytesTotal *= instance.state.platform.pageSize;
|
||||
swap->bytesUsed *= instance.state.platform.pageSize;
|
||||
swap->bytesTotal *= instance.state.platform.sysinfo.pageSize;
|
||||
swap->bytesUsed *= instance.state.platform.sysinfo.pageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const char* ffDetectSwap(FFSwapResult* swap)
|
||||
if(!NT_SUCCESS(NtQuerySystemInformation(SystemPagefileInformation, pstart, size, &size)))
|
||||
return "NtQuerySystemInformation(SystemPagefileInformation, size) failed";
|
||||
|
||||
uint32_t pageSize = instance.state.platform.pageSize;
|
||||
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
|
||||
swap->bytesUsed = (uint64_t)pstart->TotalUsed * pageSize;
|
||||
swap->bytesTotal = (uint64_t)pstart->CurrentSize * pageSize;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "terminalfont.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/processing.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
@@ -256,42 +257,66 @@ static void detectFromWindowsTerminal(const FFstrbuf* terminalExe, FFTerminalFon
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //defined(_WIN32) || defined(__linux__)
|
||||
|
||||
static bool queryKittyTerm(const char* query, FFstrbuf* res)
|
||||
{
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
|
||||
char buffer[64] = "";
|
||||
if (ffGetTerminalResponse(
|
||||
query, // kitty-query-font_family;kitty-query-font_size
|
||||
"\eP1+r%*[^=]=%64[^\e]\e\\", buffer) == NULL && *buffer)
|
||||
{
|
||||
// decode hex string
|
||||
for (const char* p = buffer; p[0] && p[1]; p += 2)
|
||||
{
|
||||
unsigned value;
|
||||
if (sscanf(p, "%2x", &value) == 1)
|
||||
ffStrbufAppendC(res, (char) value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool detectKitty(const FFstrbuf* exe, FFTerminalFontResult* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate();
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
if(!ffProcessAppendStdOut(&buf, (char* const[]){
|
||||
exe->chars,
|
||||
"+kitten",
|
||||
"query-terminal",
|
||||
NULL,
|
||||
}))
|
||||
{
|
||||
ffParsePropLines(buf.chars, "font_family: ", &fontName);
|
||||
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
|
||||
}
|
||||
// Kitty generates response independently even if we query font family and size in one query
|
||||
// which may result in short read in `ffGetTerminalResponse`
|
||||
if (queryKittyTerm("\eP+q6b697474792d71756572792d666f6e745f66616d696c79\e\\", &fontName)) // kitty-query-font_family
|
||||
queryKittyTerm("\eP+q6b697474792d71756572792d666f6e745f73697a65\e\\", &fontSize); // kitty-query-font_size
|
||||
else
|
||||
{
|
||||
FFpropquery fontQuery[] = {
|
||||
{"font_family ", &fontName},
|
||||
{"font_size ", &fontSize},
|
||||
};
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
if(!ffProcessAppendStdOut(&buf, (char* const[]){
|
||||
exe->chars,
|
||||
"+kitten",
|
||||
"query-terminal",
|
||||
NULL,
|
||||
}))
|
||||
{
|
||||
ffParsePropLines(buf.chars, "font_family: ", &fontName);
|
||||
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFpropquery fontQuery[] = {
|
||||
{"font_family ", &fontName},
|
||||
{"font_size ", &fontSize},
|
||||
};
|
||||
|
||||
ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery);
|
||||
ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery);
|
||||
|
||||
if(fontName.length == 0)
|
||||
ffStrbufSetS(&fontName, "monospace");
|
||||
if(fontSize.length == 0)
|
||||
ffStrbufSetS(&fontSize, "11.0");
|
||||
if(fontName.length == 0)
|
||||
ffStrbufSetS(&fontName, "monospace");
|
||||
if(fontSize.length == 0)
|
||||
ffStrbufSetS(&fontSize, "11.0");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -50,6 +50,26 @@ static void detectKgx(FFTerminalFontResult* terminalFont)
|
||||
}
|
||||
}
|
||||
|
||||
static void detectPtyxis(FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(!ffSettingsGet("/org/gnome/Ptyxis/use-system-font", "org.gnome.Ptyxis", NULL, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue)
|
||||
{
|
||||
FF_AUTO_FREE const char* fontName = ffSettingsGet("/org/gnome/Ptyxis/font-name", "org.gnome.Ptyxis", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(fontName))
|
||||
ffFontInitPango(&terminalFont->font, fontName);
|
||||
else
|
||||
ffStrbufAppendF(&terminalFont->error, "Couldn't get terminal font from GSettings (org.gnome.Ptyxis::font-name)");
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_AUTO_FREE const char* fontName = getSystemMonospaceFont();
|
||||
if(ffStrSet(fontName))
|
||||
ffFontInitPango(&terminalFont->font, fontName);
|
||||
else
|
||||
ffStrbufAppendS(&terminalFont->error, "Couldn't get system monospace font name from GSettings / DConf");
|
||||
}
|
||||
}
|
||||
|
||||
static void detectFromGSettings(const char* profilePath, const char* profileList, const char* profile, const char* defaultProfileKey, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FF_AUTO_FREE const char* defaultProfile = ffSettingsGetGSettings(profileList, NULL, defaultProfileKey, FF_VARIANT_TYPE_STRING).strValue;
|
||||
@@ -386,6 +406,8 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
|
||||
detectFromGSettings("/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "gnome-terminal"))
|
||||
detectFromGSettings("/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "ptyxis-agent"))
|
||||
detectPtyxis(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "kgx"))
|
||||
detectKgx(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "mate-terminal"))
|
||||
|
||||
@@ -480,37 +480,39 @@ static bool getTerminalVersionZellij(FFstrbuf* exe, FFstrbuf* version)
|
||||
#ifndef _WIN32
|
||||
static bool getTerminalVersionKitty(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
// kitty is written in python. `kitty --version` can be expensive
|
||||
char buffer[1024] = {};
|
||||
if (
|
||||
#ifdef __linux__
|
||||
ffReadFileData(FASTFETCH_TARGET_DIR_USR "/lib64/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer) ||
|
||||
ffReadFileData(FASTFETCH_TARGET_DIR_USR "/lib/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer)
|
||||
#else
|
||||
ffReadFileData(_PATH_LOCALBASE "/share/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer)
|
||||
#endif
|
||||
)
|
||||
char versionHex[64] = "";
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
|
||||
if (ffGetTerminalResponse(
|
||||
"\eP+q6b697474792d71756572792d76657273696f6e\e\\", // kitty-query-version
|
||||
"\eP1+r%*[^=]=%64[^\e]\e\\\\", versionHex) == NULL && *versionHex)
|
||||
{
|
||||
// Starts from version 0.17.0
|
||||
// https://github.com/kovidgoyal/kitty/blob/master/kitty/constants.py#L25
|
||||
const char* p = memmem(buffer, sizeof(buffer) - 1, "version: Version = Version(", strlen("version: Version = Version("));
|
||||
if (p)
|
||||
// decode hex string
|
||||
for (const char* p = versionHex; p[0] && p[1]; p += 2)
|
||||
{
|
||||
p += strlen("version: Version = Version(");
|
||||
int major, minor, patch;
|
||||
if (sscanf(p, "%d,%d,%d", &major, &minor, &patch) == 3)
|
||||
{
|
||||
ffStrbufSetF(version, "%d.%d.%d", major, minor, patch);
|
||||
return true;
|
||||
}
|
||||
unsigned value;
|
||||
if (sscanf(p, "%2x", &value) == 1)
|
||||
ffStrbufAppendC(version, (char) value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//kitty 0.21.2 created by Kovid Goyal
|
||||
return getExeVersionGeneral(exe, version);
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionPtyxis(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
if(ffProcessAppendStdOut(version, (char* const[]) {
|
||||
"ptyxis",
|
||||
"--version",
|
||||
NULL
|
||||
}) != NULL)
|
||||
return false;
|
||||
|
||||
ffStrbufSubstrBeforeFirstC(version, '\n');
|
||||
ffStrbufSubstrAfterFirstC(version, ' ');
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -607,6 +609,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
||||
)
|
||||
return getTerminalVersionUrxvt(exe, version);
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(processName, "ptyxis-agent"))
|
||||
return getTerminalVersionPtyxis(exe, version);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -331,6 +331,8 @@ static void setTerminalInfoDetails(FFTerminalResult* result)
|
||||
ffStrbufEqualS(&result->processName, "rxvt")
|
||||
)
|
||||
ffStrbufInitStatic(&result->prettyName, "rxvt-unicode");
|
||||
else if(ffStrbufStartsWithS(&result->processName, "ptyxis-agent"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Ptyxis");
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
|
||||
@@ -5,9 +5,19 @@
|
||||
|
||||
bool ffDetectTerminalSize(FFTerminalSizeResult* result)
|
||||
{
|
||||
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
|
||||
{
|
||||
DWORD outputMode;
|
||||
if (!GetConsoleMode(hOutput, &outputMode))
|
||||
{
|
||||
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
|
||||
hOutput = hConout;
|
||||
}
|
||||
}
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
|
||||
if (GetConsoleScreenBufferInfo(hOutput, &csbi))
|
||||
{
|
||||
result->columns = (uint16_t) (csbi.srWindow.Right - csbi.srWindow.Left + 1);
|
||||
result->rows = (uint16_t) (csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
|
||||
@@ -23,7 +33,7 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result)
|
||||
|
||||
{
|
||||
CONSOLE_FONT_INFO cfi;
|
||||
if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi)) // Only works for ConHost
|
||||
if(GetCurrentConsoleFont(hOutput, FALSE, &cfi)) // Only works for ConHost
|
||||
{
|
||||
result->width = result->columns * (uint16_t) cfi.dwFontSize.X;
|
||||
result->height = result->rows * (uint16_t) cfi.dwFontSize.Y;
|
||||
|
||||
@@ -53,7 +53,7 @@ const char* ffDetectTheme(FFThemeResult* result)
|
||||
}
|
||||
|
||||
if(plasma->widgetStyle.length > 0 || plasma->colorScheme.length > 0)
|
||||
ffStrbufAppendS(&result->theme1, " [QT]");
|
||||
ffStrbufAppendS(&result->theme1, " [Qt]");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -20,43 +20,61 @@
|
||||
#define FF_ARCHITECTURE "unknown"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
#define FF_SYSNAME "Linux"
|
||||
#elif defined(__FreeBSD__)
|
||||
#define FF_SYSNAME "FreeBSD"
|
||||
#elif defined(__APPLE__)
|
||||
#define FF_SYSNAME "Darwin"
|
||||
#elif defined(_WIN32)
|
||||
#define FF_SYSNAME "WIN32"
|
||||
#elif defined(__sun)
|
||||
#define FF_SYSNAME "SunOS"
|
||||
#else
|
||||
#define FF_SYSNAME "unknown"
|
||||
#endif
|
||||
|
||||
#define FF_STR_INDIR(x) #x
|
||||
#define FF_STR(x) FF_STR_INDIR(x)
|
||||
|
||||
void ffDetectVersion(FFVersionResult* version)
|
||||
{
|
||||
version->projectName = FASTFETCH_PROJECT_NAME;
|
||||
version->architecture = FF_ARCHITECTURE;
|
||||
version->version = FASTFETCH_PROJECT_VERSION;
|
||||
version->versionTweak = FASTFETCH_PROJECT_VERSION_TWEAK;
|
||||
version->cmakeBuiltType = FASTFETCH_PROJECT_CMAKE_BUILD_TYPE;
|
||||
version->compileTime = __DATE__ ", " __TIME__;
|
||||
FFVersionResult ffVersionResult = {
|
||||
.projectName = FASTFETCH_PROJECT_NAME,
|
||||
.sysName = FF_SYSNAME,
|
||||
.architecture = FF_ARCHITECTURE,
|
||||
.version = FASTFETCH_PROJECT_VERSION,
|
||||
.versionTweak = FASTFETCH_PROJECT_VERSION_TWEAK,
|
||||
.cmakeBuiltType = FASTFETCH_PROJECT_CMAKE_BUILD_TYPE,
|
||||
.compileTime = __DATE__ ", " __TIME__,
|
||||
.compiler =
|
||||
|
||||
#ifdef __clang__
|
||||
version->compiler =
|
||||
#ifdef _MSC_VER
|
||||
"clang-cl " ;
|
||||
#elif defined(__APPLE__) && defined(__apple_build_version__)
|
||||
"Apple clang "
|
||||
#else
|
||||
"clang "
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
"clang-cl " ;
|
||||
#elif defined(__APPLE__) && defined(__apple_build_version__)
|
||||
"Apple clang "
|
||||
#else
|
||||
"clang "
|
||||
#endif
|
||||
|
||||
FF_STR(__clang_major__) "." FF_STR(__clang_minor__) "." FF_STR(__clang_patchlevel__)
|
||||
FF_STR(__clang_major__) "." FF_STR(__clang_minor__) "." FF_STR(__clang_patchlevel__)
|
||||
|
||||
#if defined(__APPLE__) && defined(__apple_build_version__)
|
||||
" (" FF_STR(__apple_build_version__) ")"
|
||||
#endif
|
||||
;
|
||||
#if defined(__APPLE__) && defined(__apple_build_version__)
|
||||
" (" FF_STR(__apple_build_version__) ")"
|
||||
#endif
|
||||
,
|
||||
#elif defined(__GNUC__)
|
||||
version->compiler = "gcc " FF_STR(__GNUC__) "." FF_STR(__GNUC_MINOR__) "." FF_STR(__GNUC_PATCHLEVEL__);
|
||||
"gcc " FF_STR(__GNUC__) "." FF_STR(__GNUC_MINOR__) "." FF_STR(__GNUC_PATCHLEVEL__),
|
||||
#elif defined(_MSC_VER)
|
||||
version->compiler = "msvc " FF_STR(_MSC_VER);
|
||||
"msvc " FF_STR(_MSC_VER),
|
||||
#else
|
||||
version->compiler = "unknown";
|
||||
"unknown",
|
||||
#endif
|
||||
|
||||
.debugMode =
|
||||
#ifndef NDEBUG
|
||||
version->debugMode = true;
|
||||
true,
|
||||
#else
|
||||
version->debugMode = false;
|
||||
false,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
typedef struct FFVersionResult
|
||||
{
|
||||
const char* projectName;
|
||||
const char* sysName;
|
||||
const char* architecture;
|
||||
const char* version;
|
||||
const char* versionTweak;
|
||||
@@ -14,4 +15,4 @@ typedef struct FFVersionResult
|
||||
bool debugMode;
|
||||
} FFVersionResult;
|
||||
|
||||
void ffDetectVersion(FFVersionResult* version);
|
||||
extern FFVersionResult ffVersionResult;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "wifi.h"
|
||||
|
||||
const char* ffDetectWifi(FFlist* result)
|
||||
const char* ffDetectWifi(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
return "Not support on this platform";
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ static bool detectOpenbox(const FFstrbuf* dePrettyName, FFstrbuf* themeOrError)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(64);
|
||||
const char *configFileSubpath = "openbox/rc.xml";
|
||||
if (ffStrbufIgnCaseCompS(dePrettyName, "LXQT") == 0)
|
||||
if (ffStrbufIgnCaseCompS(dePrettyName, "LXQt") == 0)
|
||||
configFileSubpath = "openbox/lxqt-rc.xml";
|
||||
else if (ffStrbufIgnCaseCompS(dePrettyName, "LXDE") == 0)
|
||||
configFileSubpath = "openbox/lxde-rc.xml";
|
||||
|
||||
+2
-3
@@ -501,9 +501,8 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
|
||||
|
||||
static void printVersion()
|
||||
{
|
||||
FFVersionResult result = {};
|
||||
ffDetectVersion(&result);
|
||||
printf("%s %s%s%s (%s)\n", result.projectName, result.version, result.versionTweak, result.debugMode ? "-debug" : "", result.architecture);
|
||||
FFVersionResult* result = &ffVersionResult;
|
||||
printf("%s %s%s%s (%s)\n", result->projectName, result->version, result->versionTweak, result->debugMode ? "-debug" : "", result->architecture);
|
||||
}
|
||||
|
||||
static void parseCommand(FFdata* data, char* key, char* value)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$1 ## $2**
|
||||
## $2**
|
||||
$1*####$2****.
|
||||
$1###$2,
|
||||
$3...,$1/#$3,,,..
|
||||
@@ -15,4 +15,4 @@ $3((((((((((((((((((((($5@@@$6&%&$5@@@%$4,..........
|
||||
$3/(((((((((((($5@@@@@@/$4.../&&
|
||||
$3.((((((((($5@@@@($4....
|
||||
$3/((((($5@@#$4...
|
||||
$3.(($4&,
|
||||
$3.(($4&,
|
||||
|
||||
+2
-2
@@ -484,7 +484,7 @@ static const FFlogo A[] = {
|
||||
FF_COLOR_FG_YELLOW,
|
||||
FF_COLOR_FG_GREEN,
|
||||
FF_COLOR_FG_RED,
|
||||
"38", //cyan
|
||||
FF_COLOR_FG_LIGHT_BLACK,
|
||||
FF_COLOR_FG_WHITE,
|
||||
FF_COLOR_FG_CYAN,
|
||||
FF_COLOR_FG_BLUE,
|
||||
@@ -1520,7 +1520,7 @@ static const FFlogo F[] = {
|
||||
FF_COLOR_FG_YELLOW,
|
||||
FF_COLOR_FG_GREEN,
|
||||
FF_COLOR_FG_RED,
|
||||
"38", //cyan
|
||||
FF_COLOR_FG_LIGHT_BLACK,
|
||||
FF_COLOR_FG_WHITE,
|
||||
FF_COLOR_FG_CYAN,
|
||||
FF_COLOR_FG_BLUE,
|
||||
|
||||
+111
-34
@@ -10,6 +10,10 @@
|
||||
#include <sys/syslimits.h>
|
||||
#elif _WIN32
|
||||
#include <windows.h>
|
||||
#elif __linux__
|
||||
#include <sys/sendfile.h>
|
||||
#elif __sun
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
|
||||
// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145
|
||||
@@ -72,25 +76,31 @@ static bool printImageIterm(bool printError)
|
||||
|
||||
if (!options->width || !options->height)
|
||||
{
|
||||
if (!options->separate)
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
ffStrbufAppendF(&buf, "\e[2J\e[3J\e[%u;%uH",
|
||||
(unsigned) options->paddingTop,
|
||||
(unsigned) options->paddingLeft
|
||||
);
|
||||
}
|
||||
else
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
ffStrbufAppendNC(&buf, options->paddingTop, '\n');
|
||||
ffStrbufAppendNC(&buf, options->paddingLeft, ' ');
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
{
|
||||
if (printError)
|
||||
fputs("Logo (iterm): Must set logo width and height\n", stderr);
|
||||
return false;
|
||||
}
|
||||
if (options->width)
|
||||
ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u:%s\a", (unsigned) options->width, base64.chars);
|
||||
else
|
||||
ffStrbufAppendF(&buf, "\e]1337;File=inline=1:%s\a", base64.chars);
|
||||
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf);
|
||||
|
||||
if (!options->separate)
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
uint16_t X = 0, Y = 0;
|
||||
const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X);
|
||||
@@ -103,7 +113,7 @@ static bool printImageIterm(bool printError)
|
||||
instance.state.logoHeight = Y;
|
||||
fputs("\e[H", stdout);
|
||||
}
|
||||
else
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
ffPrintCharTimes('\n', options->paddingRight);
|
||||
@@ -112,7 +122,10 @@ static bool printImageIterm(bool printError)
|
||||
else
|
||||
{
|
||||
ffStrbufAppendNC(&buf, options->paddingTop, '\n');
|
||||
ffStrbufAppendNC(&buf, options->paddingLeft, ' ');
|
||||
if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
ffStrbufAppendF(&buf, "\e[9999999C\e[%uD", (unsigned) options->paddingRight + options->width);
|
||||
else
|
||||
ffStrbufAppendF(&buf, "\e[%uC", (unsigned) options->paddingLeft);
|
||||
ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\n",
|
||||
(unsigned) options->width,
|
||||
(unsigned) options->height,
|
||||
@@ -120,17 +133,22 @@ static bool printImageIterm(bool printError)
|
||||
base64.chars
|
||||
);
|
||||
|
||||
if (!options->separate)
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
instance.state.logoWidth = options->width + options->paddingLeft + options->paddingRight;
|
||||
instance.state.logoHeight = options->paddingTop + options->height;
|
||||
ffStrbufAppendF(&buf, "\e[%uA", (unsigned) instance.state.logoHeight);
|
||||
}
|
||||
else
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
ffStrbufAppendNC(&buf, options->paddingRight, '\n');
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
ffStrbufAppendF(&buf, "\e[1G\e[%uA", (unsigned) options->height);
|
||||
}
|
||||
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf);
|
||||
}
|
||||
|
||||
@@ -152,7 +170,7 @@ static bool printImageKittyDirect(bool printError)
|
||||
|
||||
if (!options->width || !options->height)
|
||||
{
|
||||
if (!options->separate)
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
// We must clear the entre screen to make sure that terminal buffer won't scroll up
|
||||
printf("\e[2J\e[3J\e[%u;%uH",
|
||||
@@ -160,18 +178,24 @@ static bool printImageKittyDirect(bool printError)
|
||||
(unsigned) options->paddingLeft
|
||||
);
|
||||
}
|
||||
else
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
ffPrintCharTimes('\n', options->paddingTop);
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
{
|
||||
if (printError)
|
||||
fputs("Logo (iterm): Must set logo width and height\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options->width)
|
||||
printf("\e_Ga=T,f=100,t=f,c=%u;%s\e\\", (unsigned) options->width, base64.chars);
|
||||
else
|
||||
printf("\e_Ga=T,f=100,t=f;%s\e\\", base64.chars);
|
||||
fflush(stdout);
|
||||
if (!options->separate)
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
uint16_t X = 0, Y = 0;
|
||||
const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X);
|
||||
@@ -184,7 +208,7 @@ static bool printImageKittyDirect(bool printError)
|
||||
instance.state.logoHeight = Y;
|
||||
fputs("\e[H", stdout);
|
||||
}
|
||||
else
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
ffPrintCharTimes('\n', options->paddingRight);
|
||||
@@ -193,24 +217,32 @@ static bool printImageKittyDirect(bool printError)
|
||||
else
|
||||
{
|
||||
ffPrintCharTimes('\n', options->paddingTop);
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
printf("\e[9999999C\e[%uD", (unsigned) options->paddingRight + options->width);
|
||||
else
|
||||
printf("\e[%uC", (unsigned) options->paddingLeft);
|
||||
|
||||
printf("\e_Ga=T,f=100,t=f,c=%u,r=%u;%s\e\\\n",
|
||||
(unsigned) options->width,
|
||||
(unsigned) options->height,
|
||||
base64.chars
|
||||
);
|
||||
if (!options->separate)
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
instance.state.logoWidth = options->width + options->paddingLeft + options->paddingRight;
|
||||
instance.state.logoHeight = options->paddingTop + options->height;
|
||||
printf("\e[%uA", (unsigned) instance.state.logoHeight);
|
||||
}
|
||||
else
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
ffPrintCharTimes('\n', options->paddingRight);
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
printf("\e[1G\e[%uA", (unsigned) options->height);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -345,12 +377,21 @@ static void printImagePixels(FFLogoRequestData* requestData, const FFstrbuf* res
|
||||
|
||||
//Write result to stdout
|
||||
ffPrintCharTimes('\n', options->paddingTop);
|
||||
ffPrintCharTimes(' ', options->paddingLeft);
|
||||
if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
printf("\e[9999999C\e[%uD", (unsigned) options->paddingRight + requestData->logoCharacterWidth);
|
||||
else
|
||||
printf("\e[%uC", (unsigned) options->paddingLeft);
|
||||
fflush(stdout);
|
||||
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), result);
|
||||
|
||||
//Go to upper left corner
|
||||
printf("\e[1G\e[%uA", instance.state.logoHeight);
|
||||
if (options->position != FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
//Go to upper left corner
|
||||
printf("\e[1G\e[%uA", instance.state.logoHeight);
|
||||
}
|
||||
|
||||
if (options->position != FF_LOGO_POSITION_LEFT)
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
}
|
||||
|
||||
static bool printImageSixel(FFLogoRequestData* requestData, const ImageData* imageData)
|
||||
@@ -631,15 +672,20 @@ FFLogoImageResult ffLogoPrintImageImpl(FFLogoRequestData* requestData, const FFI
|
||||
return printSuccessful ? FF_LOGO_IMAGE_RESULT_SUCCESS : FF_LOGO_IMAGE_RESULT_RUN_ERROR;
|
||||
}
|
||||
|
||||
static int getCacheFD(FFLogoRequestData* requestData, const char* fileName)
|
||||
static FFNativeFD getCacheFD(FFLogoRequestData* requestData, const char* fileName)
|
||||
{
|
||||
uint32_t cacheDirLength = requestData->cacheDir.length;
|
||||
ffStrbufAppendS(&requestData->cacheDir, fileName);
|
||||
#ifndef _WIN32
|
||||
int fd = open(requestData->cacheDir.chars, O_RDONLY
|
||||
#ifdef O_CLOEXEC
|
||||
| O_CLOEXEC
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
HANDLE fd = CreateFileA(requestData->cacheDir.chars, GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#endif
|
||||
ffStrbufSubstrBefore(&requestData->cacheDir, cacheDirLength);
|
||||
return fd;
|
||||
}
|
||||
@@ -683,7 +729,9 @@ static bool printCachedChars(FFLogoRequestData* requestData)
|
||||
|
||||
static bool printCachedPixel(FFLogoRequestData* requestData)
|
||||
{
|
||||
requestData->logoCharacterWidth = instance.config.logo.width;
|
||||
FFOptionsLogo* options = &instance.config.logo;
|
||||
|
||||
requestData->logoCharacterWidth = options->width;
|
||||
if(requestData->logoCharacterWidth == 0)
|
||||
{
|
||||
requestData->logoCharacterWidth = readCachedUint32(requestData, FF_CACHE_FILE_WIDTH);
|
||||
@@ -691,7 +739,7 @@ static bool printCachedPixel(FFLogoRequestData* requestData)
|
||||
return false;
|
||||
}
|
||||
|
||||
requestData->logoCharacterHeight = instance.config.logo.height;
|
||||
requestData->logoCharacterHeight = options->height;
|
||||
if(requestData->logoCharacterHeight == 0)
|
||||
{
|
||||
requestData->logoCharacterHeight = readCachedUint32(requestData, FF_CACHE_FILE_HEIGHT);
|
||||
@@ -699,35 +747,64 @@ static bool printCachedPixel(FFLogoRequestData* requestData)
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = -1;
|
||||
FF_AUTO_CLOSE_FD FFNativeFD fd = FF_INVALID_FD;
|
||||
if(requestData->type == FF_LOGO_TYPE_IMAGE_KITTY)
|
||||
{
|
||||
fd = getCacheFD(requestData, FF_CACHE_FILE_KITTY_COMPRESSED);
|
||||
if(fd == -1)
|
||||
if(fd == FF_INVALID_FD)
|
||||
fd = getCacheFD(requestData, FF_CACHE_FILE_KITTY_UNCOMPRESSED);
|
||||
}
|
||||
else if(requestData->type == FF_LOGO_TYPE_IMAGE_SIXEL)
|
||||
fd = getCacheFD(requestData, FF_CACHE_FILE_SIXEL);
|
||||
|
||||
if(fd == -1)
|
||||
if(fd == FF_INVALID_FD)
|
||||
return false;
|
||||
|
||||
ffPrintCharTimes('\n', instance.config.logo.paddingTop);
|
||||
ffPrintCharTimes(' ', instance.config.logo.paddingLeft);
|
||||
ffPrintCharTimes('\n', options->paddingTop);
|
||||
if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
printf("\e[9999999C\e[%uD", (unsigned) options->paddingRight + requestData->logoCharacterWidth);
|
||||
else
|
||||
printf("\e[%uC", (unsigned) options->paddingLeft);
|
||||
fflush(stdout);
|
||||
|
||||
char buffer[32768];
|
||||
ssize_t readBytes;
|
||||
while((readBytes = ffReadFDData(FFUnixFD2NativeFD(fd), sizeof(buffer), buffer)) > 0)
|
||||
ffWriteFDData(FFUnixFD2NativeFD(STDOUT_FILENO), (size_t) readBytes, buffer);
|
||||
bool sent = false;
|
||||
#ifdef __linux__
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) >= 0)
|
||||
{
|
||||
while (st.st_size > 0)
|
||||
{
|
||||
ssize_t bytes = sendfile(STDOUT_FILENO, fd, NULL, (size_t) st.st_size);
|
||||
if (bytes > 0)
|
||||
{
|
||||
sent = true;
|
||||
st.st_size -= bytes;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
close(fd);
|
||||
if (!sent)
|
||||
{
|
||||
char buffer[32768];
|
||||
ssize_t readBytes;
|
||||
while((readBytes = ffReadFDData(fd, sizeof(buffer), buffer)) > 0)
|
||||
ffWriteFDData(FFUnixFD2NativeFD(STDOUT_FILENO), (size_t) readBytes, buffer);
|
||||
}
|
||||
|
||||
instance.state.logoWidth = requestData->logoCharacterWidth + instance.config.logo.paddingLeft + instance.config.logo.paddingRight;
|
||||
instance.state.logoHeight = requestData->logoCharacterHeight + instance.config.logo.paddingTop;
|
||||
instance.state.logoWidth = requestData->logoCharacterWidth + options->paddingLeft + options->paddingRight;
|
||||
instance.state.logoHeight = requestData->logoCharacterHeight + options->paddingTop;
|
||||
|
||||
//Go to upper left corner
|
||||
printf("\e[1G\e[%uA", instance.state.logoHeight);
|
||||
if (options->position != FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
//Go to upper left corner
|
||||
printf("\e[1G\e[%uA", instance.state.logoHeight);
|
||||
}
|
||||
|
||||
if (options->position != FF_LOGO_POSITION_LEFT)
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+70
-36
@@ -53,54 +53,54 @@ static void ffLogoPrintCharsRaw(const char* data, size_t length)
|
||||
}
|
||||
}
|
||||
|
||||
void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
// If result is NULL, calculate logo width
|
||||
// Returns logo height
|
||||
static uint32_t logoAppendChars(const char* data, bool doColorReplacement, FFstrbuf* result)
|
||||
{
|
||||
FFOptionsLogo* options = &instance.config.logo;
|
||||
|
||||
uint32_t currentlineLength = 0;
|
||||
uint32_t logoHeight = 0;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(2048);
|
||||
|
||||
if (!instance.config.display.pipe && instance.config.display.brightColor)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_BOLT);
|
||||
|
||||
ffStrbufAppendNC(&result, options->paddingTop, '\n');
|
||||
ffStrbufAppendNC(&result, options->paddingLeft, ' ');
|
||||
|
||||
instance.state.logoHeight = options->paddingTop;
|
||||
|
||||
//Use logoColor[0] as the default color
|
||||
if(doColorReplacement && !instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[%sm", options->colors[0].chars);
|
||||
if (result)
|
||||
{
|
||||
if (options->position != FF_LOGO_POSITION_RIGHT)
|
||||
ffStrbufAppendNC(result, options->paddingLeft, ' ');
|
||||
else
|
||||
ffStrbufAppendF(result, "\e[9999999C\e[%dD", options->paddingRight + instance.state.logoWidth);
|
||||
}
|
||||
|
||||
while(*data != '\0')
|
||||
{
|
||||
//We are at the end of a line. Print paddings and update max line length
|
||||
if(*data == '\n' || (*data == '\r' && *(data + 1) == '\n'))
|
||||
{
|
||||
ffStrbufAppendNC(&result, options->paddingRight, ' ');
|
||||
|
||||
//We have \r\n, skip the \r
|
||||
if(*data == '\r')
|
||||
++data;
|
||||
|
||||
ffStrbufAppendC(&result, '\n');
|
||||
if(result) ffStrbufAppendC(result, '\n');
|
||||
++data;
|
||||
|
||||
ffStrbufAppendNC(&result, options->paddingLeft, ' ');
|
||||
if (result)
|
||||
{
|
||||
if (options->position != FF_LOGO_POSITION_RIGHT)
|
||||
ffStrbufAppendNC(result, options->paddingLeft, ' ');
|
||||
else
|
||||
ffStrbufAppendF(result, "\e[9999999C\e[%dD", options->paddingRight + instance.state.logoWidth);
|
||||
}
|
||||
|
||||
if(currentlineLength > instance.state.logoWidth)
|
||||
instance.state.logoWidth = currentlineLength;
|
||||
|
||||
currentlineLength = 0;
|
||||
++instance.state.logoHeight;
|
||||
++logoHeight;
|
||||
continue;
|
||||
}
|
||||
|
||||
//Always print tabs as 4 spaces, to have consistent spacing
|
||||
if(*data == '\t')
|
||||
{
|
||||
ffStrbufAppendNC(&result, 4, ' ');
|
||||
if(result) ffStrbufAppendNC(result, 4, ' ');
|
||||
++data;
|
||||
continue;
|
||||
}
|
||||
@@ -110,16 +110,20 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
{
|
||||
const char* start = data;
|
||||
|
||||
ffStrbufAppendS(&result, "\e[");
|
||||
if(result) ffStrbufAppendS(result, "\e[");
|
||||
data += 2;
|
||||
|
||||
while(ffCharIsDigit(*data) || *data == ';')
|
||||
ffStrbufAppendC(&result, *data++); // number
|
||||
{
|
||||
if(result) ffStrbufAppendC(result, *data); // number
|
||||
++data;
|
||||
}
|
||||
|
||||
//We have a valid control sequence, print it and continue with next char
|
||||
if(isascii(*data))
|
||||
{
|
||||
ffStrbufAppendC(&result, *data++); // single letter, end of control sequence
|
||||
if(result) ffStrbufAppendC(result, *data); // single letter, end of control sequence
|
||||
++data;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -137,7 +141,7 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
//If we have $$, or $\0, print it as single $
|
||||
if(*data == '$' || *data == '\0')
|
||||
{
|
||||
ffStrbufAppendC(&result, '$');
|
||||
if(result) ffStrbufAppendC(result, '$');
|
||||
++currentlineLength;
|
||||
++data;
|
||||
continue;
|
||||
@@ -146,18 +150,18 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
if(!instance.config.display.pipe)
|
||||
{
|
||||
//Map the number to an array index, so that '1' -> 0, '2' -> 1, etc.
|
||||
int index = ((int) *data) - 49;
|
||||
int index = *data - '1';
|
||||
|
||||
//If the index is valid, print the color. Otherwise continue as normal
|
||||
if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS)
|
||||
{
|
||||
ffStrbufAppendC(&result, '$');
|
||||
if(result) ffStrbufAppendC(result, '$');
|
||||
++currentlineLength;
|
||||
//Don't continue here, we want to print the current char as unicode
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendF(&result, "\e[%sm", options->colors[index].chars);
|
||||
if(result) ffStrbufAppendF(result, "\e[%sm", options->colors[index].chars);
|
||||
++data;
|
||||
continue;
|
||||
}
|
||||
@@ -192,25 +196,55 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
if(*data == '\0')
|
||||
break;
|
||||
|
||||
ffStrbufAppendC(&result, *data++);
|
||||
if(result) ffStrbufAppendC(result, *data);
|
||||
++data;
|
||||
}
|
||||
}
|
||||
//Happens if the last line is the longest
|
||||
if(currentlineLength > instance.state.logoWidth)
|
||||
instance.state.logoWidth = currentlineLength;
|
||||
|
||||
return logoHeight;
|
||||
}
|
||||
|
||||
void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
{
|
||||
FFOptionsLogo* options = &instance.config.logo;
|
||||
|
||||
if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
logoAppendChars(data, doColorReplacement, NULL);
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(2048);
|
||||
|
||||
if (!instance.config.display.pipe && instance.config.display.brightColor)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_BOLT);
|
||||
|
||||
ffStrbufAppendNC(&result, options->paddingTop, '\n');
|
||||
|
||||
//Use logoColor[0] as the default color
|
||||
if(doColorReplacement && !instance.config.display.pipe)
|
||||
ffStrbufAppendF(&result, "\e[%sm", options->colors[0].chars);
|
||||
|
||||
instance.state.logoHeight = options->paddingTop + logoAppendChars(data, doColorReplacement, &result);
|
||||
|
||||
if(!instance.config.display.pipe)
|
||||
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
|
||||
if(!options->separate)
|
||||
if(options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
//Happens if the last line is the longest
|
||||
if(currentlineLength > instance.state.logoWidth)
|
||||
instance.state.logoWidth = currentlineLength;
|
||||
|
||||
instance.state.logoWidth += options->paddingLeft + options->paddingRight;
|
||||
|
||||
//Go to the leftmost position and go up the height
|
||||
ffStrbufAppendF(&result, "\e[1G\e[%uA", instance.state.logoHeight);
|
||||
}
|
||||
else
|
||||
else if(options->position == FF_LOGO_POSITION_RIGHT)
|
||||
{
|
||||
instance.state.logoWidth = 0;
|
||||
|
||||
//Go to the leftmost position and go up the height
|
||||
ffStrbufAppendF(&result, "\e[1G\e[%uA", instance.state.logoHeight);
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
ffStrbufAppendNC(&result, options->paddingRight, '\n');
|
||||
@@ -306,7 +340,7 @@ static const FFlogo* logoGetBuiltinDetected(FFLogoSize size)
|
||||
if(logo != NULL)
|
||||
return logo;
|
||||
|
||||
logo = logoGetBuiltin(&instance.state.platform.systemName, size);
|
||||
logo = logoGetBuiltin(&instance.state.platform.sysinfo.name, size);
|
||||
if(logo != NULL)
|
||||
return logo;
|
||||
|
||||
|
||||
@@ -94,8 +94,8 @@ void ffPrintBattery(FFBatteryOptions* options)
|
||||
|
||||
for(uint32_t i = 0; i < results.length; i++)
|
||||
{
|
||||
FFBatteryResult* result = ffListGet(&results, i);
|
||||
printBattery(options, result, (uint8_t) i);
|
||||
FFBatteryResult* result = FF_LIST_GET(FFBatteryResult, results, i);
|
||||
printBattery(options, result, results.length == 1 ? 0 : (uint8_t) (i + 1));
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFBatteryResult, result, results)
|
||||
|
||||
@@ -50,7 +50,7 @@ void ffPrintBios(FFBiosOptions* options)
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
|
||||
ffStrbufWriteTo(&bios.version, stdout);
|
||||
if (bios.release.length)
|
||||
printf(" (%s)\n", bios.release.chars);
|
||||
@@ -59,7 +59,7 @@ void ffPrintBios(FFBiosOptions* options)
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BIOS_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BIOS_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &bios.date, "date"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &bios.release, "release"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &bios.vendor, "vendor"},
|
||||
|
||||
@@ -12,15 +12,19 @@ static void printCPUCacheNormal(const FFCPUCacheResult* result, FFCPUCacheOption
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||
|
||||
char levelStr[4] = "L";
|
||||
for (uint32_t i = 0; i < sizeof (result->caches) / sizeof (result->caches[0]) && result->caches[i].length > 0; i++)
|
||||
{
|
||||
ffStrbufClear(&key);
|
||||
levelStr[1] = (char) ('1' + i);
|
||||
if (options->moduleArgs.key.length == 0)
|
||||
ffStrbufAppendF(&key, "%s (L%u)", FF_CPUCACHE_DISPLAY_NAME, i + 1);
|
||||
ffStrbufAppendF(&key, "%s (%s)", FF_CPUCACHE_DISPLAY_NAME, levelStr);
|
||||
else
|
||||
{
|
||||
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 1, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &i, "index"},
|
||||
uint32_t index = i + 1;
|
||||
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 2, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &index, "index"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, levelStr, "level"},
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -49,14 +53,14 @@ static void printCPUCacheNormal(const FFCPUCacheResult* result, FFCPUCacheOption
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
|
||||
ffStrbufPutTo(&buffer, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer2 = ffStrbufCreate();
|
||||
ffParseSize(sum, &buffer2);
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPUCACHE_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_CPUCACHE_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer, "result"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer2, "sum"},
|
||||
}));
|
||||
|
||||
@@ -37,7 +37,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
|
||||
|
||||
if(error)
|
||||
{
|
||||
ffPrintError(FF_DISKIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
|
||||
ffPrintError(FF_DISKIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
|
||||
|
||||
ffParseSize(dev->bytesRead, &buffer);
|
||||
if (!options->detectTotal) ffStrbufAppendS(&buffer, "/s");
|
||||
|
||||
+21
-8
@@ -75,6 +75,15 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
|
||||
ffTempsAppendNum(gpu->temperature, &tempStr, options->tempConfig, &options->moduleArgs);
|
||||
FF_STRBUF_AUTO_DESTROY dTotal = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY dUsed = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY sTotal = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY sUsed = ffStrbufCreate();
|
||||
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET) ffParseSize(gpu->dedicated.total, &dTotal);
|
||||
if (gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET) ffParseSize(gpu->dedicated.used, &dUsed);
|
||||
if (gpu->shared.total != FF_GPU_VMEM_SIZE_UNSET) ffParseSize(gpu->shared.total, &sTotal);
|
||||
if (gpu->shared.used != FF_GPU_VMEM_SIZE_UNSET) ffParseSize(gpu->shared.used, &sUsed);
|
||||
|
||||
FF_PRINT_FORMAT_CHECKED(FF_GPU_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_GPU_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor, "vendor"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name, "name"},
|
||||
@@ -82,10 +91,10 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr, "temperature"},
|
||||
{FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount, "core-count"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, type, "type"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &gpu->dedicated.total, "dedicated-total"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &gpu->dedicated.used, "dedicated-used"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &gpu->shared.total, "shared-total"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &gpu->shared.used, "shared-used"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dTotal, "dedicated-total"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dUsed, "dedicated-used"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &sTotal, "shared-total"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &sUsed, "shared-used"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &gpu->platformApi, "platform-api"},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->frequency, "frequency"},
|
||||
}));
|
||||
@@ -150,6 +159,7 @@ bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char
|
||||
{ "auto", FF_GPU_DETECTION_METHOD_AUTO },
|
||||
{ "pci", FF_GPU_DETECTION_METHOD_PCI },
|
||||
{ "vulkan", FF_GPU_DETECTION_METHOD_VULKAN },
|
||||
{ "opencl", FF_GPU_DETECTION_METHOD_OPENCL },
|
||||
{ "opengl", FF_GPU_DETECTION_METHOD_OPENGL },
|
||||
{},
|
||||
});
|
||||
@@ -204,6 +214,7 @@ void ffParseGPUJsonObject(FFGPUOptions* options, yyjson_val* module)
|
||||
{ "auto", FF_GPU_DETECTION_METHOD_AUTO },
|
||||
{ "pci", FF_GPU_DETECTION_METHOD_PCI },
|
||||
{ "vulkan", FF_GPU_DETECTION_METHOD_VULKAN },
|
||||
{ "opencl", FF_GPU_DETECTION_METHOD_OPENCL },
|
||||
{ "opengl", FF_GPU_DETECTION_METHOD_OPENGL },
|
||||
{},
|
||||
});
|
||||
@@ -260,6 +271,9 @@ void ffGenerateGPUJsonConfig(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
case FF_GPU_DETECTION_METHOD_VULKAN:
|
||||
yyjson_mut_obj_add_str(doc, module, "detectionMethod", "vulkan");
|
||||
break;
|
||||
case FF_GPU_DETECTION_METHOD_OPENCL:
|
||||
yyjson_mut_obj_add_str(doc, module, "detectionMethod", "opencl");
|
||||
break;
|
||||
case FF_GPU_DETECTION_METHOD_OPENGL:
|
||||
yyjson_mut_obj_add_str(doc, module, "detectionMethod", "opengl");
|
||||
break;
|
||||
@@ -350,10 +364,9 @@ void ffGenerateGPUJsonResult(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "platformApi", &gpu->platformApi);
|
||||
|
||||
if (gpu->frequency == FF_GPU_FREQUENCY_UNSET)
|
||||
yyjson_mut_obj_add_null(doc, obj, "frequency");
|
||||
else
|
||||
yyjson_mut_obj_add_real(doc, obj, "frequency", gpu->frequency);
|
||||
yyjson_mut_obj_add_real(doc, obj, "frequency", gpu->frequency); // NaN will be output as "null"
|
||||
|
||||
yyjson_mut_obj_add_uint(doc, obj, "deviceId", gpu->deviceId);
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFGPUResult, gpu, gpus)
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef enum FFGPUDetectionMethod
|
||||
FF_GPU_DETECTION_METHOD_AUTO,
|
||||
FF_GPU_DETECTION_METHOD_PCI,
|
||||
FF_GPU_DETECTION_METHOD_VULKAN,
|
||||
FF_GPU_DETECTION_METHOD_OPENCL,
|
||||
FF_GPU_DETECTION_METHOD_OPENGL,
|
||||
} FFGPUDetectionMethod;
|
||||
|
||||
|
||||
+22
-15
@@ -3,29 +3,32 @@
|
||||
#include "modules/kernel/kernel.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#define FF_KERNEL_NUM_FORMAT_ARGS 5
|
||||
#define FF_KERNEL_NUM_FORMAT_ARGS 6
|
||||
|
||||
void ffPrintKernel(FFKernelOptions* options)
|
||||
{
|
||||
const FFPlatform* platform = &instance.state.platform;
|
||||
const FFPlatformSysinfo* info = &instance.state.platform.sysinfo;
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
printf("%s %s", platform->systemName.chars, platform->systemRelease.chars);
|
||||
printf("%s %s", info->name.chars, info->release.chars);
|
||||
|
||||
if(platform->systemDisplayVersion.length > 0)
|
||||
printf(" (%s)\n", platform->systemDisplayVersion.chars);
|
||||
if(info->displayVersion.length > 0)
|
||||
printf(" (%s)\n", info->displayVersion.chars);
|
||||
else
|
||||
putchar('\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
|
||||
ffParseSize(info->pageSize, &str);
|
||||
FF_PRINT_FORMAT_CHECKED(FF_KERNEL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_KERNEL_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemName, "sysname"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemRelease, "release"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemVersion, "version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemArchitecture, "arch"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &platform->systemDisplayVersion, "display-version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &info->name, "sysname"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &info->release, "release"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &info->version, "version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &info->architecture, "arch"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &info->displayVersion, "display-version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &str, "page-size"},
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -67,12 +70,15 @@ void ffGenerateKernelJsonConfig(FFKernelOptions* options, yyjson_mut_doc* doc, y
|
||||
|
||||
void ffGenerateKernelJsonResult(FF_MAYBE_UNUSED FFKernelOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
const FFPlatformSysinfo* info = &instance.state.platform.sysinfo;
|
||||
|
||||
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "architecture", &instance.state.platform.systemArchitecture);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &instance.state.platform.systemName);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "release", &instance.state.platform.systemRelease);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "version", &instance.state.platform.systemVersion);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "displayVersion", &instance.state.platform.systemDisplayVersion);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "architecture", &info->architecture);
|
||||
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);
|
||||
}
|
||||
|
||||
void ffPrintKernelHelpFormat(void)
|
||||
@@ -83,6 +89,7 @@ void ffPrintKernelHelpFormat(void)
|
||||
"Version - version",
|
||||
"Architecture - arch",
|
||||
"Display version - display-version",
|
||||
"Page size - page-size",
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ void ffPrintNetIO(FFNetIOOptions* options)
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
|
||||
|
||||
ffParseSize(inf->rxBytes, &buffer);
|
||||
if (!options->detectTotal) ffStrbufAppendS(&buffer, "/s");
|
||||
|
||||
+76
-46
@@ -1,6 +1,7 @@
|
||||
#include "common/printing.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "detection/opencl/opencl.h"
|
||||
#include "detection/gpu/gpu.h"
|
||||
#include "modules/opencl/opencl.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
@@ -8,35 +9,27 @@
|
||||
|
||||
void ffPrintOpenCL(FFOpenCLOptions* options)
|
||||
{
|
||||
FFOpenCLResult opencl;
|
||||
ffStrbufInit(&opencl.version);
|
||||
ffStrbufInit(&opencl.device);
|
||||
ffStrbufInit(&opencl.vendor);
|
||||
FFOpenCLResult* result = ffDetectOpenCL();
|
||||
|
||||
const char* error = ffDetectOpenCL(&opencl);
|
||||
|
||||
if(error != NULL)
|
||||
ffPrintError(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
|
||||
else
|
||||
if(result->error != NULL)
|
||||
{
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffStrbufPutTo(&opencl.version, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_PRINT_FORMAT_CHECKED(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_OPENCL_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &opencl.version, "version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &opencl.device, "device"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &opencl.vendor, "vendor"},
|
||||
}));
|
||||
}
|
||||
ffPrintError(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", result->error);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&opencl.version);
|
||||
ffStrbufDestroy(&opencl.device);
|
||||
ffStrbufDestroy(&opencl.vendor);
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffStrbufPutTo(&result->version, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_PRINT_FORMAT_CHECKED(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_OPENCL_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->version, "version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name, "name"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &result->vendor, "vendor"},
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
bool ffParseOpenCLCommandOptions(FFOpenCLOptions* options, const char* key, const char* value)
|
||||
@@ -76,36 +69,73 @@ void ffGenerateOpenCLJsonConfig(FFOpenCLOptions* options, yyjson_mut_doc* doc, y
|
||||
|
||||
void ffGenerateOpenCLJsonResult(FF_MAYBE_UNUSED FFOpenCLOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
FFOpenCLResult opencl;
|
||||
ffStrbufInit(&opencl.version);
|
||||
ffStrbufInit(&opencl.device);
|
||||
ffStrbufInit(&opencl.vendor);
|
||||
FFOpenCLResult* result = ffDetectOpenCL();
|
||||
|
||||
const char* error = ffDetectOpenCL(&opencl);
|
||||
|
||||
if(error != NULL)
|
||||
if(result->error != NULL)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", error);
|
||||
}
|
||||
else
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "version", &opencl.version);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "device", &opencl.device);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &opencl.vendor);
|
||||
yyjson_mut_obj_add_str(doc, module, "error", result->error);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&opencl.version);
|
||||
ffStrbufDestroy(&opencl.device);
|
||||
ffStrbufDestroy(&opencl.vendor);
|
||||
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->version);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &result->name);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &result->vendor);
|
||||
|
||||
yyjson_mut_val* gpus = yyjson_mut_obj_add_arr(doc, obj, "gpus");
|
||||
FF_LIST_FOR_EACH(FFGPUResult, gpu, result->gpus)
|
||||
{
|
||||
yyjson_mut_val* gpuObj = yyjson_mut_arr_add_obj(doc, gpus);
|
||||
yyjson_mut_obj_add_str(doc, gpuObj, "type", gpu->type == FF_GPU_TYPE_UNKNOWN ? "Unknown" : gpu->type == FF_GPU_TYPE_INTEGRATED ? "Integrated" : "Discrete");
|
||||
yyjson_mut_obj_add_strbuf(doc, gpuObj, "vendor", &gpu->vendor);
|
||||
yyjson_mut_obj_add_strbuf(doc, gpuObj, "name", &gpu->name);
|
||||
yyjson_mut_obj_add_strbuf(doc, gpuObj, "driver", &gpu->driver);
|
||||
yyjson_mut_obj_add_strbuf(doc, gpuObj, "platformApi", &gpu->platformApi);
|
||||
if (gpu->coreCount != FF_GPU_CORE_COUNT_UNSET)
|
||||
yyjson_mut_obj_add_int(doc, gpuObj, "coreCount", gpu->coreCount);
|
||||
else
|
||||
yyjson_mut_obj_add_null(doc, gpuObj, "coreCount");
|
||||
|
||||
yyjson_mut_obj_add_real(doc, gpuObj, "frequency", gpu->frequency);
|
||||
|
||||
yyjson_mut_val* memoryObj = yyjson_mut_obj_add_obj(doc, gpuObj, "memory");
|
||||
|
||||
{
|
||||
yyjson_mut_val* dedicatedMemory = yyjson_mut_obj_add_obj(doc, memoryObj, "dedicated");
|
||||
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
|
||||
yyjson_mut_obj_add_uint(doc, dedicatedMemory, "total", gpu->dedicated.total);
|
||||
else
|
||||
yyjson_mut_obj_add_null(doc, dedicatedMemory, "total");
|
||||
|
||||
if (gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET)
|
||||
yyjson_mut_obj_add_uint(doc, dedicatedMemory, "used", gpu->dedicated.total);
|
||||
else
|
||||
yyjson_mut_obj_add_null(doc, dedicatedMemory, "used");
|
||||
}
|
||||
|
||||
{
|
||||
yyjson_mut_val* sharedMemory = yyjson_mut_obj_add_obj(doc, memoryObj, "shared");
|
||||
if (gpu->shared.total != FF_GPU_VMEM_SIZE_UNSET)
|
||||
yyjson_mut_obj_add_uint(doc, sharedMemory, "total", gpu->shared.total);
|
||||
else
|
||||
yyjson_mut_obj_add_null(doc, sharedMemory, "total");
|
||||
|
||||
if (gpu->shared.used != FF_GPU_VMEM_SIZE_UNSET)
|
||||
yyjson_mut_obj_add_uint(doc, sharedMemory, "used", gpu->shared.used);
|
||||
else
|
||||
yyjson_mut_obj_add_null(doc, sharedMemory, "used");
|
||||
}
|
||||
|
||||
yyjson_mut_obj_add_uint(doc, gpuObj, "deviceId", gpu->deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
void ffPrintOpenCLHelpFormat(void)
|
||||
{
|
||||
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_OPENCL_MODULE_NAME, "{1}", FF_OPENCL_NUM_FORMAT_ARGS, ((const char* []) {
|
||||
"version - version",
|
||||
"device - device",
|
||||
"vendor - vendor"
|
||||
"Platform version - version",
|
||||
"Platform name - name",
|
||||
"Platform vendor - vendor",
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -19,7 +19,7 @@ static void buildOutputDefault(const FFOSResult* os, FFstrbuf* result)
|
||||
else if(os->id.length > 0)
|
||||
ffStrbufAppend(result, &os->id);
|
||||
else
|
||||
ffStrbufAppend(result, &instance.state.platform.systemName);
|
||||
ffStrbufAppend(result, &instance.state.platform.sysinfo.name);
|
||||
|
||||
//Append code name if it is missing
|
||||
if(os->codename.length > 0 && !ffStrbufContainIgnCase(result, &os->codename))
|
||||
@@ -55,10 +55,10 @@ static void buildOutputDefault(const FFOSResult* os, FFstrbuf* result)
|
||||
}
|
||||
|
||||
//Append architecture if it is missing
|
||||
if(!ffStrbufContainIgnCase(result, &instance.state.platform.systemArchitecture))
|
||||
if(!ffStrbufContainIgnCase(result, &instance.state.platform.sysinfo.architecture))
|
||||
{
|
||||
ffStrbufAppendC(result, ' ');
|
||||
ffStrbufAppend(result, &instance.state.platform.systemArchitecture);
|
||||
ffStrbufAppend(result, &instance.state.platform.sysinfo.architecture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,10 +80,10 @@ static void buildOutputNixOS(const FFOSResult* os, FFstrbuf* result)
|
||||
ffStrbufAppendC(result, ')');
|
||||
}
|
||||
|
||||
if(instance.state.platform.systemArchitecture.length > 0)
|
||||
if(instance.state.platform.sysinfo.architecture.length > 0)
|
||||
{
|
||||
ffStrbufAppendC(result, ' ');
|
||||
ffStrbufAppend(result, &instance.state.platform.systemArchitecture);
|
||||
ffStrbufAppend(result, &instance.state.platform.sysinfo.architecture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ void ffPrintOS(FFOSOptions* options)
|
||||
else
|
||||
{
|
||||
FF_PRINT_FORMAT_CHECKED(FF_OS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_OS_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemName, "sysname"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.sysinfo.name, "sysname"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &os->name, "name"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &os->prettyName, "pretty-name"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &os->id, "id"},
|
||||
@@ -123,7 +123,7 @@ void ffPrintOS(FFOSOptions* options)
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &os->versionID, "version-id"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &os->codename, "codename"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &os->buildID, "build-id"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.systemArchitecture, "arch"}
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &instance.state.platform.sysinfo.architecture, "arch"}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,8 +425,8 @@ void ffPrintPackagesHelpFormat(void)
|
||||
"Number of nix-default packages - nix-default",
|
||||
"Number of apk packages - apk",
|
||||
"Number of pkg packages - pkg",
|
||||
"Number of flatpak-system packages - flatpak-system",
|
||||
"Number of flatpak-user packages - flatpak-user",
|
||||
"Number of flatpak-system app packages - flatpak-system",
|
||||
"Number of flatpak-user app packages - flatpak-user",
|
||||
"Number of snap packages - snap",
|
||||
"Number of brew packages - brew",
|
||||
"Number of brew-cask packages - brew-cask",
|
||||
@@ -445,7 +445,7 @@ void ffPrintPackagesHelpFormat(void)
|
||||
"Number of guix-user packages - guix-user",
|
||||
"Number of guix-home packages - guix-home",
|
||||
"Total number of all nix packages - nix-all",
|
||||
"Total number of all flatpak packages - flatpak-all",
|
||||
"Total number of all flatpak app packages - flatpak-all",
|
||||
"Total number of all brew packages - brew-all",
|
||||
"Total number of all guix packages - guix-all",
|
||||
}));
|
||||
|
||||
@@ -70,7 +70,7 @@ void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
|
||||
|
||||
if (physicalType[0] || removableType[0] || readOnlyType[0])
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@ void ffPrintPhysicalMemory(FFPhysicalMemoryOptions* options)
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY prettySize = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||
|
||||
uint32_t i = 0;
|
||||
FF_LIST_FOR_EACH(FFPhysicalMemoryResult, device, result)
|
||||
@@ -32,11 +31,7 @@ void ffPrintPhysicalMemory(FFPhysicalMemoryOptions* options)
|
||||
|
||||
if (options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(
|
||||
FF_PHYSICALMEMORY_DISPLAY_NAME,
|
||||
result.length == 1 ? 0 : (uint8_t) i,
|
||||
&options->moduleArgs,
|
||||
FF_PRINT_TYPE_DEFAULT);
|
||||
ffPrintLogoAndKey(FF_PHYSICALMEMORY_DISPLAY_NAME, result.length == 1 ? 0 : (uint8_t) i, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
|
||||
fputs(prettySize.chars, stdout);
|
||||
fputs(" - ", stdout);
|
||||
@@ -53,7 +48,7 @@ void ffPrintPhysicalMemory(FFPhysicalMemoryOptions* options)
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_PHYSICALMEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
FF_PRINT_FORMAT_CHECKED(FF_PHYSICALMEMORY_DISPLAY_NAME, (uint8_t) i, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_PHYSICALMEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &device->size, "bytes"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &prettySize, "size"},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &device->maxSpeed, "max-speed"},
|
||||
|
||||
@@ -176,7 +176,6 @@ void ffGenerateTitleJsonResult(FF_MAYBE_UNUSED FFTitleOptions* options, yyjson_m
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "homeDir", &instance.state.platform.homeDir);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "exePath", &instance.state.platform.exePath);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "userShell", &instance.state.platform.userShell);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "pageSize", instance.state.platform.pageSize);
|
||||
}
|
||||
|
||||
void ffPrintTitleHelpFormat(void)
|
||||
|
||||
@@ -5,17 +5,16 @@
|
||||
#include "modules/version/version.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#define FF_VERSION_NUM_FORMAT_ARGS 9
|
||||
#define FF_VERSION_NUM_FORMAT_ARGS 10
|
||||
|
||||
void ffPrintVersion(FFVersionOptions* options)
|
||||
{
|
||||
FFVersionResult result;
|
||||
ffDetectVersion(&result);
|
||||
FFVersionResult* result = &ffVersionResult;
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(FF_VERSION_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
printf("%s %s%s%s (%s)\n", result.projectName, result.version, result.versionTweak, result.debugMode ? "-debug" : "", result.architecture);
|
||||
printf("%s %s%s%s (%s)\n", result->projectName, result->version, result->versionTweak, result->debugMode ? "-debug" : "", result->architecture);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -32,14 +31,15 @@ void ffPrintVersion(FFVersionOptions* options)
|
||||
}
|
||||
|
||||
FF_PRINT_FORMAT_CHECKED(FF_VERSION_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_VERSION_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.projectName, "project-name"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.version, "version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.versionTweak, "version-tweak"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.debugMode ? "debug" : "release", "build-type"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.architecture, "arch"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.cmakeBuiltType, "cmake-built-type"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.compileTime, "compile-time"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result.compiler, "compiler"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->projectName, "project-name"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->version, "version"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->versionTweak, "version-tweak"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->debugMode ? "debug" : "release", "build-type"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->sysName, "sysname"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->architecture, "arch"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->cmakeBuiltType, "cmake-built-type"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->compileTime, "compile-time"},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, result->compiler, "compiler"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buf, "libc-used"},
|
||||
}));
|
||||
}
|
||||
@@ -82,18 +82,18 @@ void ffGenerateVersionJsonConfig(FFVersionOptions* options, yyjson_mut_doc* doc,
|
||||
|
||||
void ffGenerateVersionJsonResult(FF_MAYBE_UNUSED FFVersionOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
FFVersionResult result;
|
||||
ffDetectVersion(&result);
|
||||
FFVersionResult* result = &ffVersionResult;
|
||||
|
||||
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
|
||||
yyjson_mut_obj_add_str(doc, obj, "projectName", result.projectName);
|
||||
yyjson_mut_obj_add_str(doc, obj, "architecture", result.architecture);
|
||||
yyjson_mut_obj_add_str(doc, obj, "version", result.version);
|
||||
yyjson_mut_obj_add_str(doc, obj, "versionTweak", result.versionTweak);
|
||||
yyjson_mut_obj_add_str(doc, obj, "cmakeBuiltType", result.cmakeBuiltType);
|
||||
yyjson_mut_obj_add_str(doc, obj, "compileTime", result.compileTime);
|
||||
yyjson_mut_obj_add_str(doc, obj, "compiler", result.compiler);
|
||||
yyjson_mut_obj_add_bool(doc, obj, "debugMode", result.debugMode);
|
||||
yyjson_mut_obj_add_str(doc, obj, "projectName", result->projectName);
|
||||
yyjson_mut_obj_add_str(doc, obj, "sysName", result->sysName);
|
||||
yyjson_mut_obj_add_str(doc, obj, "architecture", result->architecture);
|
||||
yyjson_mut_obj_add_str(doc, obj, "version", result->version);
|
||||
yyjson_mut_obj_add_str(doc, obj, "versionTweak", result->versionTweak);
|
||||
yyjson_mut_obj_add_str(doc, obj, "cmakeBuiltType", result->cmakeBuiltType);
|
||||
yyjson_mut_obj_add_str(doc, obj, "compileTime", result->compileTime);
|
||||
yyjson_mut_obj_add_str(doc, obj, "compiler", result->compiler);
|
||||
yyjson_mut_obj_add_bool(doc, obj, "debugMode", result->debugMode);
|
||||
|
||||
FFLibcResult libcResult;
|
||||
if (ffDetectLibc(&libcResult))
|
||||
@@ -119,6 +119,7 @@ void ffPrintVersionHelpFormat(void)
|
||||
"Version - version",
|
||||
"Version tweak - version-tweak",
|
||||
"Build type (debug or release) - build-type",
|
||||
"System name - sysname",
|
||||
"Architecture - arch",
|
||||
"CMake build type when compiling (Debug, Release, RelWithDebInfo, MinSizeRel) - cmake-built-type",
|
||||
"Date time when compiling - compile-time",
|
||||
|
||||
@@ -110,6 +110,7 @@ void ffGenerateVulkanJsonResult(FF_MAYBE_UNUSED FFVulkanOptions* options, yyjson
|
||||
yyjson_mut_obj_add_strbuf(doc, gpuObj, "name", &vulkanGpu->name);
|
||||
yyjson_mut_obj_add_strbuf(doc, gpuObj, "driver", &vulkanGpu->driver);
|
||||
yyjson_mut_obj_add_strbuf(doc, gpuObj, "platformApi", &vulkanGpu->platformApi);
|
||||
yyjson_mut_obj_add_uint(doc, gpuObj, "deviceId", vulkanGpu->deviceId);
|
||||
|
||||
yyjson_mut_val* memoryObj = yyjson_mut_obj_add_obj(doc, gpuObj, "memory");
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "common/processing.h"
|
||||
#include "options/general.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
@@ -21,6 +22,20 @@ const char* ffOptionsParseGeneralJsonConfig(FFOptionsGeneral* options, yyjson_va
|
||||
options->multithreading = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "processingTimeout"))
|
||||
options->processingTimeout = (int32_t) yyjson_get_int(val);
|
||||
else if (ffStrEqualsIgnCase(key, "preRun"))
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY _ = ffStrbufCreate();
|
||||
const char* error = ffProcessAppendStdOut(&_, (char* const[]) {
|
||||
#ifdef _WIN32
|
||||
"cmd.exe", "/C",
|
||||
#else
|
||||
"/bin/sh", "-c",
|
||||
#endif
|
||||
(char*) yyjson_get_str(val), NULL
|
||||
});
|
||||
if (error)
|
||||
return "Failed to execute preRun command";
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
|
||||
else if (ffStrEqualsIgnCase(key, "escapeBedrock"))
|
||||
|
||||
+35
-6
@@ -17,7 +17,7 @@ void ffOptionsInitLogo(FFOptionsLogo* options)
|
||||
options->printRemaining = true;
|
||||
options->preserveAspectRatio = false;
|
||||
options->recache = false;
|
||||
options->separate = false;
|
||||
options->position = FF_LOGO_POSITION_LEFT;
|
||||
|
||||
options->chafaFgOnly = false;
|
||||
ffStrbufInitStatic(&options->chafaSymbols, "block+border+space-wide-inverted"); // Chafa default
|
||||
@@ -111,7 +111,19 @@ logoType:
|
||||
else if(ffStrEqualsIgnCase(subKey, "recache"))
|
||||
options->recache = ffOptionParseBoolean(value);
|
||||
else if(ffStrEqualsIgnCase(subKey, "separate"))
|
||||
options->separate = ffOptionParseBoolean(value);
|
||||
{
|
||||
fputs("--logo-separate has been renamed to --logo-position\n", stderr);
|
||||
exit(477);
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(subKey, "position"))
|
||||
{
|
||||
options->position = (FFLogoPosition) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "left", FF_LOGO_POSITION_LEFT },
|
||||
{ "right", FF_LOGO_POSITION_RIGHT },
|
||||
{ "top", FF_LOGO_POSITION_TOP },
|
||||
{},
|
||||
});
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -355,9 +367,20 @@ const char* ffOptionsParseLogoJsonConfig(FFOptionsLogo* options, yyjson_val* roo
|
||||
options->recache = yyjson_get_bool(val);
|
||||
continue;
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "separate"))
|
||||
else if(ffStrEqualsIgnCase(key, "separate"))
|
||||
return "logo.separate has been renamed to logo.position\n";
|
||||
else if (ffStrEqualsIgnCase(key, "position"))
|
||||
{
|
||||
options->separate = yyjson_get_bool(val);
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "left", FF_LOGO_POSITION_LEFT },
|
||||
{ "top", FF_LOGO_POSITION_TOP },
|
||||
{ "right", FF_LOGO_POSITION_RIGHT },
|
||||
{},
|
||||
});
|
||||
|
||||
if (error) return error;
|
||||
options->position = (FFLogoPosition) value;
|
||||
continue;
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "chafa"))
|
||||
@@ -528,8 +551,14 @@ void ffOptionsGenerateLogoJsonConfig(FFOptionsLogo* options, yyjson_mut_doc* doc
|
||||
if (options->recache != defaultOptions.recache)
|
||||
yyjson_mut_obj_add_bool(doc, obj, "recache", options->recache);
|
||||
|
||||
if (options->separate != defaultOptions.separate)
|
||||
yyjson_mut_obj_add_bool(doc, obj, "separate", options->separate);
|
||||
if (options->position != defaultOptions.position)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, obj, "position", ((const char* []) {
|
||||
"left",
|
||||
"top",
|
||||
"right",
|
||||
})[options->position]);
|
||||
}
|
||||
|
||||
{
|
||||
yyjson_mut_val* chafa = yyjson_mut_obj(doc);
|
||||
|
||||
+8
-1
@@ -23,10 +23,18 @@ typedef enum FFLogoType
|
||||
FF_LOGO_TYPE_NONE, //--logo none
|
||||
} FFLogoType;
|
||||
|
||||
typedef enum FFLogoPosition
|
||||
{
|
||||
FF_LOGO_POSITION_LEFT,
|
||||
FF_LOGO_POSITION_TOP,
|
||||
FF_LOGO_POSITION_RIGHT,
|
||||
} FFLogoPosition;
|
||||
|
||||
typedef struct FFOptionsLogo
|
||||
{
|
||||
FFstrbuf source;
|
||||
FFLogoType type;
|
||||
FFLogoPosition position;
|
||||
FFstrbuf colors[FASTFETCH_LOGO_MAX_COLORS];
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
@@ -36,7 +44,6 @@ typedef struct FFOptionsLogo
|
||||
bool printRemaining;
|
||||
bool preserveAspectRatio;
|
||||
bool recache;
|
||||
bool separate;
|
||||
|
||||
bool chafaFgOnly;
|
||||
FFstrbuf chafaSymbols;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "FFPlatform_private.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "common/io/io.h"
|
||||
#include "detection/version/version.h"
|
||||
|
||||
void ffPlatformInit(FFPlatform* platform)
|
||||
{
|
||||
@@ -14,30 +15,20 @@ void ffPlatformInit(FFPlatform* platform)
|
||||
ffStrbufInit(&platform->hostName);
|
||||
ffStrbufInit(&platform->userShell);
|
||||
|
||||
ffStrbufInit(&platform->systemName);
|
||||
ffStrbufInit(&platform->systemRelease);
|
||||
ffStrbufInit(&platform->systemVersion);
|
||||
ffStrbufInit(&platform->systemArchitecture);
|
||||
FFPlatformSysinfo* info = &platform->sysinfo;
|
||||
|
||||
ffStrbufInit(&info->name);
|
||||
ffStrbufInit(&info->release);
|
||||
ffStrbufInit(&info->version);
|
||||
ffStrbufInit(&info->architecture);
|
||||
|
||||
ffPlatformInitImpl(platform);
|
||||
|
||||
if(platform->systemName.length == 0)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
ffStrbufAppendS(&platform->systemName, "Linux");
|
||||
#elif defined(__FreeBSD__)
|
||||
ffStrbufAppendS(&platform->systemName, "FreeBSD");
|
||||
#elif defined(__APPLE__)
|
||||
ffStrbufAppendS(&platform->systemName, "Darwin");
|
||||
#elif defined(_WIN32)
|
||||
ffStrbufAppendS(&platform->systemName, "Windows_NT");
|
||||
#else
|
||||
ffStrbufAppendS(&platform->systemName, "Unknown");
|
||||
#endif
|
||||
}
|
||||
if(info->name.length == 0)
|
||||
ffStrbufSetStatic(&info->name, ffVersionResult.sysName);
|
||||
|
||||
if(platform->systemArchitecture.length == 0)
|
||||
ffStrbufAppendS(&platform->systemArchitecture, "Unknown");
|
||||
if(info->architecture.length == 0)
|
||||
ffStrbufSetStatic(&info->architecture, ffVersionResult.architecture);
|
||||
}
|
||||
|
||||
void ffPlatformDestroy(FFPlatform* platform)
|
||||
@@ -58,11 +49,12 @@ void ffPlatformDestroy(FFPlatform* platform)
|
||||
ffStrbufDestroy(&platform->hostName);
|
||||
ffStrbufDestroy(&platform->userShell);
|
||||
|
||||
ffStrbufDestroy(&platform->systemArchitecture);
|
||||
ffStrbufDestroy(&platform->systemName);
|
||||
ffStrbufDestroy(&platform->systemRelease);
|
||||
ffStrbufDestroy(&platform->systemVersion);
|
||||
ffStrbufDestroy(&platform->systemDisplayVersion);
|
||||
FFPlatformSysinfo* info = &platform->sysinfo;
|
||||
ffStrbufDestroy(&info->architecture);
|
||||
ffStrbufDestroy(&info->name);
|
||||
ffStrbufDestroy(&info->release);
|
||||
ffStrbufDestroy(&info->version);
|
||||
ffStrbufDestroy(&info->displayVersion);
|
||||
}
|
||||
|
||||
void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path)
|
||||
|
||||
@@ -3,7 +3,18 @@
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "util/FFlist.h"
|
||||
|
||||
typedef struct FFPlatform {
|
||||
typedef struct FFPlatformSysinfo
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf release;
|
||||
FFstrbuf version;
|
||||
FFstrbuf architecture;
|
||||
FFstrbuf displayVersion;
|
||||
uint32_t pageSize;
|
||||
} FFPlatformSysinfo;
|
||||
|
||||
typedef struct FFPlatform
|
||||
{
|
||||
FFstrbuf homeDir; // Trailing slash included
|
||||
FFstrbuf cacheDir; // Trailing slash included
|
||||
FFlist configDirs; // List of FFstrbuf, trailing slash included
|
||||
@@ -14,13 +25,7 @@ typedef struct FFPlatform {
|
||||
FFstrbuf hostName;
|
||||
FFstrbuf userShell;
|
||||
|
||||
FFstrbuf systemName;
|
||||
FFstrbuf systemRelease;
|
||||
FFstrbuf systemVersion;
|
||||
FFstrbuf systemArchitecture;
|
||||
FFstrbuf systemDisplayVersion;
|
||||
|
||||
uint32_t pageSize;
|
||||
FFPlatformSysinfo sysinfo;
|
||||
} FFPlatform;
|
||||
|
||||
void ffPlatformInit(FFPlatform* platform);
|
||||
|
||||
@@ -169,13 +169,19 @@ static void getUserShell(FFPlatform* platform, const struct passwd* pwd)
|
||||
ffStrbufAppendS(&platform->userShell, shell);
|
||||
}
|
||||
|
||||
static void getPageSize(FFPlatform* platform)
|
||||
static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts)
|
||||
{
|
||||
ffStrbufAppendS(&info->name, uts->sysname);
|
||||
ffStrbufAppendS(&info->release, uts->release);
|
||||
ffStrbufAppendS(&info->version, uts->version);
|
||||
ffStrbufAppendS(&info->architecture, uts->machine);
|
||||
ffStrbufInit(&info->displayVersion);
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
size_t length = sizeof(platform->pageSize);
|
||||
sysctl((int[]){ CTL_HW, HW_PAGESIZE }, 2, &platform->pageSize, &length, NULL, 0);
|
||||
size_t length = sizeof(info->pageSize);
|
||||
sysctl((int[]){ CTL_HW, HW_PAGESIZE }, 2, &info->pageSize, &length, NULL, 0);
|
||||
#else
|
||||
platform->pageSize = (uint32_t) sysconf(_SC_PAGESIZE);
|
||||
info->pageSize = (uint32_t) sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -197,11 +203,5 @@ void ffPlatformInitImpl(FFPlatform* platform)
|
||||
getHostName(platform, &uts);
|
||||
getUserShell(platform, pwd);
|
||||
|
||||
ffStrbufAppendS(&platform->systemName, uts.sysname);
|
||||
ffStrbufAppendS(&platform->systemRelease, uts.release);
|
||||
ffStrbufAppendS(&platform->systemVersion, uts.version);
|
||||
ffStrbufAppendS(&platform->systemArchitecture, uts.machine);
|
||||
ffStrbufInit(&platform->systemDisplayVersion);
|
||||
|
||||
getPageSize(platform);
|
||||
getSysinfo(&platform->sysinfo, &uts);
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ static void getUserShell(FFPlatform* platform)
|
||||
ffStrbufReplaceAllC(&platform->userShell, '\\', '/');
|
||||
}
|
||||
|
||||
static void getSystemReleaseAndVersion(FFPlatform* platform)
|
||||
static void getSystemReleaseAndVersion(FFPlatformSysinfo* info)
|
||||
{
|
||||
RTL_OSVERSIONINFOW osVersion = { .dwOSVersionInfoSize = sizeof(osVersion) };
|
||||
if (!NT_SUCCESS(RtlGetVersion(&osVersion)))
|
||||
@@ -172,39 +172,39 @@ static void getSystemReleaseAndVersion(FFPlatform* platform)
|
||||
uint32_t ubr = 0;
|
||||
ffRegReadUint(hKey, L"UBR", &ubr, NULL);
|
||||
|
||||
ffStrbufAppendF(&platform->systemRelease,
|
||||
ffStrbufAppendF(&info->release,
|
||||
"%u.%u.%u.%u",
|
||||
(unsigned) osVersion.dwMajorVersion,
|
||||
(unsigned) osVersion.dwMinorVersion,
|
||||
(unsigned) osVersion.dwBuildNumber,
|
||||
(unsigned) ubr);
|
||||
|
||||
ffStrbufInit(&platform->systemDisplayVersion);
|
||||
if(!ffRegReadStrbuf(hKey, L"DisplayVersion", &platform->systemDisplayVersion, NULL))
|
||||
ffStrbufInit(&info->displayVersion);
|
||||
if(!ffRegReadStrbuf(hKey, L"DisplayVersion", &info->displayVersion, NULL))
|
||||
{
|
||||
if (osVersion.szCSDVersion[0])
|
||||
ffStrbufSetWS(&platform->systemDisplayVersion, osVersion.szCSDVersion);
|
||||
ffStrbufSetWS(&info->displayVersion, osVersion.szCSDVersion);
|
||||
else
|
||||
ffRegReadStrbuf(hKey, L"ReleaseId", &platform->systemDisplayVersion, NULL); // For old Windows 10
|
||||
ffRegReadStrbuf(hKey, L"ReleaseId", &info->displayVersion, NULL); // For old Windows 10
|
||||
}
|
||||
|
||||
ffRegReadStrbuf(hKey, L"BuildLabEx", &platform->systemVersion, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BuildLabEx", &info->version, NULL);
|
||||
|
||||
switch (osVersion.dwPlatformId)
|
||||
{
|
||||
case VER_PLATFORM_WIN32s:
|
||||
ffStrbufSetStatic(&platform->systemName, "WIN32s");
|
||||
ffStrbufSetStatic(&info->name, "WIN32s");
|
||||
break;
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
ffStrbufSetStatic(&platform->systemName, "WIN32_WINDOWS");
|
||||
ffStrbufSetStatic(&info->name, "WIN32_WINDOWS");
|
||||
break;
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
ffStrbufSetStatic(&platform->systemName, "WIN32_NT");
|
||||
ffStrbufSetStatic(&info->name, "WIN32_NT");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void getSystemArchitectureAndPageSize(FFPlatform* platform)
|
||||
static void getSystemArchitectureAndPageSize(FFPlatformSysinfo* info)
|
||||
{
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetNativeSystemInfo(&sysInfo);
|
||||
@@ -212,52 +212,53 @@ static void getSystemArchitectureAndPageSize(FFPlatform* platform)
|
||||
switch(sysInfo.wProcessorArchitecture)
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "x86_64");
|
||||
ffStrbufSetStatic(&info->architecture, "x86_64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "ia64");
|
||||
ffStrbufSetStatic(&info->architecture, "ia64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
switch (sysInfo.wProcessorLevel)
|
||||
{
|
||||
case 4:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "i486");
|
||||
ffStrbufSetStatic(&info->architecture, "i486");
|
||||
break;
|
||||
case 5:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "i586");
|
||||
ffStrbufSetStatic(&info->architecture, "i586");
|
||||
break;
|
||||
case 6:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "i686");
|
||||
ffStrbufSetStatic(&info->architecture, "i686");
|
||||
break;
|
||||
default:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "i386");
|
||||
ffStrbufSetStatic(&info->architecture, "i386");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ARM64:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "aarch64");
|
||||
ffStrbufSetStatic(&info->architecture, "aarch64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ARM:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "arm");
|
||||
ffStrbufSetStatic(&info->architecture, "arm");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_PPC:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "ppc");
|
||||
ffStrbufSetStatic(&info->architecture, "ppc");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "mips");
|
||||
ffStrbufSetStatic(&info->architecture, "mips");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "alpha");
|
||||
ffStrbufSetStatic(&info->architecture, "alpha");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA64:
|
||||
ffStrbufSetStatic(&platform->systemArchitecture, "alpha64");
|
||||
ffStrbufSetStatic(&info->architecture, "alpha64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_UNKNOWN:
|
||||
default:
|
||||
ffStrbufSetStatic(&info->architecture, "unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
platform->pageSize = sysInfo.dwPageSize;
|
||||
info->pageSize = sysInfo.dwPageSize;
|
||||
}
|
||||
|
||||
void ffPlatformInitImpl(FFPlatform* platform)
|
||||
@@ -272,6 +273,6 @@ void ffPlatformInitImpl(FFPlatform* platform)
|
||||
getHostName(platform);
|
||||
getUserShell(platform);
|
||||
|
||||
getSystemReleaseAndVersion(platform);
|
||||
getSystemArchitectureAndPageSize(platform);
|
||||
getSystemReleaseAndVersion(&platform->sysinfo);
|
||||
getSystemArchitectureAndPageSize(&platform->sysinfo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user