mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
178 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b81223002 | |||
| 488986e42e | |||
| b548c6405b | |||
| 1dd942a7b1 | |||
| 2f6613cb50 | |||
| 145e09d164 | |||
| 01dbd0c266 | |||
| 11f3dc3ea0 | |||
| 87de3f1c4a | |||
| 03511bd014 | |||
| b0ad1294e4 | |||
| fcbeecb0d5 | |||
| b3c501516a | |||
| 9418138892 | |||
| 265254ddf7 | |||
| 946154dbac | |||
| 287ba33d12 | |||
| ca75b6b55b | |||
| 666b596f63 | |||
| 5b68cdc0dd | |||
| 0f47a27d09 | |||
| e6e189497d | |||
| 32d3b265bb | |||
| ca318431f5 | |||
| 8a52836afc | |||
| 9cf95620a9 | |||
| c72c6c4a27 | |||
| e289db184c | |||
| e7c9b80d85 | |||
| b8656d5e12 | |||
| c8486610f6 | |||
| d727f8acde | |||
| 8c64e0c275 | |||
| 40588e1a39 | |||
| 6c024d29ce | |||
| db6ad5a268 | |||
| 5096b4a81d | |||
| 5c64ce3b89 | |||
| 38a6d07c85 | |||
| 4632fe8cd9 | |||
| d8bfebfc0f | |||
| 48300429af | |||
| 218dffadd3 | |||
| f324794f54 | |||
| 6e3a329d3b | |||
| b2da8bac41 | |||
| 100e59fd49 | |||
| 5fdb0719f2 | |||
| d4368f56fd | |||
| 55c939a8ef | |||
| 0be2410925 | |||
| 0f824536f9 | |||
| 51c70bc44a | |||
| 47a0b8969f | |||
| 8df95224ed | |||
| 4481d983a9 | |||
| 24e8158116 | |||
| 5239223ad5 | |||
| 1d9a938ff3 | |||
| cd01d16eb9 | |||
| 8e856c3dd6 | |||
| b6dc436e03 | |||
| 3f80fafc09 | |||
| 8e922abf73 | |||
| 737b36e799 | |||
| f5ac85c4e3 | |||
| 0250d11d97 | |||
| e88472e9f6 | |||
| 2907a26adf | |||
| d337126c80 | |||
| 099fb1a43a | |||
| 6efe186df1 | |||
| f33f172734 | |||
| d6a1caa89f | |||
| ed5d7292ba | |||
| 4b0b6c9000 | |||
| 64d64d5050 | |||
| 1a996c3d67 | |||
| ee7231d87c | |||
| 371b3a2d75 | |||
| 007ded2883 | |||
| c32f2f2f2b | |||
| 98c94b01e5 | |||
| 0dda4efa8d | |||
| 877ed94187 | |||
| 484264027c | |||
| 5498b0b042 | |||
| 8f30d0cdd8 | |||
| 80f18e2473 | |||
| 1700d23c26 | |||
| 195675f078 | |||
| 0115b638de | |||
| 3d0653025e | |||
| 991d02e2c0 | |||
| cbab8d7f70 | |||
| 6e09157235 | |||
| 464a57b319 | |||
| d31d157b00 | |||
| 07231ffbbc | |||
| f9fa482b83 | |||
| 65ed48a1bc | |||
| 3068b5bcb2 | |||
| 9da97f5860 | |||
| fa065c1040 | |||
| 664017ba81 | |||
| 1d6fefd40b | |||
| fea4a9dfd5 | |||
| 183c8d7904 | |||
| e5b110375f | |||
| 6eed53217d | |||
| 254c4e5f50 | |||
| 01a917982c | |||
| a9cb178315 | |||
| ec4bd5d3a2 | |||
| 7f19cb1d21 | |||
| e60537512e | |||
| 431f570f05 | |||
| 482e5a5eff | |||
| c282384dab | |||
| 81bddbf182 | |||
| b8fc471678 | |||
| fd34811c81 | |||
| 67c5a6b7cc | |||
| 6b02e1a0ca | |||
| 92f1604e6a | |||
| f0cee064bd | |||
| 6bd933eba2 | |||
| f3e6d04c8e | |||
| d5846d94ca | |||
| 2a61d29be9 | |||
| 49cdacd5a9 | |||
| ce6d7e386d | |||
| fe1ad0da16 | |||
| 6157de60e6 | |||
| 61e71ed658 | |||
| 381cba2612 | |||
| 34b273186a | |||
| e3acd8c155 | |||
| 55f28ae8ff | |||
| 6f2748e208 | |||
| fb3eb9666e | |||
| 8d663300c7 | |||
| d29d99bd6d | |||
| bbdeb668d6 | |||
| 85578c6807 | |||
| 93871c1e98 | |||
| bcacaa9401 | |||
| d079e25a43 | |||
| b4306b944e | |||
| fd75f0b7e7 | |||
| 87c3459f5d | |||
| 051a043a4b | |||
| 913a3e79d4 | |||
| 59557e06fd | |||
| 6d0d916861 | |||
| a0a1c04011 | |||
| b59227e49f | |||
| c64e2c14c2 | |||
| 8c6cf2ccda | |||
| bd657328d2 | |||
| 45d6f21402 | |||
| 4d569db0fd | |||
| d46f9ab4dc | |||
| 3d4ce07892 | |||
| bb3689b348 | |||
| d5500ad4f7 | |||
| 9e4a55d285 | |||
| 999b9187a0 | |||
| 73095ef9e9 | |||
| f4fc9692eb | |||
| 59ebc745c0 | |||
| 09f3bd5a79 | |||
| 413d126bcc | |||
| 9eeb216b70 | |||
| f362fdb01d | |||
| 155d4e90ae | |||
| df9aec6e86 | |||
| d903ccb6f6 |
+1
-1
@@ -10,7 +10,7 @@ trim_trailing_whitespace = true
|
||||
[*.{md,fflogo}]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{txt,fflogo}]
|
||||
[*.{fflogo}]
|
||||
insert_final_newline = false
|
||||
|
||||
[*.yml]
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
custom: paypal.me/linusdierheimer
|
||||
github: LinusDierheimer
|
||||
|
||||
@@ -10,6 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
outputs:
|
||||
ffversion: ${{ steps.ffversion.outputs.ffversion }}
|
||||
steps:
|
||||
@@ -17,7 +18,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev
|
||||
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libcjson-dev
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
@@ -28,7 +29,7 @@ jobs:
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . -j$(nproc) --target package
|
||||
run: cmake --build . --target package
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -57,12 +58,13 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install required packages
|
||||
run: brew install vulkan-loader
|
||||
run: brew install vulkan-loader molten-vk
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
@@ -73,7 +75,7 @@ jobs:
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . -j$(sysctl -n hw.logicalcpu) --target package
|
||||
run: cmake --build . --target package
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -93,13 +95,42 @@ jobs:
|
||||
name: fastfetch-macos
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
bsd:
|
||||
name: BSD
|
||||
runs-on: macos-12
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: run VM
|
||||
uses: vmactions/freebsd-vm@v0
|
||||
with:
|
||||
prepare: |
|
||||
pkg install -y cmake git pkgconf pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd
|
||||
run: |
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package
|
||||
./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
./flashfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-bsd
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
release:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch'
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- linux
|
||||
- macos
|
||||
- bsd
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
@@ -119,4 +150,4 @@ jobs:
|
||||
tag: ${{ needs.linux.outputs.ffversion }}
|
||||
commit: ${{ github.sha }}
|
||||
artifactErrorsFailBuild: true
|
||||
artifacts: fastfetch-linux/*,fastfetch-macos/*
|
||||
artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/*
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
# 1.7.4
|
||||
|
||||
The last element in the default structure (currently the color blocks) is now printed again (#283)
|
||||
|
||||
# 1.7.3
|
||||
|
||||
A lot of small improvements for MacOS & BSD platforms.
|
||||
|
||||
Features:
|
||||
* BSD is now officially supported (#228)
|
||||
* MacPorts package manager support (@SladeGetz, #234)
|
||||
* Battery support for MacOS (@CarterLi, #235)
|
||||
* Processes, swap & terminal font support for MacOS(@CarterLi, #237)
|
||||
* Song support for MacOS (@CarterLi, #242)
|
||||
* Player support for MacOS (@CarterLi, #245)
|
||||
* WM theme support for MacOS (@CarterLi, #246)
|
||||
* CPU usage support for MacOS (@CarterLi, #247)
|
||||
* Power Adapter module (@CarterLi, #249)
|
||||
* Windows terminal font for WSL (@CarterLi, #254)
|
||||
* Temps & Font support for MacOS (@CarterLi, #258)
|
||||
* Terminal font support for Termux (@CarterLi, #263)
|
||||
* Weather module (@CarterLi, #266)
|
||||
|
||||
Logos
|
||||
* Crystal linux (@AloneER0, #239)
|
||||
* FreeBSD (@draumaz, #244)
|
||||
* New Ubuntu (@AloneER0, #259)
|
||||
|
||||
Bugfixes:
|
||||
* Don't segfault in GPU code on Intel Macs (@CarterLi, #236)
|
||||
* Don't use hardcoded size units in presets (@dr460nf1r3, #255)
|
||||
* Don't crash with some format strings (#252)
|
||||
* --logo-none keeps key color now (#264)
|
||||
|
||||
# 1.7.2
|
||||
|
||||
Fixes the bash completions
|
||||
|
||||
+161
-67
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 1.7.2
|
||||
VERSION 1.7.4
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast system information tool"
|
||||
HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch"
|
||||
@@ -11,11 +11,11 @@ project(fastfetch
|
||||
# Target Platform #
|
||||
###################
|
||||
|
||||
if(APPLE OR ANDROID)
|
||||
set(LINUX FALSE CACHE BOOL "..." FORCE) # Linux true means we have full linux userland, not just the kernel
|
||||
elseif(UNIX)
|
||||
set(LINUX TRUE CACHE BOOL "..." FORCE)
|
||||
else()
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*")
|
||||
set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*")
|
||||
set(BSD TRUE CACHE BOOL "..." FORCE)
|
||||
elseif(NOT APPLE AND NOT ANDROID)
|
||||
message(FATAL_ERROR "Unsupported platform")
|
||||
endif()
|
||||
|
||||
@@ -25,27 +25,29 @@ endif()
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE" OFF)
|
||||
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
|
||||
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
|
||||
@@ -69,14 +71,21 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion")
|
||||
|
||||
# Used for dlopen finding dylibs installed by homebrew
|
||||
# `/opt/homebrew/lib` is not on in dlopen search path by default
|
||||
if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
|
||||
# Used for dlopen finding dylibs installed by homebrew, reversed for future usage
|
||||
# `/opt/homebrew/lib` is not on dlopen search path by default
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-rpath,$ENV{HOMEBREW_PREFIX}/lib")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,$ENV{HOMEBREW_PREFIX}/lib")
|
||||
endif()
|
||||
|
||||
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
|
||||
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG} -rdynamic")
|
||||
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED)
|
||||
if(IPO_SUPPORTED)
|
||||
@@ -113,6 +122,19 @@ if(NOT TARGET_DIR_HOME)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TARGET_DIR_ETC)
|
||||
set(TARGET_DIR_ETC "${TARGET_DIR_ROOT}/etc")
|
||||
endif()
|
||||
|
||||
#https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "${TARGET_DIR_USR}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "${TARGET_DIR_ETC}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
#################
|
||||
# Tweak version #
|
||||
#################
|
||||
@@ -133,9 +155,10 @@ endif()
|
||||
|
||||
function(fastfetch_load_text FILENAME OUTVAR)
|
||||
file(READ "${FILENAME}" TEMP)
|
||||
string(REPLACE "\n" "\\n" TEMP "${TEMP}")
|
||||
string(REPLACE "\"" "\\\"" TEMP "${TEMP}")
|
||||
string(REPLACE "$\\" "" TEMP "${TEMP}")
|
||||
string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline
|
||||
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
|
||||
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
|
||||
string(REPLACE "$\\" "" TEMP "${TEMP}") # Remove $\, so we can unescape some things
|
||||
set("${OUTVAR}" "${TEMP}" PARENT_SCOPE)
|
||||
endfunction(fastfetch_load_text)
|
||||
|
||||
@@ -183,16 +206,17 @@ set(LIBFASTFETCH_SRC
|
||||
src/detection/gtk.c
|
||||
src/detection/terminalShell.c
|
||||
src/detection/vulkan.c
|
||||
src/detection/media.c
|
||||
src/detection/datetime.c
|
||||
src/detection/temps.c
|
||||
src/detection/title.c
|
||||
src/detection/host/host.c
|
||||
src/detection/os/os.c
|
||||
src/detection/cpu/cpu.c
|
||||
src/detection/gpu/gpu.c
|
||||
src/detection/memory/memory.c
|
||||
src/detection/font/font.c
|
||||
src/detection/displayserver/displayserver.c
|
||||
src/detection/terminalfont/terminalfont.c
|
||||
src/detection/media/media.c
|
||||
src/modules/break.c
|
||||
src/modules/custom.c
|
||||
src/modules/title.c
|
||||
@@ -220,10 +244,12 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/memory.c
|
||||
src/modules/disk.c
|
||||
src/modules/battery.c
|
||||
src/modules/poweradapter.c
|
||||
src/modules/locale.c
|
||||
src/modules/vulkan.c
|
||||
src/modules/localip.c
|
||||
src/modules/publicip.c
|
||||
src/modules/weather.c
|
||||
src/modules/player.c
|
||||
src/modules/song.c
|
||||
src/modules/datetime.c
|
||||
@@ -232,38 +258,89 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/colors.c
|
||||
src/modules/opengl.c
|
||||
src/modules/opencl.c
|
||||
src/modules/users.c
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
if(BSD OR APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/host/host_apple.c
|
||||
src/detection/os/os_apple.c
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/gpu/gpu_apple.c
|
||||
src/detection/memory/memory_apple.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/common/sysctl.c
|
||||
)
|
||||
elseif(ANDROID)
|
||||
endif()
|
||||
|
||||
if(LINUX OR ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/host/host_android.c
|
||||
src/detection/os/os_android.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/gpu/gpu_android.c
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/displayserver/displayserver_android.c
|
||||
)
|
||||
else()
|
||||
endif()
|
||||
|
||||
if(LINUX OR ANDROID OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/poweradapter/poweradapter_linux.c
|
||||
src/detection/temps/temps_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LINUX OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/host/host_linux.c
|
||||
src/detection/os/os_linux.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/gpu/gpu_linux.c
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/battery/battery_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/font/font_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpuUsage/cpuUsage_apple.c
|
||||
src/util/apple/cf_helpers.c
|
||||
src/util/apple/osascript.m
|
||||
src/detection/host/host_apple.c
|
||||
src/detection/os/os_apple.m
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/gpu/gpu_apple.c
|
||||
src/detection/battery/battery_apple.c
|
||||
src/detection/poweradapter/poweradapter_apple.c
|
||||
src/detection/memory/memory_apple.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/detection/terminalfont/terminalfont_apple.m
|
||||
src/detection/media/media_apple.m
|
||||
src/detection/disk/disk_apple.m
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/detection/temps/temps_apple.c
|
||||
src/detection/font/font_apple.m
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/memory/memory_bsd.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/host/host_android.c
|
||||
src/detection/os/os_android.c
|
||||
src/detection/gpu/gpu_android.c
|
||||
src/detection/battery/battery_android.c
|
||||
src/detection/displayserver/displayserver_android.c
|
||||
src/detection/terminalfont/terminalfont_android.c
|
||||
src/detection/media/media_android.c
|
||||
src/detection/wmtheme/wmtheme_android.c
|
||||
src/detection/font/font_android.c
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -271,28 +348,40 @@ add_library(libfastfetch OBJECT
|
||||
${LIBFASTFETCH_SRC}
|
||||
)
|
||||
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
||||
|
||||
CHECK_INCLUDE_FILE("sys/sysinfo.h" HAVE_SYSINFO_H)
|
||||
if(HAVE_SYSINFO_H)
|
||||
# needs to be public, because changes fastfech.h ABI
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_SYSINFO_H)
|
||||
endif()
|
||||
|
||||
CHECK_INCLUDE_FILE("utmpx.h" HAVE_UTMPX_H)
|
||||
if(HAVE_UTMPX_H)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX_H)
|
||||
endif()
|
||||
|
||||
function(ff_lib_enable VARNAME)
|
||||
if(NOT ENABLE_${VARNAME})
|
||||
return()
|
||||
endif()
|
||||
|
||||
foreach(LIBNAME ${ARGN})
|
||||
pkg_check_modules(${VARNAME} ${LIBNAME})
|
||||
if(${VARNAME}_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_${VARNAME}=1)
|
||||
target_include_directories(libfastfetch PRIVATE ${${VARNAME}_INCLUDE_DIRS})
|
||||
target_link_directories(libfastfetch PRIVATE ${${VARNAME}_LIBRARY_DIRS})
|
||||
return()
|
||||
pkg_search_module(${VARNAME} ${ARGN})
|
||||
if(NOT ${VARNAME}_FOUND)
|
||||
message(WARNING "Package ${ARGV1} not found, building without support.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_${VARNAME}=1)
|
||||
target_include_directories(libfastfetch PRIVATE ${${VARNAME}_INCLUDE_DIRS})
|
||||
target_link_directories(libfastfetch PRIVATE ${${VARNAME}_LIBRARY_DIRS})
|
||||
|
||||
foreach(FLAG ${${VARNAME}_CFLAGS_OTHER})
|
||||
if(FLAG MATCHES "-D.*")
|
||||
string(SUBSTRING ${FLAG} 2 -1 FLAG)
|
||||
target_compile_definitions(libfastfetch PRIVATE ${FLAG})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
message(WARNING "Package ${ARGV1} not found, building without support.")
|
||||
endfunction()
|
||||
|
||||
ff_lib_enable(LIBPCI libpci)
|
||||
@@ -308,14 +397,16 @@ ff_lib_enable(DBUS dbus-1)
|
||||
ff_lib_enable(XFCONF libxfconf-0)
|
||||
ff_lib_enable(SQLITE3 sqlite3)
|
||||
ff_lib_enable(RPM rpm)
|
||||
ff_lib_enable(IMAGEMAGICK7 MagickCore-7.Q16HDRI MagickCore-7.Q16 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc)
|
||||
ff_lib_enable(IMAGEMAGICK6 MagickCore-6.Q16HDRI MagickCore-6.Q16 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc)
|
||||
ff_lib_enable(IMAGEMAGICK7 MagickCore-7.Q16HDRI MagickCore-7.Q16 MagickCore-7 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.pc)
|
||||
ff_lib_enable(IMAGEMAGICK6 MagickCore-6.Q16HDRI MagickCore-6.Q16 MagickCore-6 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.pc)
|
||||
ff_lib_enable(ZLIB zlib)
|
||||
ff_lib_enable(CHAFA chafa>=1.10)
|
||||
ff_lib_enable(EGL egl)
|
||||
ff_lib_enable(GLX glx)
|
||||
ff_lib_enable(OSMESA osmesa)
|
||||
ff_lib_enable(OPENCL OpenCL)
|
||||
ff_lib_enable(LIBCJSON libcjson)
|
||||
ff_lib_enable(FREETYPE freetype2)
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -324,6 +415,8 @@ if(APPLE)
|
||||
PRIVATE "-framework CoreGraphics"
|
||||
PRIVATE "-framework OpenGL"
|
||||
PRIVATE "-framework OpenCL"
|
||||
PRIVATE "-framework Cocoa"
|
||||
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -367,23 +460,22 @@ if (BUILD_TESTS)
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
add_executable(fastfetch-test-list
|
||||
tests/list.c
|
||||
)
|
||||
target_link_libraries(fastfetch-test-list
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
|
||||
add_test(NAME test-list COMMAND fastfetch-test-list)
|
||||
endif()
|
||||
|
||||
##################
|
||||
# install target #
|
||||
##################
|
||||
|
||||
#https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "${TARGET_DIR_USR}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "${TARGET_DIR_ROOT}/etc" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
@@ -431,6 +523,8 @@ elseif(APPLE)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};DragNDrop")
|
||||
|
||||
set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK TRUE)
|
||||
elseif(BSD)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};FreeBSD")
|
||||
endif()
|
||||
|
||||
set(CPACK_SET_DESTDIR ON)
|
||||
|
||||
@@ -11,8 +11,6 @@ Here i just add things that are easy to forget.
|
||||
- `libffdetect`: contains all the detection stuff. To be used by anything that needs system information
|
||||
- `libffprint`: contains the printing functions, logos, format etc
|
||||
- `fastfetch` and `flashfetch`: Executables, that initialize the config of libffprint. Fist one at runtime, second one at compile time
|
||||
- [ ] Better OS output for all possible combinations of /etc/os-release variables.
|
||||
- [ ] Find wayland compositor by looking at \${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY:-wayland-0}
|
||||
- [ ] Make LocalIP module more configurable
|
||||
- [ ] Automatic migrate old config files to newer versions
|
||||
- [ ] ZSH completions
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# <center> Fastfetch </center>
|
||||
# Fastfetch
|
||||
|
||||
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 in pure c, with performance and customizability in mind. Currently Linux, Android and MacOS are supported.
|
||||
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 in pure c, with performance and customizability in mind. Currently Linux, Android, BSD and MacOS 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" />
|
||||
@@ -42,35 +42,37 @@ The following libraries are used if present at runtime:
|
||||
[`libOSMesa`](https://docs.mesa3d.org/osmesa.html): At least one of them is needed by the OpenGL module for gl context creation.
|
||||
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module
|
||||
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
|
||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for rpm package count.
|
||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count.
|
||||
* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE.
|
||||
* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( WSL ).
|
||||
* [`freetype`](https://www.freetype.org/): Needed for Termux font detection ( Android ).
|
||||
|
||||
## Support status
|
||||
All categories not listed here should work without needing a specific implementation.
|
||||
|
||||
##### Available Modules
|
||||
```
|
||||
Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom
|
||||
Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom
|
||||
```
|
||||
|
||||
##### Logos
|
||||
```
|
||||
AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Debian, Devuan, Deepin, Endeavour, Fedora, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Zorin
|
||||
AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Zorin
|
||||
```
|
||||
* Most of the logos have a small variant. Access it by appending _small to the logo name.
|
||||
* Some logos have an old variant. Access it by appending _old to the logo name.
|
||||
* Unknown/unsupported logos will be replaced with a generic linux logo when running fastfetch.
|
||||
* To disable the logo, use `--logo none`.
|
||||
* Get a list of all available logos with `fastfetch --print-logos`.
|
||||
* Printing images as logo is supported using Sixel or Kitty graphics protocol.
|
||||
* Printing images as logo is supported using Sixel / Kitty graphics protocol or chafas image to text conversion.
|
||||
|
||||
##### Package managers
|
||||
```
|
||||
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, brew
|
||||
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts
|
||||
```
|
||||
|
||||
##### WM themes
|
||||
```
|
||||
KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE)
|
||||
KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS)
|
||||
```
|
||||
|
||||
##### DE versions
|
||||
@@ -80,7 +82,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt
|
||||
|
||||
##### Terminal fonts
|
||||
```
|
||||
konsole, gnome-terminal-server, tilix, xfce4-terminal, alacritty, lxterminal, TTY
|
||||
Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, TTY, Windows Terminal, Termux
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
@@ -30,6 +30,7 @@ __fastfetch_complete_help()
|
||||
"swap-format"
|
||||
"disk-format"
|
||||
"battery-format"
|
||||
"poweradapter-format"
|
||||
"locale-format"
|
||||
"local-ip-format"
|
||||
"public-ip-format"
|
||||
@@ -176,9 +177,13 @@ __fastfetch_completion()
|
||||
"--allow-slow-operations"
|
||||
"--disable-linewrap"
|
||||
"--hide-cursor"
|
||||
"--cpu-temp"
|
||||
"--gpu-temp"
|
||||
"--battery-temp"
|
||||
"--localip-show-ipv4"
|
||||
"--localip-show-ipv6"
|
||||
"--localip-show-loop"
|
||||
"--localip-name-prefix"
|
||||
"--escape-bedrock"
|
||||
"--pipe"
|
||||
"--title-fqdn"
|
||||
@@ -211,7 +216,10 @@ __fastfetch_completion()
|
||||
"--set"
|
||||
"--set-keyless"
|
||||
"--player-name"
|
||||
"--public-ip-url"
|
||||
"--public-ip-timeout"
|
||||
"--weather-output-format"
|
||||
"--weather-timeout"
|
||||
"--os-key"
|
||||
"--os-format"
|
||||
"--os-error"
|
||||
@@ -284,6 +292,9 @@ __fastfetch_completion()
|
||||
"--battery-key"
|
||||
"--battery-format"
|
||||
"--battery-error"
|
||||
"--poweradapter-key"
|
||||
"--poweradapter-format"
|
||||
"--poweradapter-error"
|
||||
"--locale-key"
|
||||
"--locale-format"
|
||||
"--locale-error"
|
||||
@@ -293,6 +304,9 @@ __fastfetch_completion()
|
||||
"--public-ip-key"
|
||||
"--public-ip-format"
|
||||
"--public-ip-error"
|
||||
"--weather-key"
|
||||
"--weather-format"
|
||||
"--weather-error"
|
||||
"--player-key"
|
||||
"--player-format"
|
||||
"--player-error"
|
||||
@@ -317,6 +331,9 @@ __fastfetch_completion()
|
||||
"--opencl-key"
|
||||
"--opencl-format"
|
||||
"--opencl-error"
|
||||
"--users-key"
|
||||
"--users-format"
|
||||
"--users-error"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_PATH=(
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Break:Colors
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors
|
||||
|
||||
@@ -8,5 +8,4 @@
|
||||
--icons-key I
|
||||
--icons-format {5}
|
||||
--font-key F
|
||||
--font-format {21}
|
||||
--cursor-key C
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
--structure Host:Resolution:CPU:GPU:Memory:Disk:Battery
|
||||
--memory-format "{?2}{2}MiB{?}"
|
||||
--disk-format "{?2}{2}GB{?}"
|
||||
--memory-format "{?2}{2}{?}"
|
||||
--disk-format "{?2}{2}{?}"
|
||||
--battery-format "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@
|
||||
--de-format "{2} {3}"
|
||||
--theme-format "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
|
||||
--terminal-font-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--memory-format "{/1}{-}{/}{/2}{-}{/}{}MiB / {}MiB"
|
||||
--memory-format "{/1}{-}{/}{/2}{-}{/}{} / {}"
|
||||
--gpu-key "GPU"
|
||||
--resolution-key "Resolution"
|
||||
|
||||
+4
-3
@@ -11,16 +11,17 @@
|
||||
--wm-theme-format Name: {}
|
||||
--theme-format Plasma: {}; Plasma colors: {}; Plasma colors pretty: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
|
||||
--icons-format Plasma: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
|
||||
--font-format Plasma raw: {}; Plasma name: {}; Plasma size: {}; Plasma styles: {}; Plasma pretty: {}; GTK2 raw: {}; GTK2 name: {}; GTK2 size: {}; GTK2 styles: {}; GTK2 pretty: {}; GTK3 raw: {}; GTK3 name: {}; GTK3 size: {}; GTK3 styles: {}; GTK3 pretty: {}; GTK4 raw: {}; GTK4 name: {}; GTK4 size: {}; GTK4 styles: {}; GTK4 pretty: {}; GTK: {}
|
||||
--font-format Font1: {}; Font2: {}; Font3: {}; Font4: {}
|
||||
--cursor-format Theme: {}; Size: {}
|
||||
--terminal-format Process: {}; Path: {}; Exe: {}
|
||||
--terminal-font-format Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}
|
||||
--terminal-font-format Pretty: {}; Name: {}; Size: {}; Styles: {}
|
||||
--cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {}
|
||||
--cpu-usage-format Percentage: {}
|
||||
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}
|
||||
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}
|
||||
--memory-format Used: {}; Total: {}; Percentage: {}
|
||||
--disk-format Used: {}; Total: {}; Files: {}; Percentage: {}
|
||||
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
|
||||
--poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {}
|
||||
--player-format Pretty: {}; Name: {}; Bus: {}; Url: {}
|
||||
--media-format Pretty: {}; Name: {}; Artist: {}; Album: {}
|
||||
--datetime-format year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# make the script exit if any of the commands fail,
|
||||
# making fastfetch not run if the build failed.
|
||||
set -e
|
||||
|
||||
mkdir -p build/
|
||||
cd build/
|
||||
cmake ..
|
||||
cmake --build . --target fastfetch -j$(nproc)
|
||||
|
||||
if [ -z "${CMAKE_BUILD_TYPE}" ]; then
|
||||
CMAKE_BUILD_TYPE=Release
|
||||
fi
|
||||
cmake "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" ..
|
||||
|
||||
if [ -z "$OSTYPE" ] || [ "$OSTYPE" = "linux-gnu" ]; then
|
||||
cmake_build_args="-j$(nproc)"
|
||||
elif [ "$OSTYPE" = "darwin" ]; then
|
||||
cmake_build_args="-j$(sysctl -n hw.ncpu)"
|
||||
else
|
||||
cmake_build_args=""
|
||||
fi
|
||||
cmake --build . --target fastfetch ${cmake_build_args}
|
||||
|
||||
./fastfetch "$@"
|
||||
|
||||
+101
-11
@@ -4,6 +4,7 @@
|
||||
#include "common/printing.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FF_CACHE_VERSION_NAME "cacheversion"
|
||||
#define FF_CACHE_VERSION_EXTENSION "ffv"
|
||||
@@ -11,7 +12,7 @@
|
||||
#define FF_CACHE_VALUE_EXTENSION "ffcv"
|
||||
#define FF_CACHE_SPLIT_EXTENSION "ffcs"
|
||||
|
||||
#define FF_CACHE_EXTENSION_DATA "ffcd"
|
||||
#define FF_CACHE_EXTENSION_V1 "ffc1"
|
||||
|
||||
static void getCacheFilePath(const FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
|
||||
{
|
||||
@@ -211,24 +212,113 @@ void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const
|
||||
ffCacheClose(&cache);
|
||||
}
|
||||
|
||||
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data)
|
||||
typedef struct FFCacheRead
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
|
||||
ffWriteFileData(path.chars, dataSize, data);
|
||||
ffStrbufDestroy(&path);
|
||||
FFstrbuf data;
|
||||
uint32_t position;
|
||||
} FFCacheRead;
|
||||
|
||||
static bool cacheReadStrbuf(FFCacheRead* cacheRead, FFstrbuf* strbuf)
|
||||
{
|
||||
if(cacheRead->position >= cacheRead->data.length)
|
||||
return false;
|
||||
|
||||
ffStrbufAppendS(strbuf, cacheRead->data.chars + cacheRead->position);
|
||||
cacheRead->position += strbuf->length + 1; // skip the null byte too
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data)
|
||||
static bool cacheReadData(FFCacheRead* cacheRead, size_t dataSize, void* data)
|
||||
{
|
||||
if(cacheRead->position + dataSize > cacheRead->data.length)
|
||||
return false;
|
||||
|
||||
memcpy(data, cacheRead->data.chars + cacheRead->position, dataSize);
|
||||
cacheRead->position += (uint32_t) dataSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheResetStrbuf(FFCache* cache, FFstrbuf* strbuf)
|
||||
{
|
||||
FF_UNUSED(cache);
|
||||
ffStrbufClear(strbuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheResetData(FFCache* cacheRead, size_t dataSize, void* data)
|
||||
{
|
||||
FF_UNUSED(cacheRead, dataSize, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
|
||||
{
|
||||
if(instance->config.recache)
|
||||
return false;
|
||||
|
||||
FFCacheRead cache;
|
||||
bool result;
|
||||
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
|
||||
ssize_t result = ffReadFileData(path.chars, dataSize, data);
|
||||
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
|
||||
|
||||
cache.position = 0;
|
||||
|
||||
ffStrbufInitA(&cache.data, 256);
|
||||
result = ffAppendFileBuffer(path.chars, &cache.data);
|
||||
|
||||
if(result)
|
||||
result = callback(obj, &cache, (FFCacheMethodStrbuf) cacheReadStrbuf, (FFCacheMethodData) cacheReadData);
|
||||
|
||||
if(result)
|
||||
result = cache.position == cache.data.length;
|
||||
|
||||
if(!result)
|
||||
callback(obj, NULL, (FFCacheMethodStrbuf) cacheResetStrbuf, (FFCacheMethodData) cacheResetData);
|
||||
|
||||
ffStrbufDestroy(&cache.data);
|
||||
ffStrbufDestroy(&path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct FFCacheWrite
|
||||
{
|
||||
FFstrbuf data;
|
||||
} FFCacheWrite;
|
||||
|
||||
static bool cacheWriteStrbuf(FFCacheWrite* cacheWrite, FFstrbuf* strbuf)
|
||||
{
|
||||
ffStrbufEnsureFree(&cacheWrite->data, strbuf->length);
|
||||
memcpy(cacheWrite->data.chars + cacheWrite->data.length, strbuf->chars, strbuf->length +1); //Copy the nullbyte too
|
||||
cacheWrite->data.length += strbuf->length + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheWriteData(FFCacheWrite* cacheWrite, size_t dataSize, const void* data)
|
||||
{
|
||||
ffStrbufEnsureFree(&cacheWrite->data, (uint32_t) dataSize);
|
||||
memcpy(cacheWrite->data.chars + cacheWrite->data.length, data, dataSize);
|
||||
cacheWrite->data.length += (uint32_t) dataSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
|
||||
{
|
||||
if(!instance->config.cacheSave)
|
||||
return;
|
||||
|
||||
FFCacheWrite cache;
|
||||
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
|
||||
|
||||
ffStrbufInitA(&cache.data, 256);
|
||||
callback(obj, &cache, (FFCacheMethodStrbuf) cacheWriteStrbuf, (FFCacheMethodData) cacheWriteData);
|
||||
ffWriteFileBuffer(path.chars, &cache.data);
|
||||
|
||||
ffStrbufDestroy(&cache.data);
|
||||
ffStrbufDestroy(&path);
|
||||
return result > 0 && (size_t) result == dataSize;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,13 @@ bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModu
|
||||
void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
|
||||
|
||||
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data);
|
||||
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data);
|
||||
typedef void FFCache;
|
||||
|
||||
typedef bool(*FFCacheMethodStrbuf)(FFCache* cache, FFstrbuf* strbuf);
|
||||
typedef bool(*FFCacheMethodData)(FFCache* cache, size_t dataSize, void* data);
|
||||
typedef bool(*FFCacheMethodCallback)(void* data, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod);
|
||||
|
||||
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
|
||||
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -204,6 +204,23 @@ void ffFontInitCopy(FFfont* font, const char* name)
|
||||
ffFontInitValues(font, name, NULL);
|
||||
}
|
||||
|
||||
void ffFontInitWithSpace(FFfont* font, const char* rawName)
|
||||
{
|
||||
const char* pspace = strrchr(rawName, ' ');
|
||||
if(pspace == NULL)
|
||||
{
|
||||
ffFontInitCopy(font, rawName);
|
||||
return;
|
||||
}
|
||||
|
||||
fontInit(font);
|
||||
|
||||
ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
|
||||
ffStrbufAppendS(&font->size, pspace + 1);
|
||||
|
||||
fontInitPretty(font);
|
||||
}
|
||||
|
||||
void ffFontDestroy(FFfont* font)
|
||||
{
|
||||
ffStrbufDestroy(&font->pretty);
|
||||
|
||||
@@ -18,6 +18,7 @@ void ffFontInitQt(FFfont* font, const char* data);
|
||||
void ffFontInitPango(FFfont* font, const char* data);
|
||||
void ffFontInitCopy(FFfont* font, const char* name);
|
||||
void ffFontInitValues(FFfont* font, const char* name, const char* size);
|
||||
void ffFontInitWithSpace(FFfont* font, const char* rawName);
|
||||
void ffFontDestroy(FFfont* font);
|
||||
|
||||
#endif
|
||||
|
||||
+4
-2
@@ -55,10 +55,12 @@ static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start,
|
||||
|
||||
static inline void appendEmptyPlaceholder(FFstrbuf* buffer, const char* placeholder, uint32_t* argCounter, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
if(*argCounter > numArgs)
|
||||
if(*argCounter >= numArgs)
|
||||
ffStrbufAppendS(buffer, placeholder);
|
||||
else
|
||||
ffFormatAppendFormatArg(buffer, &arguments[(*argCounter)++]);
|
||||
ffFormatAppendFormatArg(buffer, arguments + *argCounter);
|
||||
|
||||
(*argCounter)++;
|
||||
}
|
||||
|
||||
static inline bool formatArgSet(const FFformatarg* arg)
|
||||
|
||||
+132
-4
@@ -31,7 +31,10 @@ static void initConfigDirs(FFstate* state)
|
||||
|
||||
#define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \
|
||||
if(ffListFirstIndexComp(&state->configDirs, element, strbufEqualsAdapter) < state->configDirs.length - 1) \
|
||||
--state->configDirs.length;
|
||||
{ \
|
||||
ffStrbufDestroy(ffListGet(&state->configDirs, state->configDirs.length - 1)); \
|
||||
--state->configDirs.length; \
|
||||
}
|
||||
|
||||
FFstrbuf* userConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(userConfigHome, 64);
|
||||
@@ -69,15 +72,16 @@ static void initConfigDirs(FFstate* state)
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
ffStrbufDestroy(&xdgConfigDirs);
|
||||
|
||||
FFstrbuf* systemConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfigHome, 64);
|
||||
ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ROOT"/etc/xdg/");
|
||||
ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ETC"/xdg/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigHome)
|
||||
|
||||
FFstrbuf* systemConfig = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfig, 64);
|
||||
ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ROOT"/etc/");
|
||||
ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ETC"/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfig)
|
||||
|
||||
#undef FF_ENSURE_ONLY_ONCE_IN_LIST
|
||||
@@ -128,7 +132,7 @@ static void initModuleArg(FFModuleArgs* args)
|
||||
|
||||
static void defaultConfig(FFinstance* instance)
|
||||
{
|
||||
ffStrbufInit(&instance->config.logo.source);
|
||||
ffStrbufInitA(&instance->config.logo.source, 0);
|
||||
instance->config.logo.type = FF_LOGO_TYPE_AUTO;
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufInit(&instance->config.logo.colors[i]);
|
||||
@@ -180,9 +184,11 @@ static void defaultConfig(FFinstance* instance)
|
||||
initModuleArg(&instance->config.swap);
|
||||
initModuleArg(&instance->config.disk);
|
||||
initModuleArg(&instance->config.battery);
|
||||
initModuleArg(&instance->config.powerAdapter);
|
||||
initModuleArg(&instance->config.locale);
|
||||
initModuleArg(&instance->config.localIP);
|
||||
initModuleArg(&instance->config.publicIP);
|
||||
initModuleArg(&instance->config.weather);
|
||||
initModuleArg(&instance->config.player);
|
||||
initModuleArg(&instance->config.song);
|
||||
initModuleArg(&instance->config.dateTime);
|
||||
@@ -191,6 +197,7 @@ static void defaultConfig(FFinstance* instance)
|
||||
initModuleArg(&instance->config.vulkan);
|
||||
initModuleArg(&instance->config.openGL);
|
||||
initModuleArg(&instance->config.openCL);
|
||||
initModuleArg(&instance->config.users);
|
||||
|
||||
ffStrbufInitA(&instance->config.libPCI, 0);
|
||||
ffStrbufInitA(&instance->config.libVulkan, 0);
|
||||
@@ -212,10 +219,17 @@ static void defaultConfig(FFinstance* instance)
|
||||
ffStrbufInitA(&instance->config.libGLX, 0);
|
||||
ffStrbufInitA(&instance->config.libOSMesa, 0);
|
||||
ffStrbufInitA(&instance->config.libOpenCL, 0);
|
||||
ffStrbufInitA(&instance->config.libcJSON, 0);
|
||||
ffStrbufInitA(&instance->config.libfreetype, 0);
|
||||
|
||||
instance->config.cpuTemp = false;
|
||||
instance->config.gpuTemp = false;
|
||||
instance->config.batteryTemp = false;
|
||||
|
||||
instance->config.titleFQDN = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.diskFolders, 0);
|
||||
instance->config.diskRemovable = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.batteryDir, 0);
|
||||
|
||||
@@ -224,8 +238,13 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.localIpShowIpV4 = true;
|
||||
instance->config.localIpShowIpV6 = false;
|
||||
instance->config.localIpShowLoop = false;
|
||||
ffStrbufInit(&instance->config.localIpNamePrefix);
|
||||
|
||||
instance->config.publicIpTimeout = 0;
|
||||
ffStrbufInit(&instance->config.publicIpUrl);
|
||||
|
||||
instance->config.weatherTimeout = 0;
|
||||
ffStrbufInitS(&instance->config.weatherOutputFormat, "%t+-+%C+(%l)");
|
||||
|
||||
ffStrbufInitA(&instance->config.osFile, 0);
|
||||
|
||||
@@ -379,6 +398,109 @@ void ffFinish(FFinstance* instance)
|
||||
resetConsole();
|
||||
}
|
||||
|
||||
static void destroyModuleArg(FFModuleArgs* args)
|
||||
{
|
||||
ffStrbufDestroy(&args->key);
|
||||
ffStrbufDestroy(&args->outputFormat);
|
||||
ffStrbufDestroy(&args->errorFormat);
|
||||
}
|
||||
|
||||
static void destroyConfig(FFinstance* instance)
|
||||
{
|
||||
ffStrbufDestroy(&instance->config.logo.source);
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufDestroy(&instance->config.logo.colors[i]);
|
||||
ffStrbufDestroy(&instance->config.colorKeys);
|
||||
ffStrbufDestroy(&instance->config.colorTitle);
|
||||
ffStrbufDestroy(&instance->config.separator);
|
||||
|
||||
destroyModuleArg(&instance->config.os);
|
||||
destroyModuleArg(&instance->config.host);
|
||||
destroyModuleArg(&instance->config.kernel);
|
||||
destroyModuleArg(&instance->config.uptime);
|
||||
destroyModuleArg(&instance->config.processes);
|
||||
destroyModuleArg(&instance->config.packages);
|
||||
destroyModuleArg(&instance->config.shell);
|
||||
destroyModuleArg(&instance->config.resolution);
|
||||
destroyModuleArg(&instance->config.de);
|
||||
destroyModuleArg(&instance->config.wm);
|
||||
destroyModuleArg(&instance->config.wmTheme);
|
||||
destroyModuleArg(&instance->config.theme);
|
||||
destroyModuleArg(&instance->config.icons);
|
||||
destroyModuleArg(&instance->config.font);
|
||||
destroyModuleArg(&instance->config.cursor);
|
||||
destroyModuleArg(&instance->config.terminal);
|
||||
destroyModuleArg(&instance->config.terminalFont);
|
||||
destroyModuleArg(&instance->config.cpu);
|
||||
destroyModuleArg(&instance->config.cpuUsage);
|
||||
destroyModuleArg(&instance->config.gpu);
|
||||
destroyModuleArg(&instance->config.memory);
|
||||
destroyModuleArg(&instance->config.swap);
|
||||
destroyModuleArg(&instance->config.disk);
|
||||
destroyModuleArg(&instance->config.battery);
|
||||
destroyModuleArg(&instance->config.powerAdapter);
|
||||
destroyModuleArg(&instance->config.locale);
|
||||
destroyModuleArg(&instance->config.localIP);
|
||||
destroyModuleArg(&instance->config.publicIP);
|
||||
destroyModuleArg(&instance->config.weather);
|
||||
destroyModuleArg(&instance->config.player);
|
||||
destroyModuleArg(&instance->config.song);
|
||||
destroyModuleArg(&instance->config.dateTime);
|
||||
destroyModuleArg(&instance->config.date);
|
||||
destroyModuleArg(&instance->config.time);
|
||||
destroyModuleArg(&instance->config.vulkan);
|
||||
destroyModuleArg(&instance->config.openGL);
|
||||
destroyModuleArg(&instance->config.openCL);
|
||||
destroyModuleArg(&instance->config.users);
|
||||
|
||||
ffStrbufDestroy(&instance->config.libPCI);
|
||||
ffStrbufDestroy(&instance->config.libVulkan);
|
||||
ffStrbufDestroy(&instance->config.libWayland);
|
||||
ffStrbufDestroy(&instance->config.libXcbRandr);
|
||||
ffStrbufDestroy(&instance->config.libXcb);
|
||||
ffStrbufDestroy(&instance->config.libXrandr);
|
||||
ffStrbufDestroy(&instance->config.libX11);
|
||||
ffStrbufDestroy(&instance->config.libGIO);
|
||||
ffStrbufDestroy(&instance->config.libDConf);
|
||||
ffStrbufDestroy(&instance->config.libDBus);
|
||||
ffStrbufDestroy(&instance->config.libXFConf);
|
||||
ffStrbufDestroy(&instance->config.libSQLite3);
|
||||
ffStrbufDestroy(&instance->config.librpm);
|
||||
ffStrbufDestroy(&instance->config.libImageMagick);
|
||||
ffStrbufDestroy(&instance->config.libZ);
|
||||
ffStrbufDestroy(&instance->config.libChafa);
|
||||
ffStrbufDestroy(&instance->config.libEGL);
|
||||
ffStrbufDestroy(&instance->config.libGLX);
|
||||
ffStrbufDestroy(&instance->config.libOSMesa);
|
||||
ffStrbufDestroy(&instance->config.libOpenCL);
|
||||
ffStrbufDestroy(&instance->config.libcJSON);
|
||||
ffStrbufDestroy(&instance->config.libfreetype);
|
||||
|
||||
ffStrbufDestroy(&instance->config.diskFolders);
|
||||
ffStrbufDestroy(&instance->config.batteryDir);
|
||||
ffStrbufDestroy(&instance->config.separatorString);
|
||||
ffStrbufDestroy(&instance->config.localIpNamePrefix);
|
||||
ffStrbufDestroy(&instance->config.publicIpUrl);
|
||||
ffStrbufDestroy(&instance->config.weatherOutputFormat);
|
||||
ffStrbufDestroy(&instance->config.osFile);
|
||||
ffStrbufDestroy(&instance->config.playerName);
|
||||
}
|
||||
|
||||
static void destroyState(FFinstance* instance)
|
||||
{
|
||||
for(uint32_t i = 0; i < instance->state.configDirs.length; ++i)
|
||||
ffStrbufDestroy((FFstrbuf*)ffListGet(&instance->state.configDirs, i));
|
||||
ffListDestroy(&instance->state.configDirs);
|
||||
|
||||
ffStrbufDestroy(&instance->state.cacheDir);
|
||||
}
|
||||
|
||||
void ffDestroyInstance(FFinstance* instance)
|
||||
{
|
||||
destroyConfig(instance);
|
||||
destroyState(instance);
|
||||
}
|
||||
|
||||
//Must be in a file compiled with the libfastfetch target, because the FF_HAVE* macros are not defined for the executable targets
|
||||
void ffListFeatures()
|
||||
{
|
||||
@@ -446,6 +568,12 @@ void ffListFeatures()
|
||||
#ifdef FF_HAVE_OPENCL
|
||||
"opencl\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_LIBCJSON
|
||||
"libcjson\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_FREETYPE
|
||||
"freetype"
|
||||
#endif
|
||||
""
|
||||
, stdout);
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,6 +19,6 @@ bool ffFileExists(const char* fileName, mode_t mode);
|
||||
// Not thread safe!
|
||||
void ffSuppressIO(bool suppress);
|
||||
|
||||
void ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
FF_C_SCANF(2, 3) void ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
|
||||
#endif
|
||||
|
||||
+17
-4
@@ -3,9 +3,22 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
//Clang doesn't define __SANITIZE_ADDRESS__ but defines __has_feature(address_sanitizer)
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(address_sanitizer)
|
||||
#define __SANITIZE_ADDRESS__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
|
||||
#else
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY
|
||||
#endif
|
||||
|
||||
static void* libraryLoad(const char* path, int maxVersion)
|
||||
{
|
||||
void* result = dlopen(path, RTLD_LAZY);
|
||||
void* result = dlopen(path, FF_DLOPEN_FLAGS);
|
||||
if(result != NULL || maxVersion < 0)
|
||||
return result;
|
||||
|
||||
@@ -19,7 +32,7 @@ static void* libraryLoad(const char* path, int maxVersion)
|
||||
uint32_t originalLength = pathbuf.length;
|
||||
ffStrbufAppendF(&pathbuf, "%i", i);
|
||||
|
||||
result = dlopen(pathbuf.chars, RTLD_LAZY);
|
||||
result = dlopen(pathbuf.chars, FF_DLOPEN_FLAGS);
|
||||
if(result != NULL)
|
||||
break;
|
||||
|
||||
@@ -32,8 +45,8 @@ static void* libraryLoad(const char* path, int maxVersion)
|
||||
|
||||
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...)
|
||||
{
|
||||
if(userProvidedName->length > 0)
|
||||
return dlopen(userProvidedName->chars, RTLD_LAZY);
|
||||
if(userProvidedName != NULL && userProvidedName->length > 0)
|
||||
return dlopen(userProvidedName->chars, FF_DLOPEN_FLAGS);
|
||||
|
||||
va_list defaultNames;
|
||||
va_start(defaultNames, userProvidedName);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
__typeof__(&symbolName) ff ## symbolName;
|
||||
|
||||
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
|
||||
void* libraryObjectName = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL);\
|
||||
void* libraryObjectName = ffLibraryLoad(userLibraryName, __VA_ARGS__, NULL);\
|
||||
if(libraryObjectName == NULL) \
|
||||
return returnValue;
|
||||
|
||||
|
||||
+35
-19
@@ -6,22 +6,23 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, FFstrbuf* buffer)
|
||||
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
|
||||
{
|
||||
struct addrinfo hints = {0};
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return;
|
||||
return -1;
|
||||
|
||||
int sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(sock == -1)
|
||||
int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
@@ -29,14 +30,14 @@ void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, F
|
||||
struct timeval timev;
|
||||
timev.tv_sec = 0;
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
if(connect(sock, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(sock);
|
||||
close(sockfd);
|
||||
freeaddrinfo(addr);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
@@ -47,16 +48,23 @@ void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, F
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n\r\n");
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
if(send(sock, command.chars, command.length, 0) == -1)
|
||||
if(send(sockfd, command.chars, command.length, 0) == -1)
|
||||
{
|
||||
ffStrbufDestroy(&command);
|
||||
close(sock);
|
||||
return;
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
ffStrbufDestroy(&command);
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
ssize_t received = recv(sock, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
@@ -64,6 +72,14 @@ void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, F
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&command);
|
||||
close(sock);
|
||||
close(sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
int sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
|
||||
if(sockfd > 0)
|
||||
return ffNetworkingRecvHttpResponse(sockfd, buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, FFstrbuf* buffer);
|
||||
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
|
||||
bool ffNetworkingRecvHttpResponse(int sock, FFstrbuf* buffer);
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat);
|
||||
void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...);
|
||||
void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
FF_C_PRINTF(6, 7) void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...);
|
||||
FF_C_PRINTF(5, 6) void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
void ffPrintColor(const FFstrbuf* colorValue);
|
||||
void ffPrintCharTimes(char c, uint32_t times);
|
||||
void ffPrintUserString(const char* str);
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
{
|
||||
int pipes[2];
|
||||
|
||||
if(pipe(pipes) == -1)
|
||||
return;
|
||||
return "pipe() failed";
|
||||
|
||||
pid_t childPid = fork();
|
||||
if(childPid == -1)
|
||||
return;
|
||||
return "fork() failed";
|
||||
|
||||
//Child
|
||||
if(childPid == 0)
|
||||
@@ -33,4 +33,6 @@ void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
waitpid(childPid, NULL, 0);
|
||||
ffAppendFDBuffer(pipes[0], buffer);
|
||||
close(pipes[0]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]);
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]);
|
||||
|
||||
#endif
|
||||
|
||||
+10
-45
@@ -89,7 +89,7 @@ typedef struct GSettingsData
|
||||
GVariantGetters variantGetters;
|
||||
} GSettingsData;
|
||||
|
||||
static const GSettingsData* getGSettingsData(FFinstance* instance)
|
||||
static const GSettingsData* getGSettingsData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0.so", 1);
|
||||
|
||||
@@ -114,7 +114,7 @@ static const GSettingsData* getGSettingsData(FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
{
|
||||
const GSettingsData* data = getGSettingsData(instance);
|
||||
if(data == NULL)
|
||||
@@ -143,7 +143,7 @@ FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, c
|
||||
return getGVariantValue(variant, type, &data->variantGetters);
|
||||
}
|
||||
#else //FF_HAVE_GIO
|
||||
FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, schemaName, path, key, type)
|
||||
return FF_VARIANT_NULL;
|
||||
@@ -161,7 +161,7 @@ typedef struct DConfData
|
||||
DConfClient* client;
|
||||
} DConfData;
|
||||
|
||||
static const DConfData* getDConfData(FFinstance* instance)
|
||||
static const DConfData* getDConfData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf.so", 2);
|
||||
|
||||
@@ -181,7 +181,7 @@ static const DConfData* getDConfData(FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type)
|
||||
{
|
||||
const DConfData* data = getDConfData(instance);
|
||||
if(data == NULL)
|
||||
@@ -199,14 +199,14 @@ FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttyp
|
||||
return getGVariantValue(variant, type, &data->variantGetters);
|
||||
}
|
||||
#else //FF_HAVE_DCONF
|
||||
FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, key, type)
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#endif //FF_HAVE_DCONF
|
||||
|
||||
FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
{
|
||||
FFvariant gsettings = ffSettingsGetGSettings(instance, gsettingsSchemaName, gsettingsPath, gsettingsKey, type);
|
||||
|
||||
@@ -231,7 +231,7 @@ typedef struct XFConfData
|
||||
FF_LIBRARY_SYMBOL(xfconf_init)
|
||||
} XFConfData;
|
||||
|
||||
static const XFConfData* getXFConfData(FFinstance* instance)
|
||||
static const XFConfData* getXFConfData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0.so", 4);
|
||||
|
||||
@@ -248,7 +248,7 @@ static const XFConfData* getXFConfData(FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
const XFConfData* data = getXFConfData(instance);
|
||||
if(data == NULL)
|
||||
@@ -271,7 +271,7 @@ FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, con
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#else //FF_HAVE_XFCONF
|
||||
FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, channelName, propertyName, type)
|
||||
return FF_VARIANT_NULL;
|
||||
@@ -358,38 +358,3 @@ void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
|
||||
result->chars[result->length] = '\0';
|
||||
}
|
||||
#endif //__ANDROID__
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
void ffSettingsGetAppleProperty(const char* propName, FFstrbuf* result)
|
||||
{
|
||||
size_t neededLength;
|
||||
if(sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 0)
|
||||
return;
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t) neededLength);
|
||||
|
||||
if(sysctlbyname(propName, result->chars + result->length, &neededLength, NULL, 0) == 0)
|
||||
result->length += (uint32_t) neededLength;
|
||||
|
||||
result->chars[result->length] = '\0';
|
||||
}
|
||||
|
||||
int ffSettingsGetAppleInt(const char* propName, int defaultValue)
|
||||
{
|
||||
int result;
|
||||
size_t neededLength = sizeof(result);
|
||||
if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
|
||||
return defaultValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t ffSettingsGetAppleInt64(const char* propName, int64_t defaultValue)
|
||||
{
|
||||
int64_t result;
|
||||
size_t neededLength = sizeof(result);
|
||||
if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
|
||||
return defaultValue;
|
||||
return result;
|
||||
}
|
||||
#endif //__APPLE__
|
||||
|
||||
+4
-10
@@ -25,10 +25,10 @@ typedef union FFvariant
|
||||
|
||||
#define FF_VARIANT_NULL ((FFvariant){.strValue = NULL})
|
||||
|
||||
FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type);
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type);
|
||||
|
||||
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query);
|
||||
|
||||
@@ -36,10 +36,4 @@ int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, cons
|
||||
void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
void ffSettingsGetAppleProperty(const char* propName, FFstrbuf* result);
|
||||
int ffSettingsGetAppleInt(const char* propName, int defaultValue);
|
||||
int64_t ffSettingsGetAppleInt64(const char* propName, int64_t defaultValue);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "sysctl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void ffSysctlGetString(const char* propName, FFstrbuf* result)
|
||||
{
|
||||
size_t neededLength;
|
||||
if(sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator
|
||||
return;
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
||||
|
||||
if(sysctlbyname(propName, result->chars + result->length, &neededLength, NULL, 0) == 0)
|
||||
result->length += (uint32_t) neededLength - 1;
|
||||
|
||||
result->chars[result->length] = '\0';
|
||||
}
|
||||
|
||||
int ffSysctlGetInt(const char* propName, int defaultValue)
|
||||
{
|
||||
int result;
|
||||
size_t neededLength = sizeof(result);
|
||||
if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
|
||||
return defaultValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue)
|
||||
{
|
||||
int64_t result;
|
||||
size_t neededLength = sizeof(result);
|
||||
if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
|
||||
return defaultValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength)
|
||||
{
|
||||
if(sysctl(request, requestLength, NULL, resultLength, NULL, 0) != 0)
|
||||
return NULL;
|
||||
|
||||
void* data = malloc(*resultLength);
|
||||
if(data == NULL)
|
||||
return NULL;
|
||||
|
||||
if(sysctl(request, requestLength, data, resultLength, NULL, 0) != 0)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_sysctl
|
||||
#define FF_INCLUDED_common_sysctl
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
void ffSysctlGetString(const char* propName, FFstrbuf* result);
|
||||
int ffSysctlGetInt(const char* propName, int defaultValue);
|
||||
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
|
||||
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
|
||||
|
||||
#endif
|
||||
@@ -151,12 +151,30 @@
|
||||
# Default is "-"
|
||||
#--separator-string -
|
||||
|
||||
# Public IP URL option:
|
||||
# Sets the URL of public IP detection server to be used.
|
||||
# Only HTTP protocol is supported, and the value should not contain "http://" prefix.
|
||||
# Default is "ipinfo.io/ip".
|
||||
#--public-ip-url "ipinfo.io/ip"
|
||||
|
||||
# Public IP timeout option:
|
||||
# Sets the time to wait for the public ip server to respond.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (disabled).
|
||||
#--public-ip-timeout 0
|
||||
|
||||
# Weather output format option:
|
||||
# Sets the weather format to be used. It must be URI encoded.
|
||||
# See: https://github.com/chubin/wttr.in#one-line-output
|
||||
# Default is "%t+-+%C+(%l)".
|
||||
#--weather-output-format "%t+-+%C+(%l)"
|
||||
|
||||
# Weather timeout option:
|
||||
# Sets the time to wait for the weather server (wttr.in) to respond.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (disabled).
|
||||
#--weather-timeout 0
|
||||
|
||||
# OS file option
|
||||
# Sets the path to the file containing the operating system information.
|
||||
# Should be a valid path to an existing file.
|
||||
@@ -209,15 +227,18 @@
|
||||
#--swap-key Swap
|
||||
#--disk-key Disk ({1})
|
||||
#--battery-key Battery {1}
|
||||
#--poweradapter-key Power Adapter {1}
|
||||
#--locale-key Locale
|
||||
#--local-ip-key Local IP ({1})
|
||||
#--public-ip-key Public IP
|
||||
#--weather-key Weather
|
||||
#--player-key Media Player
|
||||
#--song-key Song
|
||||
#--datetime-key Date Time
|
||||
#--vulkan-key Vulkan
|
||||
#--opengl-key OpenGL
|
||||
#--opencl-key OpenCL
|
||||
#--users-key Users
|
||||
|
||||
# Format options:
|
||||
# Sets the format string for module values.
|
||||
@@ -248,15 +269,18 @@
|
||||
#--swap-format
|
||||
#--disk-format
|
||||
#--battery-format
|
||||
#--poweradapter-format
|
||||
#--locale-format
|
||||
#--local-ip-format
|
||||
#--public-ip-format
|
||||
#--weather-format
|
||||
#--player-format
|
||||
#--song-format
|
||||
#--datetime-format
|
||||
#--vulkan-format
|
||||
#--opengl-format
|
||||
#--opencl-format
|
||||
#--users-format
|
||||
|
||||
# Error options:
|
||||
# Sets the format string to use if an error occured
|
||||
@@ -287,15 +311,18 @@
|
||||
#--swap-error
|
||||
#--disk-error
|
||||
#--battery-error
|
||||
#--poweradapter-error
|
||||
#--locale-error
|
||||
#--local-ip-error
|
||||
#--public-ip-error
|
||||
#--weather-error
|
||||
#--player-error
|
||||
#--song-error
|
||||
#--datetime-error
|
||||
#--vulkan-error
|
||||
#--opengl-error
|
||||
#--opencl-error
|
||||
#--users-error
|
||||
|
||||
# Library options:
|
||||
# Sets an user specific path to a library to load.
|
||||
@@ -320,3 +347,5 @@
|
||||
#--lib-glx /usr/lib/libGLX.so
|
||||
#--lib-osmesa /usr/lib/libOSMesa.so
|
||||
#--lib-opencl /usr/lib/libOpenCL.so
|
||||
#--lib-cjson /usr/lib/libcjson.so
|
||||
#--lib-freetype /data/data/com.termux/files/usr/lib
|
||||
|
||||
+10
-1
@@ -84,17 +84,26 @@ Library options: Set the path of a library to load
|
||||
--lib-glx <path>
|
||||
--lib-osmesa <path>
|
||||
--lib-opencl <path>
|
||||
--lib-cjson <path>
|
||||
|
||||
Module specific options:
|
||||
--title-fqdn <?value>: sets if the title should use fully qualified domain name. Default is false.
|
||||
--title-fqdn <?value>: Sets if the title should use fully qualified domain name. Default is false.
|
||||
--separator-string <str>: Set the string printed by the separator module
|
||||
--os-file <path>: Set the path to the file containing OS informations
|
||||
--disk-folders <folders>: A colon separated list of folder paths for the disk output. Default is "/:/home"
|
||||
--disk-removable <?value>: Sets if removable volume should be printed. Default is false
|
||||
--battery-dir <folder>: The directory where the battery folders are. Standard: /sys/class/power_supply/
|
||||
--cpu-temp <?value>: Detect and display CPU temperature if supported. Default is false
|
||||
--gpu-temp <?value>: Detect and display GPU temperature if supported. Default is false
|
||||
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
|
||||
--localip-show-ipv4 <?value>: Show ipv4 addresses in local ip module. Default is true
|
||||
--localip-show-ipv6 <?value>: Show ipv6 addresses in local ip module. Default is false
|
||||
--localip-show-loop <?value>: Show loop back addresses (127.0.0.1) in local ip module. Default is false
|
||||
--localip-name-prefix <str>: Show ips with given name prefix only. Default is empty
|
||||
--public-ip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
|
||||
--public-ip-url: The URL of public IP detection server to be used.
|
||||
--weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0)
|
||||
--weather-output-format: The output weather format to be used. It must be URI encoded.
|
||||
--player-name: The name of the player to use
|
||||
--gl <value>: Sets the opengl context creation library to use. Must be auto, egl, glx or osmesa. Default is auto
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ Packages
|
||||
Player
|
||||
Processes
|
||||
PublicIP
|
||||
PowerAdapter
|
||||
Resolution
|
||||
Separator
|
||||
Shell
|
||||
|
||||
@@ -1 +1 @@
|
||||
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Locale:Break:Colors
|
||||
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:PowerAdapter:Locale:Break:Colors
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_battery_battery
|
||||
#define FF_INCLUDED_detection_battery_battery
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_BATTERY_TEMP_UNSET (0/0.0)
|
||||
|
||||
typedef struct BatteryResult
|
||||
{
|
||||
FFstrbuf manufacturer;
|
||||
FFstrbuf modelName;
|
||||
FFstrbuf technology;
|
||||
FFstrbuf capacity;
|
||||
FFstrbuf status;
|
||||
double temperature;
|
||||
} BatteryResult;
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
#include "battery.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) {
|
||||
FF_UNUSED(instance, results)
|
||||
return "Unimplemented";
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "fastfetch.h"
|
||||
#include "battery.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "detection/temps/temps_apple.h"
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
static double detectBatteryTemp()
|
||||
{
|
||||
FFlist temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
ffDetectCoreTemps(FF_TEMP_BATTERY, &temps);
|
||||
|
||||
if(temps.length == 0)
|
||||
return FF_BATTERY_TEMP_UNSET;
|
||||
|
||||
double result = 0;
|
||||
for(uint32_t i = 0; i < temps.length; ++i)
|
||||
{
|
||||
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
|
||||
result += tempValue->value;
|
||||
//TODO: do we really need this?
|
||||
ffStrbufDestroy(&tempValue->name);
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
|
||||
if (matchDict == NULL)
|
||||
return "IOServiceMatching(\"AppleSmartBattery\") failed";
|
||||
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool boolValue;
|
||||
const char* error;
|
||||
|
||||
BatteryResult* battery = ffListAdd(results);
|
||||
ffStrbufInit(&battery->capacity);
|
||||
int currentCapacity, maxCapacity;
|
||||
|
||||
if ((error = ffCfDictGetInt(properties, CFSTR("MaxCapacity"), &maxCapacity)))
|
||||
return error;
|
||||
if (maxCapacity <= 0)
|
||||
return "Querying MaxCapacity failed";
|
||||
|
||||
if ((error = ffCfDictGetInt(properties, CFSTR("CurrentCapacity"), ¤tCapacity)))
|
||||
return error;
|
||||
if(currentCapacity <= 0)
|
||||
return "Querying CurrentCapacity failed";
|
||||
|
||||
ffStrbufAppendF(&battery->capacity, "%.0f", currentCapacity * 100.0 / maxCapacity);
|
||||
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->technology);
|
||||
if (!ffCfDictGetBool(properties, CFSTR("built-in"), &boolValue) && boolValue)
|
||||
{
|
||||
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
|
||||
ffStrbufAppendS(&battery->modelName, "Builtin");
|
||||
ffStrbufAppendS(&battery->technology, "Lithium");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&battery->manufacturer, "Unknown");
|
||||
ffStrbufAppendS(&battery->modelName, "Unknown");
|
||||
ffStrbufAppendS(&battery->technology, "Unknown");
|
||||
}
|
||||
|
||||
ffStrbufInit(&battery->status);
|
||||
if (!ffCfDictGetBool(properties, CFSTR("FullyCharged"), &boolValue) && boolValue)
|
||||
ffStrbufAppendS(&battery->status, "Fully charged");
|
||||
else if (!ffCfDictGetBool(properties, CFSTR("IsCharging"), &boolValue) && boolValue)
|
||||
ffStrbufAppendS(&battery->status, "Charging");
|
||||
else
|
||||
ffStrbufAppendS(&battery->status, "");
|
||||
|
||||
if(instance->config.batteryTemp)
|
||||
battery->temperature = detectBatteryTemp();
|
||||
else
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
}
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
#include "battery.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static void parseBattery(FFstrbuf* dir, FFlist* results)
|
||||
{
|
||||
uint32_t dirLength = dir->length;
|
||||
|
||||
FFstrbuf testBatteryBuffer;
|
||||
ffStrbufInit(&testBatteryBuffer);
|
||||
|
||||
//type must exist and be "Battery"
|
||||
ffStrbufAppendS(dir, "/type");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Battery") != 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
//scope may not exist or must not be "Device"
|
||||
ffStrbufAppendS(dir, "/scope");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Device") == 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
BatteryResult* result = ffListAdd(results);
|
||||
|
||||
//capacity must exist and be not empty
|
||||
ffStrbufInit(&result->capacity);
|
||||
ffStrbufAppendS(dir, "/capacity");
|
||||
ffReadFileBuffer(dir->chars, &result->capacity);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(result->capacity.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&result->capacity);
|
||||
--results->length;
|
||||
return;
|
||||
}
|
||||
|
||||
//At this point, we have a battery. Try to get as much values as possible.
|
||||
|
||||
ffStrbufInit(&result->manufacturer);
|
||||
ffStrbufAppendS(dir, "/manufacturer");
|
||||
ffReadFileBuffer(dir->chars, &result->manufacturer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->modelName);
|
||||
ffStrbufAppendS(dir, "/model_name");
|
||||
ffReadFileBuffer(dir->chars, &result->modelName);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->technology);
|
||||
ffStrbufAppendS(dir, "/technology");
|
||||
ffReadFileBuffer(dir->chars, &result->technology);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->status);
|
||||
ffStrbufAppendS(dir, "/status");
|
||||
ffReadFileBuffer(dir->chars, &result->status);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
result->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
}
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) {
|
||||
FFstrbuf baseDir;
|
||||
ffStrbufInitA(&baseDir, 64);
|
||||
if(instance->config.batteryDir.length > 0)
|
||||
{
|
||||
ffStrbufAppend(&baseDir, &instance->config.batteryDir);
|
||||
ffStrbufEnsureEndsWithC(&baseDir, '/');
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, "/sys/class/power_supply/");
|
||||
}
|
||||
|
||||
uint32_t baseDirLength = baseDir.length;
|
||||
|
||||
DIR* dirp = opendir(baseDir.chars);
|
||||
if(dirp == NULL)
|
||||
{
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return "opendir(batteryDir) == NULL";
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||
parseBattery(&baseDir, results);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
if(results->length == 0) {
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return "batteryDir doesn't contain any battery folder";
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return NULL;
|
||||
}
|
||||
+44
-14
@@ -1,22 +1,52 @@
|
||||
#include "cpu.h"
|
||||
#include "common/caching.h"
|
||||
#include "detection/internal.h"
|
||||
|
||||
void ffDetectCPUImpl(FFCPUResult* cpu);
|
||||
#define FF_CPU_CACHE_NAME "cpu"
|
||||
|
||||
const FFCPUResult* ffDetectCPU()
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached);
|
||||
|
||||
static bool cacheCallback(FFCPUResult* cpu, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod)
|
||||
{
|
||||
return
|
||||
strbufMethod(cache, &cpu->vendor) &&
|
||||
strbufMethod(cache, &cpu->name) &&
|
||||
dataMethod(cache, sizeof(cpu->coresPhysical), &cpu->coresPhysical) &&
|
||||
dataMethod(cache, sizeof(cpu->coresLogical), &cpu->coresLogical) &&
|
||||
dataMethod(cache, sizeof(cpu->coresOnline), &cpu->coresOnline) &&
|
||||
dataMethod(cache, sizeof(cpu->frequencyMin), &cpu->frequencyMin) &&
|
||||
dataMethod(cache, sizeof(cpu->frequencyMax), &cpu->frequencyMax);
|
||||
}
|
||||
|
||||
static void detectCPU(const FFinstance* instance, FFCPUResult* cpu)
|
||||
{
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
|
||||
bool cached = ffCacheRead(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
|
||||
|
||||
ffDetectCPUImpl(instance, cpu, cached);
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
const char* removeStrings[] = {
|
||||
"(R)", "(r)", "(TM)", "(tm)",
|
||||
" CPU", " FPU", " APU", " Processor",
|
||||
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
|
||||
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
|
||||
" with Radeon Graphics"
|
||||
};
|
||||
ffStrbufRemoveStringsA(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
|
||||
ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own
|
||||
ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it
|
||||
|
||||
ffCacheWrite(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
|
||||
}
|
||||
|
||||
const FFCPUResult* ffDetectCPU(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECTION_INTERNAL_GUARD(FFCPUResult,
|
||||
ffDetectCPUImpl(&result);
|
||||
|
||||
const char* removeStrings[] = {
|
||||
"(R)", "(r)", "(TM)", "(tm)",
|
||||
" CPU", " FPU", " APU", " Processor",
|
||||
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
|
||||
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
|
||||
" with Radeon Graphics"
|
||||
};
|
||||
ffStrbufRemoveStringsA(&result.name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
|
||||
ffStrbufSubstrBeforeFirstC(&result.name, '@'); //Cut the speed output in the name as we append our own
|
||||
ffStrbufTrimRight(&result.name, ' '); //If we removed the @ in previous step there was most likely a space before it
|
||||
detectCPU(instance, &result);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,6 @@ typedef struct FFCPUResult
|
||||
double temperature;
|
||||
} FFCPUResult;
|
||||
|
||||
const FFCPUResult* ffDetectCPU();
|
||||
const FFCPUResult* ffDetectCPU(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "cpu.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/sysctl.h"
|
||||
#include "detection/temps/temps_apple.h"
|
||||
|
||||
static double getFrequency(const char* propName)
|
||||
{
|
||||
double herz = (double) ffSettingsGetAppleInt64(propName, 0);
|
||||
double herz = (double) ffSysctlGetInt64(propName, 0);
|
||||
if(herz <= 0.0)
|
||||
return herz;
|
||||
|
||||
@@ -12,31 +13,64 @@ static double getFrequency(const char* propName)
|
||||
return herz / 1000.0; //to GHz
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(FFCPUResult* cpu)
|
||||
static double detectCpuTemp(const FFstrbuf* cpuName)
|
||||
{
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffSettingsGetAppleProperty("machdep.cpu.brand_string", &cpu->name);
|
||||
FFlist temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
ffSettingsGetAppleProperty("machdep.cpu.vendor", &cpu->vendor);
|
||||
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
|
||||
ffDetectCoreTemps(FF_TEMP_CPU_M1X, &temps);
|
||||
else if(ffStrbufStartsWithS(cpuName, "Apple M2"))
|
||||
ffDetectCoreTemps(FF_TEMP_CPU_M2X, &temps);
|
||||
else //TODO: PPC?
|
||||
ffDetectCoreTemps(FF_TEMP_CPU_X64, &temps);
|
||||
|
||||
cpu->coresPhysical = (uint16_t) ffSettingsGetAppleInt("hw.physicalcpu_max", 1);
|
||||
if(cpu->coresPhysical == 1)
|
||||
cpu->coresPhysical = (uint16_t) ffSettingsGetAppleInt("hw.physicalcpu", 1);
|
||||
if(temps.length == 0)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
cpu->coresLogical = (uint16_t) ffSettingsGetAppleInt("hw.logicalcpu_max", 1);
|
||||
if(cpu->coresLogical == 1)
|
||||
cpu->coresLogical = (uint16_t) ffSettingsGetAppleInt("hw.ncpu", 1);
|
||||
|
||||
cpu->coresOnline = (uint16_t) ffSettingsGetAppleInt("hw.logicalcpu", 1);
|
||||
if(cpu->coresOnline == 1)
|
||||
cpu->coresOnline = (uint16_t) ffSettingsGetAppleInt("hw.activecpu", 1);
|
||||
|
||||
cpu->frequencyMin = getFrequency("hw.cpufrequency_min");
|
||||
cpu->frequencyMax = getFrequency("hw.cpufrequency_max");
|
||||
if(cpu->frequencyMax == 0.0)
|
||||
cpu->frequencyMax = getFrequency("hw.cpufrequency");
|
||||
|
||||
//TODO find a way to detect this
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
double result = 0;
|
||||
for(uint32_t i = 0; i < temps.length; ++i)
|
||||
{
|
||||
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
|
||||
result += tempValue->value;
|
||||
//TODO: do we really need this?
|
||||
ffStrbufDestroy(&tempValue->name);
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
if(!cached)
|
||||
{
|
||||
ffSysctlGetString("machdep.cpu.brand_string", &cpu->name);
|
||||
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
|
||||
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1);
|
||||
if(cpu->coresPhysical == 1)
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu", 1);
|
||||
|
||||
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.logicalcpu_max", 1);
|
||||
if(cpu->coresLogical == 1)
|
||||
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
|
||||
|
||||
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.logicalcpu", 1);
|
||||
if(cpu->coresOnline == 1)
|
||||
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.activecpu", 1);
|
||||
|
||||
cpu->frequencyMin = getFrequency("hw.cpufrequency_min");
|
||||
cpu->frequencyMax = getFrequency("hw.cpufrequency_max");
|
||||
if(cpu->frequencyMax == 0.0)
|
||||
cpu->frequencyMax = getFrequency("hw.cpufrequency");
|
||||
}
|
||||
|
||||
if (instance->config.cpuTemp)
|
||||
cpu->temperature = detectCpuTemp(&cpu->name);
|
||||
else
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "cpu.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
ffSysctlGetString("hw.model", &cpu->name);
|
||||
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
|
||||
cpu->coresLogical = cpu->coresPhysical;
|
||||
cpu->coresOnline = cpu->coresPhysical;
|
||||
|
||||
cpu->frequencyMin = ffSysctlGetInt("hw.clockrate", 0) / 1000.0;
|
||||
cpu->frequencyMax = cpu->frequencyMin;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "cpu.h"
|
||||
#include "common/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "detection/temps.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -60,9 +60,9 @@ static double getFrequency(const char* info, const char* scaling)
|
||||
return getGHz(scaling);
|
||||
}
|
||||
|
||||
static double detectCPUTemp()
|
||||
static double detectCPUTemp(const FFinstance* instance)
|
||||
{
|
||||
const FFTempsResult *temps = ffDetectTemps();
|
||||
const FFTempsResult* temps = ffDetectTemps(instance);
|
||||
|
||||
for(uint32_t i = 0; i < temps->values.length; i++)
|
||||
{
|
||||
@@ -78,10 +78,15 @@ static double detectCPUTemp()
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(FFCPUResult* cpu)
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
if(instance->config.cpuTemp)
|
||||
cpu->temperature = detectCPUTemp(instance);
|
||||
else
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
FFstrbuf physicalCoresBuffer;
|
||||
ffStrbufInit(&physicalCoresBuffer);
|
||||
@@ -89,14 +94,18 @@ void ffDetectCPUImpl(FFCPUResult* cpu)
|
||||
parseCpuInfo(cpu, &physicalCoresBuffer);
|
||||
|
||||
cpu->coresPhysical = ffStrbufToUInt16(&physicalCoresBuffer, 1);
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
|
||||
#ifdef FF_HAVE_SYSINFO_H
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
#else
|
||||
cpu->coresLogical = 1;
|
||||
cpu->coresOnline = 1;
|
||||
#endif
|
||||
|
||||
#define BP "/sys/devices/system/cpu/cpufreq/policy0/"
|
||||
cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq");
|
||||
cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq");
|
||||
|
||||
cpu->temperature = detectCPUTemp();
|
||||
|
||||
ffStrbufDestroy(&physicalCoresBuffer);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_cpu_cpuUsage
|
||||
#define FF_INCLUDED_detection_cpu_cpuUsage
|
||||
|
||||
const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#include <mach/processor_info.h>
|
||||
#include <mach/mach_host.h>
|
||||
|
||||
const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll)
|
||||
{
|
||||
natural_t numCPUs = 0U;
|
||||
processor_info_array_t cpuInfo;
|
||||
mach_msg_type_number_t numCpuInfo;
|
||||
*inUseAll = *totalAll = 0;
|
||||
|
||||
if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUs, &cpuInfo, &numCpuInfo) != KERN_SUCCESS)
|
||||
return "host_processor_info() failed";
|
||||
if (numCPUs * CPU_STATE_MAX != numCpuInfo)
|
||||
return "Unexpected host_processor_info() result";
|
||||
|
||||
for (natural_t i = 0U; i < numCPUs; ++i) {
|
||||
integer_t inUse = cpuInfo[CPU_STATE_MAX * i + CPU_STATE_USER]
|
||||
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_SYSTEM]
|
||||
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_NICE];
|
||||
integer_t total = inUse + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_IDLE];
|
||||
*inUseAll += inUse;
|
||||
*totalAll += total;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll)
|
||||
{
|
||||
long user, nice, system, idle, iowait, irq, softirq;
|
||||
|
||||
FILE* procStat = fopen("/proc/stat", "r");
|
||||
if(procStat == NULL)
|
||||
return "fopen(\"""/proc/stat\", \"r\") == NULL";
|
||||
|
||||
if (fscanf(procStat, "cpu%ld%ld%ld%ld%ld%ld%ld", &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0)
|
||||
{
|
||||
fclose(procStat);
|
||||
return "fscanf() failed";
|
||||
}
|
||||
*inUseAll = user + nice + system;
|
||||
*totalAll = *inUseAll + idle + iowait + irq + softirq;
|
||||
|
||||
fclose(procStat);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -27,21 +27,21 @@ const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
|
||||
result.yearShort = (uint8_t) (result.year % 100);
|
||||
result.month = (uint8_t) (tm->tm_mon + 1);
|
||||
|
||||
ffStrbufInit(&result.monthPretty);
|
||||
ffStrbufInitA(&result.monthPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.monthPretty.length = (uint32_t) strftime(result.monthPretty.chars, ffStrbufGetFree(&result.monthPretty), "%m", tm);
|
||||
|
||||
ffStrbufInit(&result.monthName);
|
||||
ffStrbufInitA(&result.monthName, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.monthName.length = (uint32_t) strftime(result.monthName.chars, ffStrbufGetFree(&result.monthName), "%B", tm);
|
||||
|
||||
ffStrbufInit(&result.monthNameShort);
|
||||
ffStrbufInitA(&result.monthNameShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.monthNameShort.length = (uint32_t) strftime(result.monthNameShort.chars, ffStrbufGetFree(&result.monthNameShort), "%b", tm);
|
||||
|
||||
result.week = (uint8_t) (tm->tm_yday / 7 + 1);
|
||||
|
||||
ffStrbufInit(&result.weekday);
|
||||
ffStrbufInitA(&result.weekday, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.weekday.length = (uint32_t) strftime(result.weekday.chars, ffStrbufGetFree(&result.weekday), "%A", tm);
|
||||
|
||||
ffStrbufInit(&result.weekdayShort);
|
||||
ffStrbufInitA(&result.weekdayShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.weekdayShort.length = (uint32_t) strftime(result.weekdayShort.chars, ffStrbufGetFree(&result.weekdayShort), "%a", tm);
|
||||
|
||||
result.dayInYear = (uint8_t) (tm->tm_yday + 1);
|
||||
@@ -50,22 +50,22 @@ const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
|
||||
|
||||
result.hour = (uint8_t) tm->tm_hour;
|
||||
|
||||
ffStrbufInit(&result.hourPretty);
|
||||
ffStrbufInitA(&result.hourPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.hourPretty.length = (uint32_t) strftime(result.hourPretty.chars, ffStrbufGetFree(&result.hourPretty), "%H", tm);
|
||||
|
||||
result.hour12 = (uint8_t) (result.hour % 12);
|
||||
|
||||
ffStrbufInit(&result.hour12Pretty);
|
||||
ffStrbufInitA(&result.hour12Pretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.hour12Pretty.length = (uint32_t) strftime(result.hour12Pretty.chars, ffStrbufGetFree(&result.hour12Pretty), "%I", tm);
|
||||
|
||||
result.minute = (uint8_t) tm->tm_min;
|
||||
|
||||
ffStrbufInit(&result.minutePretty);
|
||||
ffStrbufInitA(&result.minutePretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.minutePretty.length = (uint32_t) strftime(result.minutePretty.chars, ffStrbufGetFree(&result.minutePretty), "%M", tm);
|
||||
|
||||
result.second = (uint8_t) tm->tm_sec;
|
||||
|
||||
ffStrbufInit(&result.secondPretty);
|
||||
ffStrbufInitA(&result.secondPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.secondPretty.length = (uint32_t) strftime(result.secondPretty.chars, ffStrbufGetFree(&result.secondPretty), "%S", tm);
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_disk_disk
|
||||
#define FF_INCLUDED_detection_disk_disk
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "disk.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil];
|
||||
NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys
|
||||
options:NSVolumeEnumerationSkipHiddenVolumes];
|
||||
if(urls == nil)
|
||||
return "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed";
|
||||
|
||||
for (NSURL *url in urls) {
|
||||
NSError *error;
|
||||
NSNumber* removable;
|
||||
if([url getResourceValue:&removable forKey:NSURLVolumeIsRemovableKey error:&error] == NO)
|
||||
continue;
|
||||
if(removable.boolValue && !instance->config.diskRemovable)
|
||||
continue;
|
||||
|
||||
ffStrbufInitS((FFstrbuf *)ffListAdd(folders), [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "disk.h"
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
struct statvfs fsRoot;
|
||||
int rootRet = statvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot);
|
||||
if(rootRet != 0)
|
||||
return "statvfs(\"/\") failed";
|
||||
|
||||
ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_ROOT"/");
|
||||
|
||||
struct statvfs fsHome;
|
||||
int homeRet = statvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome);
|
||||
if(homeRet == 0 && (fsRoot.f_fsid != fsHome.f_fsid))
|
||||
ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_HOME);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
#include "displayserver.h"
|
||||
#include "common/library.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
//Resolution code heavily inspired by displayplacer <3
|
||||
@@ -60,19 +59,10 @@ static void detectWM(FFDisplayServerResult* ds)
|
||||
u_int requestLength = sizeof(request) / sizeof(*request);
|
||||
|
||||
size_t length = 0;
|
||||
if(sysctl(request, requestLength, NULL, &length, NULL, 0) != 0)
|
||||
return;
|
||||
|
||||
struct kinfo_proc* processes = malloc(length);
|
||||
struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length);
|
||||
if(processes == NULL)
|
||||
return;
|
||||
|
||||
if(sysctl(request, requestLength, processes, &length, NULL, 0) != 0)
|
||||
{
|
||||
free(processes);
|
||||
return;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < length / sizeof(struct kinfo_proc); i++)
|
||||
{
|
||||
const char* comm = processes[i].kp_proc.p_comm;
|
||||
|
||||
@@ -34,7 +34,7 @@ static void parseDRM(FFDisplayServerResult* result)
|
||||
resolution->height = 0;
|
||||
resolution->refreshRate = 0;
|
||||
|
||||
int scanned = fscanf(modeFile, "%ix%i", &resolution->width, &resolution->height);
|
||||
int scanned = fscanf(modeFile, "%ux%u", &resolution->width, &resolution->height);
|
||||
if(scanned < 2 || resolution->width == 0 || resolution->height == 0)
|
||||
--result->resolutions.length;
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define _GNU_SOURCE //required for struct ucred
|
||||
|
||||
#include "displayserver_linux.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -17,9 +15,11 @@ typedef struct WaylandData
|
||||
FFlist* results;
|
||||
FF_LIBRARY_SYMBOL(wl_proxy_marshal_constructor_versioned)
|
||||
FF_LIBRARY_SYMBOL(wl_proxy_add_listener)
|
||||
FF_LIBRARY_SYMBOL(wl_proxy_destroy)
|
||||
const struct wl_interface* ffwl_output_interface;
|
||||
} WaylandData;
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
struct ucred ucred;
|
||||
@@ -35,6 +35,12 @@ static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path
|
||||
ffStrbufDestroy(&procPath);
|
||||
}
|
||||
#else
|
||||
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_UNUSED(fd, result);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void stubListener(void* data, ...)
|
||||
{
|
||||
@@ -43,10 +49,10 @@ static void stubListener(void* data, ...)
|
||||
|
||||
static void waylandOutputModeListener(void* data, struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate)
|
||||
{
|
||||
FF_UNUSED(output);
|
||||
|
||||
WaylandData* wldata = data;
|
||||
|
||||
wldata->ffwl_proxy_destroy((struct wl_proxy*) output);
|
||||
|
||||
if(!(flags & WL_OUTPUT_MODE_CURRENT) || width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
@@ -96,7 +102,7 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
|
||||
|
||||
bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(wayland, instance->config.libWayland, false, "libwayland-client.so", 1)
|
||||
FF_LIBRARY_LOAD(wayland, &instance->config.libWayland, false, "libwayland-client.so", 1)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false)
|
||||
@@ -110,6 +116,7 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_proxy_marshal_constructor_versioned, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_proxy_add_listener, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_proxy_destroy, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_output_interface, false)
|
||||
|
||||
struct wl_display* display = ffwl_display_connect(NULL);
|
||||
@@ -140,7 +147,8 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
ffwl_display_dispatch(display);
|
||||
ffwl_display_roundtrip(display);
|
||||
|
||||
ffwl_display_disconnect(display); //This will also destroy our wl_registry and wl_output proxies
|
||||
data.ffwl_proxy_destroy(registry);
|
||||
ffwl_display_disconnect(display);
|
||||
dlclose(wayland);
|
||||
|
||||
//We successfully connected to wayland and detected the resolution.
|
||||
|
||||
@@ -129,6 +129,10 @@ static void getKDE(FFDisplayServerResult* result)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
if(result->deVersion.length == 0)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
if(result->deVersion.length == 0)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/local/share/xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
if(result->deVersion.length == 0)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/local/share/wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
|
||||
applyBetterWM(result, getenv("KDEWM"));
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
|
||||
|
||||
void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xcb, instance->config.libXcb, , "libxcb.so", 2)
|
||||
FF_LIBRARY_LOAD(xcb, &instance->config.libXcb, , "libxcb.so", 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,)
|
||||
@@ -326,7 +326,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
|
||||
void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xcbRandr, instance->config.libXcbRandr, , "libxcb-randr.so", 1)
|
||||
FF_LIBRARY_LOAD(xcbRandr, &instance->config.libXcbRandr, , "libxcb-randr.so", 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,)
|
||||
|
||||
@@ -55,7 +55,7 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl
|
||||
|
||||
void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(x11, instance->config.libX11, , "libX11.so", 7, "libX11-xcb.so", 2)
|
||||
FF_LIBRARY_LOAD(x11, &instance->config.libX11, , "libX11.so", 7, "libX11-xcb.so", 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,)
|
||||
|
||||
@@ -259,7 +259,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
|
||||
void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xrandr, instance->config.libXrandr, , "libXrandr.so", 3)
|
||||
FF_LIBRARY_LOAD(xrandr, &instance->config.libXrandr, , "libXrandr.so", 3)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "font.h"
|
||||
#include "detection/internal.h"
|
||||
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* font);
|
||||
|
||||
static void detectFont(const FFinstance* instance, FFFontResult* font)
|
||||
{
|
||||
ffStrbufInit(&font->error);
|
||||
|
||||
for(uint32_t i = 0; i < FF_DETECT_FONT_NUM_FONTS; ++i)
|
||||
ffStrbufInit(&font->fonts[i]);
|
||||
|
||||
ffDetectFontImpl(instance, font);
|
||||
|
||||
if(font->error.length > 0)
|
||||
return;
|
||||
|
||||
for(uint32_t i = 0; i < FF_DETECT_FONT_NUM_FONTS; ++i)
|
||||
{
|
||||
if(font->fonts[i].length > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&font->error, "No fonts found");
|
||||
}
|
||||
|
||||
const FFFontResult* ffDetectFont(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECTION_INTERNAL_GUARD(FFFontResult,
|
||||
detectFont(instance, &result);
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_font_font
|
||||
#define FF_INCLUDED_detection_font_font
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_DETECT_FONT_NUM_FONTS 4
|
||||
|
||||
typedef struct FFFontResult
|
||||
{
|
||||
FFstrbuf error;
|
||||
|
||||
/**
|
||||
* Linux / BSD: QT, GTK2, GTK3, GTK4
|
||||
* MacOS: System, User, Monospace, Application
|
||||
* Other: Unset, Unset, Unset, Unset
|
||||
*/
|
||||
FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS];
|
||||
} FFFontResult;
|
||||
|
||||
const FFFontResult* ffDetectFont(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "fastfetch.h"
|
||||
#include "font.h"
|
||||
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
ffStrbufAppendS(&result->error, "Not implemented");
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "common/font.h"
|
||||
#include "common/io.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "font.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
static void detectFontForType(CTFontUIFontType uiType, FFstrbuf* font)
|
||||
{
|
||||
CTFontRef ctFont = CTFontCreateUIFontForLanguage(uiType, 12, NULL);
|
||||
ffCfStrGetString(CTFontCopyFamilyName(ctFont), font);
|
||||
}
|
||||
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
ffSuppressIO(true);
|
||||
detectFontForType(kCTFontUIFontSystem, &result->fonts[0]);
|
||||
detectFontForType(kCTFontUIFontUser, &result->fonts[1]);
|
||||
detectFontForType(kCTFontUIFontUserFixedPitch, &result->fonts[2]);
|
||||
detectFontForType(kCTFontUIFontApplication, &result->fonts[3]);
|
||||
ffSuppressIO(false);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "detection/qt.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "common/font.h"
|
||||
#include "font.h"
|
||||
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
FFfont qt;
|
||||
ffFontInitQt(&qt, ffDetectQt(instance)->font.chars);
|
||||
ffStrbufAppend(&result->fonts[0], &qt.pretty);
|
||||
ffFontDestroy(&qt);
|
||||
|
||||
FFfont gtk2;
|
||||
ffFontInitPango(>k2, ffDetectGTK2(instance)->font.chars);
|
||||
ffStrbufAppend(&result->fonts[1], >k2.pretty);
|
||||
ffFontDestroy(>k2);
|
||||
|
||||
FFfont gtk3;
|
||||
ffFontInitPango(>k3, ffDetectGTK3(instance)->font.chars);
|
||||
ffStrbufAppend(&result->fonts[2], >k3.pretty);
|
||||
ffFontDestroy(>k3);
|
||||
|
||||
FFfont gtk4;
|
||||
ffFontInitPango(>k4, ffDetectGTK4(instance)->font.chars);
|
||||
ffStrbufAppend(&result->fonts[3], >k4.pretty);
|
||||
ffFontDestroy(>k4);
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_GPU_TEMP_UNSET (0/0.0)
|
||||
#define FF_GPU_CORE_COUNT_UNSET -1
|
||||
|
||||
typedef struct FFGPUResult
|
||||
{
|
||||
@@ -13,6 +14,7 @@ typedef struct FFGPUResult
|
||||
FFstrbuf name;
|
||||
FFstrbuf driver;
|
||||
double temperature;
|
||||
int coreCount;
|
||||
} FFGPUResult;
|
||||
|
||||
const FFlist* ffDetectGPU(const FFinstance* instance);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "gpu.h"
|
||||
|
||||
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(gpus, instance);
|
||||
return "Unimplemented";
|
||||
}
|
||||
|
||||
@@ -1,33 +1,52 @@
|
||||
#include "gpu.h"
|
||||
#include "common/library.h"
|
||||
#include "detection/cpu/cpu.h"
|
||||
#include "detection/temps/temps_apple.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
|
||||
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||
{
|
||||
FFlist temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
if(ffStrbufStartsWithS(gpuName, "Apple M1"))
|
||||
ffDetectCoreTemps(FF_TEMP_GPU_M1X, &temps);
|
||||
else if(ffStrbufStartsWithS(gpuName, "Apple M2"))
|
||||
ffDetectCoreTemps(FF_TEMP_GPU_M2X, &temps);
|
||||
else if(ffStrbufStartsWithS(gpuName, "Intel"))
|
||||
ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &temps);
|
||||
else if(ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
|
||||
ffDetectCoreTemps(FF_TEMP_GPU_AMD, &temps);
|
||||
else
|
||||
ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &temps);
|
||||
|
||||
if(temps.length == 0)
|
||||
return FF_GPU_TEMP_UNSET;
|
||||
|
||||
double result = 0;
|
||||
for(uint32_t i = 0; i < temps.length; ++i)
|
||||
{
|
||||
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
|
||||
result += tempValue->value;
|
||||
//TODO: do we really need this?
|
||||
ffStrbufDestroy(&tempValue->name);
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
const FFCPUResult* cpu = ffDetectCPU();
|
||||
if(ffStrbufStartsWithIgnCaseS(&cpu->name, "Apple M"))
|
||||
{
|
||||
FFGPUResult* gpu = ffListAdd(gpus);
|
||||
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufAppendS(&gpu->vendor, "Apple");
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufAppendS(&gpu->name, cpu->name.chars + 6); //Cut "Apple "
|
||||
|
||||
ffStrbufInitA(&gpu->driver, 0);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching("IOPCIDevice");
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAcceleratorClassName);
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(0, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return;
|
||||
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
@@ -39,30 +58,43 @@ void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
continue;
|
||||
}
|
||||
|
||||
CFStringRef key = CFStringCreateWithCStringNoCopy(NULL, "model", kCFStringEncodingASCII, kCFAllocatorNull);
|
||||
CFStringRef model = CFDictionaryGetValue(properties, key);
|
||||
if(model == NULL || CFGetTypeID(model) != CFDataGetTypeID())
|
||||
{
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
FFGPUResult* gpu = ffListAdd(gpus);
|
||||
|
||||
uint32_t modelLength = (uint32_t) CFStringGetLength(model);
|
||||
ffStrbufInitA(&gpu->name, modelLength + 1);
|
||||
CFStringGetCString(model, gpu->name.chars, modelLength + 1, kCFStringEncodingASCII);
|
||||
gpu->name.length = modelLength;
|
||||
gpu->name.chars[gpu->name.length] = '\0';
|
||||
|
||||
ffStrbufInitA(&gpu->vendor, 0);
|
||||
ffStrbufInitA(&gpu->driver, 0);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffCfDictGetString(properties, CFSTR("CFBundleIdentifier"), &gpu->driver);
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
//IOAccelerator returns model property for Apple Silicon, but not for Intel Iris GPUs.
|
||||
//Still needs testing for AMD's
|
||||
if(ffCfDictGetString(properties, CFSTR("model"), &gpu->name))
|
||||
{
|
||||
CFRelease(properties);
|
||||
|
||||
io_registry_entry_t parentEntry;
|
||||
IORegistryEntryGetParentEntry(registryEntry, kIOServicePlane, &parentEntry);
|
||||
if(IORegistryEntryCreateCFProperties(parentEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(parentEntry);
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
ffCfDictGetString(properties, CFSTR("model"), &gpu->name);
|
||||
}
|
||||
|
||||
if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount))
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
if(instance->config.gpuTemp)
|
||||
gpu->temperature = detectGpuTemp(&gpu->name);
|
||||
else
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
}
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "common/library.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
#include "detection/temps.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pci/pci.h>
|
||||
@@ -17,10 +17,14 @@
|
||||
typedef struct PCIData
|
||||
{
|
||||
struct pci_access* access;
|
||||
FF_LIBRARY_SYMBOL(pci_read_byte);
|
||||
FF_LIBRARY_SYMBOL(pci_read_word);
|
||||
FF_LIBRARY_SYMBOL(pci_lookup_name);
|
||||
FF_LIBRARY_SYMBOL(pci_get_param);
|
||||
FF_LIBRARY_SYMBOL(pci_fill_info)
|
||||
FF_LIBRARY_SYMBOL(pci_read_byte)
|
||||
FF_LIBRARY_SYMBOL(pci_lookup_name)
|
||||
FF_LIBRARY_SYMBOL(pci_get_param)
|
||||
|
||||
#if PCI_LIB_VERSION >= 0x030800
|
||||
FF_LIBRARY_SYMBOL(pci_get_string_property)
|
||||
#endif
|
||||
} PCIData;
|
||||
|
||||
static bool pciIDsContains(u16 searched, const u16* ids)
|
||||
@@ -60,9 +64,27 @@ static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
|
||||
|
||||
static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
|
||||
{
|
||||
u8 revId;
|
||||
bool revIdSet = false;;
|
||||
|
||||
#if PCI_LIB_VERSION >= 0x030800
|
||||
revIdSet = pci->ffpci_fill_info(device, PCI_FILL_CLASS_EXT) & PCI_FILL_CLASS_EXT;
|
||||
if(revIdSet)
|
||||
revId = device->rev_id;
|
||||
#endif
|
||||
|
||||
if(!revIdSet)
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
return;
|
||||
#else
|
||||
revId = pci->ffpci_read_byte(device, PCI_REVISION_ID);
|
||||
#endif
|
||||
}
|
||||
|
||||
FFstrbuf query;
|
||||
ffStrbufInit(&query);
|
||||
ffStrbufAppendF(&query, "%X, %X,", device->device_id, pci->ffpci_read_byte(device, PCI_REVISION_ID));
|
||||
ffStrbufAppendF(&query, "%X, %X,", device->device_id, revId);
|
||||
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/libdrm/amdgpu.ids", query.chars, &gpu->name);
|
||||
|
||||
@@ -100,6 +122,14 @@ static void pciDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
|
||||
|
||||
static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
|
||||
{
|
||||
#if PCI_LIB_VERSION >= 0x030800
|
||||
pci->ffpci_fill_info(device, PCI_FILL_DRIVER);
|
||||
ffStrbufAppendS(&gpu->driver, pci->ffpci_get_string_property(device, PCI_FILL_DRIVER));
|
||||
|
||||
if(gpu->driver.length > 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
const char* base = pci->ffpci_get_param(pci->access, "sysfs.path");
|
||||
if(!ffStrSet(base))
|
||||
return;
|
||||
@@ -120,9 +150,9 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device)
|
||||
static void pciDetectTemperatur(const FFinstance* instance, FFGPUResult* gpu, struct pci_dev* device)
|
||||
{
|
||||
const FFTempsResult* tempsResult = ffDetectTemps();
|
||||
const FFTempsResult* tempsResult = ffDetectTemps(instance);
|
||||
|
||||
for(uint32_t i = 0; i < tempsResult->values.length; i++)
|
||||
{
|
||||
@@ -141,9 +171,9 @@ static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device)
|
||||
}
|
||||
}
|
||||
|
||||
static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* device)
|
||||
static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData* pci, struct pci_dev* device)
|
||||
{
|
||||
device->device_class = pci->ffpci_read_word(device, PCI_CLASS_DEVICE);
|
||||
pci->ffpci_fill_info(device, PCI_FILL_CLASS);
|
||||
|
||||
char class[1024];
|
||||
pci->ffpci_lookup_name(pci->access, class, sizeof(class) - 1, PCI_LOOKUP_CLASS, device->device_class);
|
||||
@@ -154,8 +184,7 @@ static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* devic
|
||||
strcasecmp("Display controller", class) != 0
|
||||
) return;
|
||||
|
||||
device->vendor_id = pci->ffpci_read_word(device, PCI_VENDOR_ID);
|
||||
device->device_id = pci->ffpci_read_word(device, PCI_DEVICE_ID);
|
||||
pci->ffpci_fill_info(device, PCI_FILL_IDENT);
|
||||
|
||||
FFGPUResult* gpu = ffListAdd(results);
|
||||
|
||||
@@ -168,24 +197,31 @@ static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* devic
|
||||
ffStrbufInit(&gpu->driver);
|
||||
pciDetectDriverName(gpu, pci, device);
|
||||
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
pciDetectTemperatur(gpu, device);
|
||||
if(instance->config.gpuTemp)
|
||||
pciDetectTemperatur(instance, gpu, device);
|
||||
}
|
||||
|
||||
static void pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
|
||||
static const char* pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
|
||||
{
|
||||
PCIData pci;
|
||||
|
||||
FF_LIBRARY_LOAD(libpci, instance->config.libPCI, , "libpci.so", 4)
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_alloc, )
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_init, )
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_scan_bus, )
|
||||
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_cleanup, )
|
||||
FF_LIBRARY_LOAD(libpci, &instance->config.libPCI, "dlopen libpci.so failed", "libpci.so", 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_cleanup);
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_read_byte, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_read_word, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_lookup_name, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libpci, pci, pci_get_param, )
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_fill_info);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_lookup_name);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_read_byte);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_get_param);
|
||||
|
||||
#if PCI_LIB_VERSION >= 0x030800
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libpci, pci, pci_get_string_property);
|
||||
#endif
|
||||
|
||||
pci.access = ffpci_alloc();
|
||||
ffpci_init(pci.access);
|
||||
@@ -194,12 +230,13 @@ static void pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
|
||||
struct pci_dev* device = pci.access->devices;
|
||||
while(device != NULL)
|
||||
{
|
||||
pciHandleDevice(gpus, &pci, device);
|
||||
pciHandleDevice(instance, gpus, &pci, device);
|
||||
device = device->next;
|
||||
}
|
||||
|
||||
ffpci_cleanup(pci.access);
|
||||
dlclose(libpci);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -208,5 +245,7 @@ void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
#ifdef FF_HAVE_LIBPCI
|
||||
pciDetectGPUs(instance, gpus);
|
||||
#else
|
||||
FF_UNUSED(gpus, instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
+5
-5
@@ -32,7 +32,7 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
|
||||
ffStrbufAppendF(&result->cursorSize, "%i", cursorSize);
|
||||
}
|
||||
|
||||
static void detectGTKFromSettings(FFinstance* instance, FFGTKResult* result)
|
||||
static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* result)
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -144,7 +144,7 @@ static void detectGTKFromConfigDir(FFstrbuf* configDir, const char* version, FFG
|
||||
ffStrbufSubstrBefore(configDir, configDirLength);
|
||||
}
|
||||
|
||||
static void detectGTK(FFinstance* instance, const char* version, FFGTKResult* result)
|
||||
static void detectGTK(const FFinstance* instance, const char* version, FFGTKResult* result)
|
||||
{
|
||||
//Mate, Cinnamon and Gnome use dconf to save theme config
|
||||
//On other DEs, this will do nothing
|
||||
@@ -186,17 +186,17 @@ static void detectGTK(FFinstance* instance, const char* version, FFGTKResult* re
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
return &result;
|
||||
|
||||
const FFGTKResult* ffDetectGTK2(FFinstance* instance)
|
||||
const FFGTKResult* ffDetectGTK2(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECT_GTK_IMPL(2)
|
||||
}
|
||||
|
||||
const FFGTKResult* ffDetectGTK3(FFinstance* instance)
|
||||
const FFGTKResult* ffDetectGTK3(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECT_GTK_IMPL(3)
|
||||
}
|
||||
|
||||
const FFGTKResult* ffDetectGTK4(FFinstance* instance)
|
||||
const FFGTKResult* ffDetectGTK4(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECT_GTK_IMPL(4)
|
||||
}
|
||||
|
||||
+3
-3
@@ -14,8 +14,8 @@ typedef struct FFGTKResult
|
||||
FFstrbuf cursorSize;
|
||||
} FFGTKResult;
|
||||
|
||||
const FFGTKResult* ffDetectGTK2(FFinstance* instance);
|
||||
const FFGTKResult* ffDetectGTK4(FFinstance* instance);
|
||||
const FFGTKResult* ffDetectGTK3(FFinstance* instance);
|
||||
const FFGTKResult* ffDetectGTK2(const FFinstance* instance);
|
||||
const FFGTKResult* ffDetectGTK4(const FFinstance* instance);
|
||||
const FFGTKResult* ffDetectGTK3(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,11 +1,120 @@
|
||||
#include "host.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
static const char* getProductName(const FFstrbuf* hwModel)
|
||||
{
|
||||
//https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L1386
|
||||
if(ffStrbufCompS(hwModel, "Mac14,7") == 0) return "MacBook Pro (13-inch, M2, 2022)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro18,3") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro18,4") == 0) return "MacBook Pro (14-inch, 2021)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro18,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro18,2") == 0) return "MacBook Pro (16-inch, 2021)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro17,1") == 0) return "MacBook Pro (13-inch, M1, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,4") == 0) return "MacBook Pro (16-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,3") == 0) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,2") == 0) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,1") == 0) return "MacBook Pro (16-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,4") == 0) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,3") == 0) return "MacBook Pro (15-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,2") == 0) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,1") == 0) return "MacBook Pro (15-inch, 2018/2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro14,3") == 0) return "MacBook Pro (15-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro14,2") == 0) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro14,1") == 0) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro13,3") == 0) return "MacBook Pro (15-inch, 2016)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro13,2") == 0) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro13,1") == 0) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro12,1") == 0) return "MacBook Pro (Retina, 13-inch, Early 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro11,4") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro11,5") == 0) return "MacBook Pro (Retina, 15-inch, Mid 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro11,2") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro11,3") == 0) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro11,1") == 0) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro10,2") == 0) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro10,1") == 0) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro9,2") == 0) return "MacBook Pro (13-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro9,1") == 0) return "MacBook Pro (15-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro8,3") == 0) return "MacBook Pro (17-inch, 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro8,2") == 0) return "MacBook Pro (15-inch, 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro8,1") == 0) return "MacBook Pro (13-inch, 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro7,1") == 0) return "MacBook Pro (13-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro6,2") == 0) return "MacBook Pro (15-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro6,1") == 0) return "MacBook Pro (17-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,5") == 0) return "MacBook Pro (13-inch, Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,3") == 0) return "MacBook Pro (15-inch, Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,2") == 0) return "MacBook Pro (17-inch, Mid/Early 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,1") == 0) return "MacBook Pro (15-inch, Late 2008)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro4,1") == 0) return "MacBook Pro (17/15-inch, Early 2008)";
|
||||
if(ffStrbufCompS(hwModel, "Mac14,2") == 0) return "MacBook Air (M2, 2022)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir10,1") == 0) return "MacBook Air (M1, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir9,1") == 0) return "MacBook Air (Retina, 13-inch, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir8,2") == 0) return "MacBook Air (Retina, 13-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir8,1") == 0) return "MacBook Air (Retina, 13-inch, 2018)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir7,2") == 0) return "MacBook Air (13-inch, Early 2015/2017)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir7,1") == 0) return "MacBook Air (11-inch, Early 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir6,2") == 0) return "MacBook Air (13-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir6,1") == 0) return "MacBook Air (11-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir5,2") == 0) return "MacBook Air (13-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir5,1") == 0) return "MacBook Air (11-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir4,2") == 0) return "MacBook Air (13-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir4,1") == 0) return "MacBook Air (11-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir3,2") == 0) return "MacBook Air (13-inch, Late 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir3,1") == 0) return "MacBook Air (11-inch, Late 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir2,1") == 0) return "MacBook Air (Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook10,1") == 0) return "MacBook (Retina, 12-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook9,1") == 0) return "MacBook (Retina, 12-inch, Early 2016)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook8,1") == 0) return "MacBook (Retina, 12-inch, Early 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook7,1") == 0) return "MacBook (13-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook6,1") == 0) return "MacBook (13-inch, Late 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook5,2") == 0) return "MacBook (13-inch, Early/Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "Mac13,1") == 0) return "Mac Studio (2022, Two USB-C front ports)";
|
||||
if(ffStrbufCompS(hwModel, "Mac13,2") == 0) return "Mac Studio (2022, Two Thunderbolt 4 front ports)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini9,1") == 0) return "Mac mini (M1, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini8,1") == 0) return "Mac mini (2018)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini7,1") == 0) return "Mac mini (Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini6,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "Macmini6,2") == 0) return "Mac mini (Late 2012)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini5,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "Macmini5,2") == 0) return "Mac mini (Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini4,1") == 0) return "Mac mini (Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini3,1") == 0) return "Mac mini (Early/Late 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro7,1") == 0) return "Mac Pro (2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro6,1") == 0) return "Mac Pro (Late 2013)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro5,1") == 0) return "Mac Pro (Mid 2010 - Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro4,1") == 0) return "Mac Pro (Early 2009)";
|
||||
if(ffStrbufCompS(hwModel, "iMac21,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "iMac21,2") == 0) return "iMac (24-inch, M1, 2021)";
|
||||
if(ffStrbufCompS(hwModel, "iMac20,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "iMac20,2") == 0) return "iMac (Retina 5K, 27-inch, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "iMac19,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "iMac19,2") == 0) return "iMac (Retina 4K, 21.5-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "iMacPro1,1") == 0) return "iMac Pro (2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac18,3") == 0) return "iMac (Retina 5K, 27-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac18,2") == 0) return "iMac (Retina 4K, 21.5-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac18,1") == 0) return "iMac (21.5-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac17,1") == 0) return "iMac (Retina 5K, 27-inch, Late 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac16,2") == 0) return "iMac (Retina 4K, 21.5-inch, Late 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac16,1") == 0) return "iMac (21.5-inch, Late 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac15,1") == 0) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac14,4") == 0) return "iMac (21.5-inch, Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "iMac14,2") == 0) return "iMac (27-inch, Late 2013)";
|
||||
if(ffStrbufCompS(hwModel, "iMac14,1") == 0) return "iMac (21.5-inch, Late 2013)";
|
||||
if(ffStrbufCompS(hwModel, "iMac13,2") == 0) return "iMac (27-inch, Late 2012)";
|
||||
if(ffStrbufCompS(hwModel, "iMac13,1") == 0) return "iMac (21.5-inch, Late 2012)";
|
||||
if(ffStrbufCompS(hwModel, "iMac12,2") == 0) return "iMac (27-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "iMac12,1") == 0) return "iMac (21.5-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "iMac11,3") == 0) return "iMac (27-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "iMac11,2") == 0) return "iMac (21.5-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "iMac10,1") == 0) return "iMac (27/21.5-inch, Late 2009)";
|
||||
if(ffStrbufCompS(hwModel, "iMac9,1") == 0) return "iMac (24/20-inch, Early 2009)";
|
||||
return hwModel->chars;
|
||||
}
|
||||
|
||||
void ffDetectHostImpl(FFHostResult* host)
|
||||
{
|
||||
ffStrbufInit(&host->productName);
|
||||
ffStrbufInit(&host->productFamily);
|
||||
|
||||
ffStrbufInitA(&host->productFamily, 0);
|
||||
ffStrbufInitA(&host->sysVendor, 0);
|
||||
ffStrbufInitA(&host->productVersion, 0);
|
||||
ffStrbufInitA(&host->productSku, 0);
|
||||
@@ -20,5 +129,6 @@ void ffDetectHostImpl(FFHostResult* host)
|
||||
ffStrbufInitA(&host->chassisVendor, 0);
|
||||
ffStrbufInitA(&host->chassisVersion, 0);
|
||||
|
||||
ffSettingsGetAppleProperty("hw.model", &host->productName);
|
||||
ffSysctlGetString("hw.model", &host->productFamily);
|
||||
ffStrbufAppendS(&host->productName, getProductName(&host->productFamily));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "media.h"
|
||||
#include "detection/internal.h"
|
||||
|
||||
void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media);
|
||||
|
||||
const FFMediaResult* ffDetectMedia(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECTION_INTERNAL_GUARD(FFMediaResult,
|
||||
ffStrbufInitA(&result.error, 0);
|
||||
ffStrbufInit(&result.busNameShort);
|
||||
ffStrbufInit(&result.player);
|
||||
ffStrbufInit(&result.song);
|
||||
ffStrbufInit(&result.artist);
|
||||
ffStrbufInit(&result.album);
|
||||
ffStrbufInit(&result.url);
|
||||
ffStrbufInit(&result.status);
|
||||
|
||||
ffDetectMediaImpl(instance, &result);
|
||||
|
||||
if(result.song.length == 0 && result.error.length == 0)
|
||||
ffStrbufAppendS(&result.error, "No media found");
|
||||
);
|
||||
}
|
||||
@@ -7,14 +7,16 @@
|
||||
|
||||
typedef struct FFMediaResult
|
||||
{
|
||||
FFstrbuf error;
|
||||
FFstrbuf busNameShort; //e.g. plasma-browser-integration
|
||||
FFstrbuf player; // e.g. Google Chrome
|
||||
FFstrbuf song;
|
||||
FFstrbuf artist;
|
||||
FFstrbuf album;
|
||||
FFstrbuf url;
|
||||
FFstrbuf status;
|
||||
} FFMediaResult;
|
||||
|
||||
const FFMediaResult* ffDetectMedia(FFinstance* instance);
|
||||
const FFMediaResult* ffDetectMedia(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "media.h"
|
||||
|
||||
void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
ffStrbufAppendS(&media->error, "Media not supported on Android");
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/media/media.h"
|
||||
#include "common/library.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "util/apple/osascript.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
extern void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t dispatcher, void(^callback)(_Nullable CFDictionaryRef info)) __attribute__((weak_import));
|
||||
extern void MRMediaRemoteGetNowPlayingClient(dispatch_queue_t dispatcher, void (^callback)(_Nullable id clientObj)) __attribute__((weak_import));
|
||||
extern CFStringRef MRNowPlayingClientGetBundleIdentifier(id clientObj) __attribute__((weak_import));
|
||||
extern CFStringRef MRNowPlayingClientGetParentAppBundleIdentifier(id clientObj) __attribute__((weak_import));
|
||||
void MRMediaRemoteGetNowPlayingApplicationIsPlaying(dispatch_queue_t queue, void (^callback)(BOOL playing));
|
||||
|
||||
static const char* getMedia(FFMediaResult* result)
|
||||
{
|
||||
#define FF_TEST_FN_EXISTANCE(fn) if (!fn) return "MediaRemote function " #fn " is not available"
|
||||
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingInfo);
|
||||
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingClient);
|
||||
FF_TEST_FN_EXISTANCE(MRNowPlayingClientGetBundleIdentifier);
|
||||
FF_TEST_FN_EXISTANCE(MRNowPlayingClientGetParentAppBundleIdentifier);
|
||||
#undef FF_TEST_FN_EXISTANCE
|
||||
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
|
||||
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingApplicationIsPlaying(queue, ^(BOOL playing) {
|
||||
ffStrbufAppendS(&result->status, playing ? "Playing" : "Paused");
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
dispatch_group_enter(group);
|
||||
__block const char* error = NULL;
|
||||
MRMediaRemoteGetNowPlayingInfo(queue, ^(_Nullable CFDictionaryRef info) {
|
||||
if(info != nil)
|
||||
{
|
||||
error = ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoTitle"), &result->song);
|
||||
if(!error)
|
||||
{
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtist"), &result->artist);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoAlbum"), &result->album);
|
||||
}
|
||||
}
|
||||
else
|
||||
error = "MRMediaRemoteGetNowPlayingInfo() failed";
|
||||
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingClient(queue, ^(_Nullable id clientObj) {
|
||||
if (clientObj != nil)
|
||||
{
|
||||
CFStringRef identifier = MRNowPlayingClientGetBundleIdentifier(clientObj);
|
||||
if (identifier == nil)
|
||||
identifier = MRNowPlayingClientGetParentAppBundleIdentifier(clientObj);
|
||||
if (identifier != nil)
|
||||
ffCfStrGetString(identifier, &result->busNameShort);
|
||||
}
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if(result->busNameShort.length > 0)
|
||||
{
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "name of app id \"%s\"", result->busNameShort.chars);
|
||||
ffOsascript(buf, &result->player);
|
||||
}
|
||||
|
||||
if(result->song.length > 0)
|
||||
return NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media)
|
||||
{
|
||||
FF_UNUSED(instance)
|
||||
const char* error = getMedia(media);
|
||||
ffStrbufAppendS(&media->error, error);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/media.h"
|
||||
#include "detection/media/media.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
@@ -232,7 +232,7 @@ static bool getBusProperties(const char* busName, FFMediaResult* result, DBusDat
|
||||
return true;
|
||||
}
|
||||
|
||||
static void getCustomBus(FFinstance* instance, FFMediaResult* result, DBusData* data)
|
||||
static void getCustomBus(const FFinstance* instance, FFMediaResult* result, DBusData* data)
|
||||
{
|
||||
if(ffStrbufStartsWithS(&instance->config.playerName, FF_DBUS_MPRIS_PREFIX))
|
||||
{
|
||||
@@ -291,33 +291,33 @@ static void getBestBus(FFMediaResult* result, DBusData* data)
|
||||
data->ffdbus_message_unref(reply);
|
||||
}
|
||||
|
||||
static void getMedia(FFinstance* instance, FFMediaResult* result)
|
||||
static const char* getMedia(const FFinstance* instance, FFMediaResult* result)
|
||||
{
|
||||
DBusData data;
|
||||
|
||||
FF_LIBRARY_LOAD(dbus, instance->config.libDBus, , "libdbus-1.so", 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL(dbus, dbus_bus_get,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_new_method_call,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_init,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_init_append,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_append_basic,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_get_arg_type,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_get_basic,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_recurse,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_has_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_iter_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_message_unref,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_connection_send_with_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_connection_flush,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_pending_call_block,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_pending_call_steal_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(dbus, data, dbus_pending_call_unref,)
|
||||
FF_LIBRARY_LOAD(dbus, &instance->config.libDBus, "dlopen dbus failed", "libdbus-1.so", 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dbus, dbus_bus_get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_new_method_call)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_init)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_init_append)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_append_basic)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_get_arg_type)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_get_basic)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_recurse)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_has_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_iter_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_message_unref)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_connection_send_with_reply)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_connection_flush)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_pending_call_block)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_pending_call_steal_reply)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(dbus, data, dbus_pending_call_unref)
|
||||
|
||||
data.connection = ffdbus_bus_get(DBUS_BUS_SESSION, NULL);
|
||||
if(data.connection == NULL)
|
||||
{
|
||||
dlclose(dbus);
|
||||
return;
|
||||
return "Failed to connect to session dbus";
|
||||
}
|
||||
|
||||
if(instance->config.playerName.length > 0)
|
||||
@@ -326,44 +326,18 @@ static void getMedia(FFinstance* instance, FFMediaResult* result)
|
||||
getBestBus(result, &data);
|
||||
|
||||
dlclose(dbus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const FFMediaResult* ffDetectMedia(FFinstance* instance)
|
||||
void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media)
|
||||
{
|
||||
static FFMediaResult result;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static bool init = false;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
if(init)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.busNameShort);
|
||||
ffStrbufInit(&result.player);
|
||||
ffStrbufInit(&result.song);
|
||||
ffStrbufInit(&result.artist);
|
||||
ffStrbufInit(&result.album);
|
||||
ffStrbufInit(&result.url);
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
getMedia(instance, &result);
|
||||
const char* error = getMedia(instance, media);
|
||||
ffStrbufAppendS(&media->error, error);
|
||||
#else
|
||||
FF_UNUSED(instance);
|
||||
ffStrbufAppendS(&media->error, "Fastfetch was compiled without DBus support");
|
||||
#endif
|
||||
|
||||
//Set player if a custom player was given, but loading with dbus failed
|
||||
if(instance->config.playerName.length > 0 && result.song.length == 0)
|
||||
{
|
||||
if(ffStrbufStartsWithS(&instance->config.playerName, FF_DBUS_MPRIS_PREFIX))
|
||||
ffStrbufAppendS(&result.player, instance->config.playerName.chars + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
else
|
||||
ffStrbufAppend(&result.player, &instance->config.playerName);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
@@ -5,6 +5,9 @@ void ffDetectMemoryImpl(FFMemoryResult* memory);
|
||||
|
||||
static void calculatePercentage(FFMemoryStorage* storage)
|
||||
{
|
||||
if(storage->error.length != 0)
|
||||
return;
|
||||
|
||||
if(storage->bytesTotal == 0)
|
||||
storage->percentage = 0;
|
||||
else
|
||||
@@ -14,6 +17,9 @@ static void calculatePercentage(FFMemoryStorage* storage)
|
||||
const FFMemoryResult* ffDetectMemory()
|
||||
{
|
||||
FF_DETECTION_INTERNAL_GUARD(FFMemoryResult,
|
||||
ffStrbufInitA(&result.ram.error, 0);
|
||||
ffStrbufInitA(&result.swap.error, 0);
|
||||
|
||||
ffDetectMemoryImpl(&result);
|
||||
calculatePercentage(&result.ram);
|
||||
calculatePercentage(&result.swap);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
typedef struct FFMemoryStorage
|
||||
{
|
||||
FFstrbuf error;
|
||||
uint64_t bytesUsed;
|
||||
uint64_t bytesTotal;
|
||||
uint8_t percentage;
|
||||
|
||||
@@ -1,24 +1,52 @@
|
||||
#include "memory.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
#include "common/sysctl.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <mach/mach.h>
|
||||
|
||||
void ffDetectMemoryImpl(FFMemoryResult* memory)
|
||||
static void detectRam(FFMemoryStorage* ram)
|
||||
{
|
||||
memset(memory, 0, sizeof(FFMemoryResult));
|
||||
|
||||
memory->ram.bytesTotal = (uint64_t) ffSettingsGetAppleInt64("hw.memsize", 0);
|
||||
|
||||
uint32_t pagesize = (uint32_t) ffSettingsGetAppleInt("hw.pagesize", 0);
|
||||
if(pagesize == 0)
|
||||
ram->bytesTotal = (uint64_t) ffSysctlGetInt64("hw.memsize", 0);
|
||||
if(ram->bytesTotal == 0)
|
||||
{
|
||||
ffStrbufAppendS(&ram->error, "Failed to read hw.memsize");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t pagesize = (uint32_t) ffSysctlGetInt("hw.pagesize", 0);
|
||||
if(pagesize == 0)
|
||||
{
|
||||
ffStrbufAppendS(&ram->error, "Failed to read hw.pagesize");
|
||||
return;
|
||||
}
|
||||
|
||||
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
|
||||
vm_statistics_data_t vmstat;
|
||||
if(host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) (&vmstat), &count) != KERN_SUCCESS)
|
||||
{
|
||||
ffStrbufAppendS(&ram->error, "Failed to read vm statistics");
|
||||
return;
|
||||
}
|
||||
|
||||
memory->ram.bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * pagesize;
|
||||
ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * pagesize;
|
||||
}
|
||||
|
||||
static void detectSwap(FFMemoryStorage* swap)
|
||||
{
|
||||
struct xsw_usage xsw;
|
||||
size_t size = sizeof(xsw);
|
||||
if(sysctlbyname("vm.swapusage", &xsw, &size, 0, 0) != 0)
|
||||
{
|
||||
ffStrbufAppendS(&swap->error, "Failed to read vm.swapusage");
|
||||
return;
|
||||
}
|
||||
|
||||
swap->bytesTotal = xsw.xsu_total;
|
||||
swap->bytesUsed = xsw.xsu_used;
|
||||
}
|
||||
|
||||
void ffDetectMemoryImpl(FFMemoryResult* memory)
|
||||
{
|
||||
detectRam(&memory->ram);
|
||||
detectSwap(&memory->swap);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "memory.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
static void detectRam(FFMemoryStorage* ram)
|
||||
{
|
||||
uint32_t pageSize = (uint32_t) ffSysctlGetInt("hw.pagesize", 0);
|
||||
if(pageSize == 0)
|
||||
{
|
||||
ffStrbufAppendS(&ram->error, "Failed to read hw.pagesize");
|
||||
return;
|
||||
}
|
||||
|
||||
ram->bytesTotal = (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_page_count", 0) * pageSize;
|
||||
if(ram->bytesTotal == 0)
|
||||
{
|
||||
ffStrbufAppendS(&ram->error, "Failed to read vm.stats.vm.v_page_count");
|
||||
return;
|
||||
}
|
||||
|
||||
ram->bytesUsed = ram->bytesTotal
|
||||
- (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_free_count", 0) * pageSize
|
||||
- (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_inactive_count", 0) * pageSize
|
||||
;
|
||||
}
|
||||
|
||||
static void detectSwap(FFMemoryStorage* swap)
|
||||
{
|
||||
ffStrbufAppendS(&swap->error, "Not implemented");
|
||||
}
|
||||
void ffDetectMemoryImpl(FFMemoryResult* memory)
|
||||
{
|
||||
detectRam(&memory->ram);
|
||||
detectSwap(&memory->swap);
|
||||
}
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
void ffDetectMemoryImpl(FFMemoryResult* memory)
|
||||
{
|
||||
memset(memory, 0, sizeof(FFMemoryResult));
|
||||
|
||||
FILE* meminfo = fopen("/proc/meminfo", "r");
|
||||
if(meminfo == NULL)
|
||||
{
|
||||
ffStrbufAppendS(&memory->ram.error, "Failed to open /proc/meminfo");
|
||||
ffStrbufAppendS(&memory->swap.error, "Failed to open /proc/meminfo");
|
||||
return;
|
||||
}
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
@@ -41,7 +43,10 @@ void ffDetectMemoryImpl(FFMemoryResult* memory)
|
||||
fclose(meminfo);
|
||||
|
||||
memory->ram.bytesTotal = memTotal * (uint64_t) 1024;
|
||||
memory->ram.bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024;
|
||||
if(memory->ram.bytesTotal == 0)
|
||||
ffStrbufAppendS(&memory->ram.error, "Failed to read MemTotal");
|
||||
else
|
||||
memory->ram.bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024;
|
||||
|
||||
memory->swap.bytesTotal = swapTotal * (uint64_t) 1024;
|
||||
memory->swap.bytesUsed = (swapTotal - swapFree) * (uint64_t) 1024;
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
#include "os.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
typedef enum PListKey
|
||||
{
|
||||
PLIST_KEY_NAME,
|
||||
PLIST_KEY_VERSION,
|
||||
PLIST_KEY_BUILD,
|
||||
PLIST_KEY_OTHER
|
||||
} PListKey;
|
||||
|
||||
static void parseFile(FFOSResult* os)
|
||||
{
|
||||
FILE* plist = fopen("/System/Library/CoreServices/SystemVersion.plist", "r");
|
||||
if(plist == NULL)
|
||||
return;
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
PListKey key = PLIST_KEY_OTHER;
|
||||
|
||||
FFstrbuf keyBuffer;
|
||||
ffStrbufInit(&keyBuffer);
|
||||
|
||||
while(getline(&line, &len, plist) != EOF)
|
||||
{
|
||||
if(ffParsePropLine(line, "<key>", &keyBuffer))
|
||||
{
|
||||
if(ffStrbufIgnCaseCompS(&keyBuffer, "ProductName") == 0)
|
||||
key = PLIST_KEY_NAME;
|
||||
else if(ffStrbufIgnCaseCompS(&keyBuffer, "ProductUserVisibleVersion") == 0)
|
||||
key = PLIST_KEY_VERSION;
|
||||
else if(ffStrbufIgnCaseCompS(&keyBuffer, "ProductBuildVersion") == 0)
|
||||
key = PLIST_KEY_BUILD;
|
||||
else
|
||||
key = PLIST_KEY_OTHER;
|
||||
|
||||
ffStrbufClear(&keyBuffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(key == PLIST_KEY_NAME)
|
||||
ffParsePropLine(line, "<string>", &os->name);
|
||||
else if(key == PLIST_KEY_VERSION)
|
||||
ffParsePropLine(line, "<string>", &os->version);
|
||||
else if(key == PLIST_KEY_BUILD)
|
||||
ffParsePropLine(line, "<string>", &os->buildID);
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&keyBuffer);
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
fclose(plist);
|
||||
}
|
||||
|
||||
void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
ffStrbufInit(&os->name);
|
||||
ffStrbufInit(&os->version);
|
||||
ffStrbufInit(&os->buildID);
|
||||
ffStrbufInit(&os->id);
|
||||
ffStrbufInit(&os->prettyName);
|
||||
ffStrbufInit(&os->versionID);
|
||||
ffStrbufInit(&os->systemName);
|
||||
ffStrbufInit(&os->architecture);
|
||||
|
||||
ffStrbufInitA(&os->codename, 0);
|
||||
ffStrbufInitA(&os->idLike, 0);
|
||||
ffStrbufInitA(&os->variant, 0);
|
||||
ffStrbufInitA(&os->variantID, 0);
|
||||
|
||||
parseFile(os);
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&os->name, "MacOS"))
|
||||
ffStrbufAppendS(&os->id, "macos");
|
||||
|
||||
if(os->version.length == 0)
|
||||
ffSettingsGetAppleProperty("kern.osproductversion", &os->version);
|
||||
|
||||
//TODO map version to pretty name
|
||||
ffStrbufAppend(&os->prettyName, &os->name);
|
||||
ffStrbufAppend(&os->versionID, &os->version);
|
||||
ffSettingsGetAppleProperty("kern.ostype", &os->systemName);
|
||||
ffSettingsGetAppleProperty("hw.machine", &os->architecture);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "os.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static void parseSystemVersion(FFOSResult* os)
|
||||
{
|
||||
NSError* error;
|
||||
NSString* fileName = @"file:///System/Library/CoreServices/SystemVersion.plist";
|
||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
|
||||
error:&error];
|
||||
if(error)
|
||||
return;
|
||||
|
||||
NSString* value;
|
||||
|
||||
if((value = [dict valueForKey:@"ProductName"]))
|
||||
ffStrbufInitS(&os->name, value.UTF8String);
|
||||
if((value = [dict valueForKey:@"ProductUserVisibleVersion"]))
|
||||
ffStrbufInitS(&os->version, value.UTF8String);
|
||||
if((value = [dict valueForKey:@"ProductBuildVersion"]))
|
||||
ffStrbufInitS(&os->buildID, value.UTF8String);
|
||||
}
|
||||
|
||||
void parseOSXSoftwareLicense(FFOSResult* os)
|
||||
{
|
||||
FILE* rtf = fopen("/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf", "r");
|
||||
if(rtf == NULL)
|
||||
return;
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
const char* searchStr = "\\f0\\b SOFTWARE LICENSE AGREEMENT FOR macOS ";
|
||||
const size_t searchLen = strlen(searchStr);
|
||||
while(getline(&line, &len, rtf) != EOF)
|
||||
{
|
||||
if (strncmp(line, searchStr, searchLen) == 0)
|
||||
{
|
||||
ffStrbufAppendS(&os->codename, line + searchLen);
|
||||
ffStrbufTrimRight(&os->codename, '\n');
|
||||
ffStrbufTrimRight(&os->codename, '\\');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
fclose(rtf);
|
||||
}
|
||||
|
||||
void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
ffStrbufInit(&os->name);
|
||||
ffStrbufInit(&os->version);
|
||||
ffStrbufInit(&os->buildID);
|
||||
ffStrbufInit(&os->id);
|
||||
ffStrbufInit(&os->prettyName);
|
||||
ffStrbufInit(&os->versionID);
|
||||
ffStrbufInit(&os->systemName);
|
||||
ffStrbufInit(&os->architecture);
|
||||
|
||||
ffStrbufInitA(&os->codename, 0);
|
||||
ffStrbufInitA(&os->idLike, 0);
|
||||
ffStrbufInitA(&os->variant, 0);
|
||||
ffStrbufInitA(&os->variantID, 0);
|
||||
|
||||
parseSystemVersion(os);
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&os->name, "MacOS"))
|
||||
ffStrbufAppendS(&os->id, "macos");
|
||||
|
||||
if(os->version.length == 0)
|
||||
ffSysctlGetString("kern.osproductversion", &os->version);
|
||||
|
||||
if(os->buildID.length == 0)
|
||||
ffSysctlGetString("kern.osversion", &os->buildID);
|
||||
|
||||
ffStrbufAppend(&os->prettyName, &os->name);
|
||||
ffStrbufAppend(&os->versionID, &os->version);
|
||||
ffSysctlGetString("kern.ostype", &os->systemName);
|
||||
ffSysctlGetString("hw.machine", &os->architecture);
|
||||
|
||||
parseOSXSoftwareLicense(os);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ static void detectOS(FFOSResult* os, const FFinstance* instance)
|
||||
return;
|
||||
}
|
||||
|
||||
if(instance->config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock/etc/bedrock-release", os))
|
||||
if(instance->config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os))
|
||||
{
|
||||
if(os->id.length == 0)
|
||||
ffStrbufAppendS(&os->id, "bedrock");
|
||||
@@ -115,7 +115,7 @@ static void detectOS(FFOSResult* os, const FFinstance* instance)
|
||||
return;
|
||||
}
|
||||
|
||||
parseFile(FASTFETCH_TARGET_DIR_ROOT"/etc/os-release", os);
|
||||
parseFile(FASTFETCH_TARGET_DIR_ETC"/os-release", os);
|
||||
if(allRelevantValuesSet(os))
|
||||
return;
|
||||
|
||||
@@ -123,7 +123,7 @@ static void detectOS(FFOSResult* os, const FFinstance* instance)
|
||||
if(allRelevantValuesSet(os))
|
||||
return;
|
||||
|
||||
parseFile(FASTFETCH_TARGET_DIR_ROOT"/etc/lsb-release", os);
|
||||
parseFile(FASTFETCH_TARGET_DIR_ETC"/lsb-release", os);
|
||||
}
|
||||
|
||||
void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_poweradapter_poweradapter
|
||||
#define FF_INCLUDED_detection_poweradapter_poweradapter
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct PowerAdapterResult
|
||||
{
|
||||
FFstrbuf description;
|
||||
FFstrbuf name;
|
||||
FFstrbuf modelName;
|
||||
FFstrbuf manufacturer;
|
||||
int watts;
|
||||
} PowerAdapterResult;
|
||||
|
||||
const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results);
|
||||
|
||||
#define FF_POWER_ADAPTER_UNSET -2
|
||||
#define FF_POWER_ADAPTER_NOT_CONNECTED -1
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "fastfetch.h"
|
||||
#include "poweradapter.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
|
||||
if (matchDict == NULL)
|
||||
return "IOServiceMatching(\"AppleSmartBattery\") failed";
|
||||
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
PowerAdapterResult* adapter = ffListAdd(results);
|
||||
|
||||
ffStrbufInit(&adapter->name);
|
||||
ffStrbufInit(&adapter->description);
|
||||
ffStrbufInit(&adapter->manufacturer);
|
||||
ffStrbufInit(&adapter->modelName);
|
||||
adapter->watts = FF_POWER_ADAPTER_UNSET;
|
||||
|
||||
CFDictionaryRef adapterDict;
|
||||
if(!ffCfDictGetDict(properties, CFSTR("AdapterDetails"), &adapterDict))
|
||||
{
|
||||
if (ffCfDictGetInt(adapterDict, CFSTR("Watts"), &adapter->watts))
|
||||
{
|
||||
adapter->watts = FF_POWER_ADAPTER_NOT_CONNECTED;
|
||||
continue;
|
||||
}
|
||||
ffCfDictGetString(adapterDict, CFSTR("Name"), &adapter->name);
|
||||
ffCfDictGetString(adapterDict, CFSTR("Description"), &adapter->description);
|
||||
ffCfDictGetString(adapterDict, CFSTR("Manufacturer"), &adapter->manufacturer);
|
||||
ffCfDictGetString(adapterDict, CFSTR("Model"), &adapter->modelName);
|
||||
}
|
||||
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
}
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance, results);
|
||||
return "Unimplemented";
|
||||
}
|
||||
+1
-1
@@ -131,7 +131,7 @@ static void detectLXQt(const FFinstance* instance, FFQtResult* result)
|
||||
});
|
||||
}
|
||||
|
||||
const FFQtResult* ffDetectQt(FFinstance* instance)
|
||||
const FFQtResult* ffDetectQt(const FFinstance* instance)
|
||||
{
|
||||
static FFQtResult result;
|
||||
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ typedef struct FFQtResult
|
||||
FFstrbuf font;
|
||||
} FFQtResult;
|
||||
|
||||
const FFQtResult* ffDetectQt(FFinstance* instance);
|
||||
const FFQtResult* ffDetectQt(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
#include "fastfetch.h"
|
||||
#include "temps_apple.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
static const char kDataTypeFlt[] = "flt ";
|
||||
static const char kDataTypeFp1f[] = "fp1f";
|
||||
static const char kDataTypeFp4c[] = "fp4c";
|
||||
static const char kDataTypeFp5b[] = "fp5b";
|
||||
static const char kDataTypeFp6a[] = "fp6a";
|
||||
static const char kDataTypeFp79[] = "fp79";
|
||||
static const char kDataTypeFp88[] = "fp88";
|
||||
static const char kDataTypeFpa6[] = "fpa6";
|
||||
static const char kDataTypeFpc4[] = "fpc4";
|
||||
static const char kDataTypeFpe2[] = "fpe2";
|
||||
static const char kDataTypeSp1e[] = "sp1e";
|
||||
static const char kDataTypeSp3c[] = "sp3c";
|
||||
static const char kDataTypeSp4b[] = "sp4b";
|
||||
static const char kDataTypeSp5a[] = "sp5a";
|
||||
static const char kDataTypeSp69[] = "sp69";
|
||||
static const char kDataTypeSp78[] = "sp78";
|
||||
static const char kDataTypeSp87[] = "sp87";
|
||||
static const char kDataTypeSp96[] = "sp96";
|
||||
static const char kDataTypeSpb4[] = "spb4";
|
||||
static const char kDataTypeSpf0[] = "spf0";
|
||||
static const char kDataTypeUi8[] = "ui8 ";
|
||||
static const char kDataTypeUi16[] = "ui16";
|
||||
static const char kDataTypeUi32[] = "ui32";
|
||||
static const char kDataTypeUi64[] = "ui64";
|
||||
static const char kDataTypeSi8[] = "si8 ";
|
||||
static const char kDataTypeSi16[] = "si16";
|
||||
static const char kDataTypePwm[] = "{pwm";
|
||||
|
||||
static const char *kIOAppleSmcHiddenClassName = "AppleSMC";
|
||||
static const char kSmcCmdReadBytes = 5;
|
||||
static const char kSmcCmdReadKeyInfo = 9;
|
||||
static const uint32_t kKernelIndexSmc = 2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char major;
|
||||
char minor;
|
||||
char build;
|
||||
char reserved[1];
|
||||
uint16_t release;
|
||||
} SmcKeyData_vers_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t version;
|
||||
uint16_t length;
|
||||
uint32_t cpuPLimit;
|
||||
uint32_t gpuPLimit;
|
||||
uint32_t memPLimit;
|
||||
} SmcKeyData_pLimitData_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dataSize;
|
||||
uint32_t dataType;
|
||||
char dataAttributes;
|
||||
} SmcKeyData_keyInfo_t;
|
||||
|
||||
typedef unsigned char SmcBytes_t[32];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t key;
|
||||
SmcKeyData_vers_t vers;
|
||||
SmcKeyData_pLimitData_t pLimitData;
|
||||
SmcKeyData_keyInfo_t keyInfo;
|
||||
char result;
|
||||
char status;
|
||||
char data8;
|
||||
uint32_t data32;
|
||||
SmcBytes_t bytes;
|
||||
} SmcKeyData_t;
|
||||
|
||||
typedef char UInt32Char_t[5];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32Char_t key;
|
||||
uint32_t dataSize;
|
||||
UInt32Char_t dataType;
|
||||
SmcBytes_t bytes;
|
||||
} SmcVal_t;
|
||||
|
||||
static uint32_t smcStrtoul(const char *str, int size, int base)
|
||||
{
|
||||
uint32_t total = 0;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (base == 16)
|
||||
total += (uint32_t)(str[i] << (size - 1 - i) * 8);
|
||||
else
|
||||
total += (uint32_t)((unsigned char)(str[i]) << (size - 1 - i) * 8);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static void smcUltostr(char *str, uint32_t val)
|
||||
{
|
||||
str[0] = '\0';
|
||||
sprintf(str, "%c%c%c%c",
|
||||
(unsigned int)val >> 24,
|
||||
(unsigned int)val >> 16,
|
||||
(unsigned int)val >> 8,
|
||||
(unsigned int)val);
|
||||
}
|
||||
|
||||
static const char *smcCall(io_connect_t conn, uint32_t selector, SmcKeyData_t *inputStructure, SmcKeyData_t *outputStructure)
|
||||
{
|
||||
size_t structureInputSize;
|
||||
size_t structureOutputSize;
|
||||
structureInputSize = sizeof(SmcKeyData_t);
|
||||
structureOutputSize = sizeof(SmcKeyData_t);
|
||||
|
||||
if (IOConnectCallStructMethod(conn, selector, inputStructure, structureInputSize, outputStructure, &structureOutputSize) != kIOReturnSuccess)
|
||||
return "IOConnectCallStructMethod(conn) failed";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Provides key info, using a cache to dramatically improve the energy impact of smcFanControl
|
||||
static const char *smcGetKeyInfo(io_connect_t conn, const uint32_t key, SmcKeyData_keyInfo_t *key_info)
|
||||
{
|
||||
SmcKeyData_t inputStructure = {0};
|
||||
SmcKeyData_t outputStructure = {0};
|
||||
|
||||
inputStructure.key = key;
|
||||
inputStructure.data8 = kSmcCmdReadKeyInfo;
|
||||
|
||||
const char *error = smcCall(conn, kKernelIndexSmc, &inputStructure, &outputStructure);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
*key_info = outputStructure.keyInfo;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcVal_t *val)
|
||||
{
|
||||
SmcKeyData_t inputStructure = {0};
|
||||
SmcKeyData_t outputStructure = {0};
|
||||
|
||||
inputStructure.key = smcStrtoul(key, 4, 16);
|
||||
strcpy(val->key, key);
|
||||
|
||||
const char *error = smcGetKeyInfo(conn, inputStructure.key, &outputStructure.keyInfo);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
val->dataSize = outputStructure.keyInfo.dataSize;
|
||||
smcUltostr(val->dataType, outputStructure.keyInfo.dataType);
|
||||
inputStructure.keyInfo.dataSize = val->dataSize;
|
||||
inputStructure.data8 = kSmcCmdReadBytes;
|
||||
|
||||
error = smcCall(conn, kKernelIndexSmc, &inputStructure, &outputStructure);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *smcOpen(io_connect_t *conn)
|
||||
{
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAppleSmcHiddenClassName);
|
||||
if (matchDict == NULL)
|
||||
return "IOServiceMatching(\"AppleSmartBattery\") failed";
|
||||
|
||||
io_iterator_t iterator;
|
||||
if (IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_object_t device = IOIteratorNext(iterator);
|
||||
IOObjectRelease(iterator);
|
||||
if (device == 0)
|
||||
return "No SMC device found";
|
||||
|
||||
kern_return_t result = IOServiceOpen(device, mach_task_self(), 0, conn);
|
||||
IOObjectRelease(device);
|
||||
if (result != kIOReturnSuccess)
|
||||
return "IOServiceOpen() failed";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, double *value)
|
||||
{
|
||||
SmcVal_t val = {0};
|
||||
const char* error = smcReadSmcVal(conn, key, &val);
|
||||
if (error != NULL)
|
||||
return error;
|
||||
if (val.dataSize == 0)
|
||||
return "Empty SMC result";
|
||||
|
||||
if (strcmp(val.dataType, kDataTypeUi8) == 0 ||
|
||||
strcmp(val.dataType, kDataTypeUi16) == 0 ||
|
||||
strcmp(val.dataType, kDataTypeUi32) == 0 ||
|
||||
strcmp(val.dataType, kDataTypeUi64) == 0)
|
||||
{
|
||||
uint64_t tmp = 0;
|
||||
for (uint32_t i = 0; i < val.dataSize; i++)
|
||||
tmp += (uint64_t)((uint8_t)(val.bytes[i]) * pow(256, val.dataSize - 1 - i));
|
||||
*value = tmp;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFlt) == 0)
|
||||
{
|
||||
*value = *(float *)(val.bytes);
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFp1f) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFp4c) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFp5b) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFp6a) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFp79) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFp88) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFpa6) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFpc4) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeFpe2) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 4.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp1e) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 16384.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp3c) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp4b) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp5a) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp69) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp78) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp87) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 128.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSp96) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSpb4) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSpf0) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(uint16_t *)(val.bytes)) / 1.0;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSi8) == 0 && val.dataSize == 1)
|
||||
{
|
||||
signed char *bytes = (signed char *)val.bytes;
|
||||
int16_t temp = 0;
|
||||
temp += (int8_t)(bytes[0]);
|
||||
*value = temp;
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypeSi16) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = ntohs(*(int16_t *)(val.bytes));
|
||||
}
|
||||
else if (strcmp(val.dataType, kDataTypePwm) == 0 && val.dataSize == 2)
|
||||
{
|
||||
*value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0;
|
||||
}
|
||||
else
|
||||
return "Unknown SMC data type";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void detectTemp(io_connect_t conn, const char *sensor, const char *name, FFlist *list)
|
||||
{
|
||||
double temp = 0;
|
||||
const char* error = smcReadValue(conn, sensor, &temp);
|
||||
if (error)
|
||||
return;
|
||||
|
||||
FFTempValue* tempValue= (FFTempValue*)ffListAdd(list);
|
||||
tempValue->value = temp;
|
||||
|
||||
assert(strlen(sensor) == 4);
|
||||
ffStrbufInitNS(&tempValue->deviceClass, 4, sensor);
|
||||
|
||||
ffStrbufInitS(&tempValue->name, name);
|
||||
}
|
||||
|
||||
const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result)
|
||||
{
|
||||
static io_connect_t conn;
|
||||
static dispatch_once_t once_control;
|
||||
dispatch_once_f(&once_control, &conn, (dispatch_function_t) smcOpen);
|
||||
if(!conn)
|
||||
return "smcOpen() failed";
|
||||
|
||||
// https://github.com/exelban/stats/blob/master/Modules/Sensors/values.swift
|
||||
switch (type)
|
||||
{
|
||||
case FF_TEMP_CPU_X64:
|
||||
detectTemp(conn, "TC0D", "CPU diode", result);
|
||||
detectTemp(conn, "TC0E", "CPU diode virtual", result);
|
||||
detectTemp(conn, "TC0F", "CPU diode filtered", result);
|
||||
detectTemp(conn, "TC0P", "CPU proximity", result);
|
||||
break;
|
||||
|
||||
case FF_TEMP_CPU_M1X:
|
||||
detectTemp(conn, "Tp09", "CPU efficient core 1", result);
|
||||
detectTemp(conn, "Tp0T", "CPU efficient core 2", result);
|
||||
|
||||
detectTemp(conn, "Tp01", "CPU performance core 1", result);
|
||||
detectTemp(conn, "Tp05", "CPU performance core 2", result);
|
||||
detectTemp(conn, "Tp0D", "CPU performance core 3", result);
|
||||
detectTemp(conn, "Tp0H", "CPU performance core 4", result);
|
||||
detectTemp(conn, "Tp0L", "CPU performance core 5", result);
|
||||
detectTemp(conn, "Tp0P", "CPU performance core 6", result);
|
||||
detectTemp(conn, "Tp0X", "CPU performance core 7", result);
|
||||
detectTemp(conn, "Tp0b", "CPU performance core 8", result);
|
||||
break;
|
||||
|
||||
case FF_TEMP_CPU_M2X:
|
||||
detectTemp(conn, "Tp05", "CPU efficient core 1", result);
|
||||
detectTemp(conn, "Tp0D", "CPU efficient core 2", result);
|
||||
detectTemp(conn, "Tp0j", "CPU efficient core 3", result);
|
||||
detectTemp(conn, "Tp0r", "CPU efficient core 4", result);
|
||||
|
||||
detectTemp(conn, "Tp01", "CPU performance core 1", result);
|
||||
detectTemp(conn, "Tp09", "CPU performance core 2", result);
|
||||
detectTemp(conn, "Tp0f", "CPU performance core 3", result);
|
||||
detectTemp(conn, "Tp0n", "CPU performance core 4", result);
|
||||
break;
|
||||
|
||||
case FF_TEMP_GPU_INTEL:
|
||||
detectTemp(conn, "TCGC", "GPU Intel Graphics", result);
|
||||
goto gpu_unknown;
|
||||
|
||||
case FF_TEMP_GPU_AMD:
|
||||
detectTemp(conn, "TGDD", "GPU AMD Radeon", result);
|
||||
goto gpu_unknown;
|
||||
|
||||
case FF_TEMP_GPU_UNKNOWN: // Nvidia?
|
||||
gpu_unknown:
|
||||
detectTemp(conn, "TG0D", "GPU diode", result);
|
||||
detectTemp(conn, "TG0P", "GPU proximity", result);
|
||||
break;
|
||||
|
||||
case FF_TEMP_GPU_M1X:
|
||||
detectTemp(conn, "Tg05", "GPU 1", result);
|
||||
detectTemp(conn, "Tg0D", "GPU 2", result);
|
||||
detectTemp(conn, "Tg0L", "GPU 3", result);
|
||||
detectTemp(conn, "Tg0T", "GPU 4", result);
|
||||
break;
|
||||
|
||||
case FF_TEMP_GPU_M2X:
|
||||
detectTemp(conn, "Tg0f", "GPU 1", result);
|
||||
detectTemp(conn, "Tg0n", "GPU 2", result);
|
||||
break;
|
||||
|
||||
case FF_TEMP_BATTERY:
|
||||
detectTemp(conn, "TB1T", "Battery", result);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_temps_apple
|
||||
#define FF_INCLUDED_detection_temps_apple
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFlist.h"
|
||||
|
||||
typedef struct FFTempValue
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf deviceClass;
|
||||
double value;
|
||||
} FFTempValue;
|
||||
|
||||
enum FFTempType
|
||||
{
|
||||
FF_TEMP_CPU_X64,
|
||||
FF_TEMP_CPU_M1X,
|
||||
FF_TEMP_CPU_M2X,
|
||||
|
||||
FF_TEMP_GPU_INTEL,
|
||||
FF_TEMP_GPU_AMD,
|
||||
FF_TEMP_GPU_UNKNOWN,
|
||||
FF_TEMP_GPU_M1X,
|
||||
FF_TEMP_GPU_M2X,
|
||||
|
||||
FF_TEMP_BATTERY,
|
||||
};
|
||||
|
||||
const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result);
|
||||
|
||||
#endif
|
||||
@@ -1,53 +1,25 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/temps.h"
|
||||
#include "common/io.h"
|
||||
#include "temps_linux.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>
|
||||
|
||||
static bool isTempFile(const char* name)
|
||||
{
|
||||
return
|
||||
strncmp(name, "temp", 4) == 0 &&
|
||||
name[4] >= '0' &&
|
||||
name[4] <= '9' &&
|
||||
strncmp(name + 5, "_input", 6) == 0;
|
||||
}
|
||||
|
||||
static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
|
||||
{
|
||||
DIR* dirp = opendir(dir->chars);
|
||||
if(dirp == NULL)
|
||||
return false;
|
||||
|
||||
uint32_t dirLength = dir->length;
|
||||
value->value = 0.0 / 0.0; //use NaN as error value
|
||||
|
||||
FFstrbuf valueString;
|
||||
ffStrbufInit(&valueString);
|
||||
FFstrbuf valueBuffer;
|
||||
ffStrbufInit(&valueBuffer);
|
||||
|
||||
struct dirent* dirent;
|
||||
while((dirent = readdir(dirp)) != NULL)
|
||||
{
|
||||
if(!isTempFile(dirent->d_name))
|
||||
continue;
|
||||
ffStrbufAppendS(dir, "temp1_input");
|
||||
ffReadFileBuffer(dir->chars, &valueBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufAppendS(dir, dirent->d_name);
|
||||
ffReadFileBuffer(dir->chars, &valueString);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
value->value = ffStrbufToDouble(&valueBuffer);
|
||||
|
||||
//ffStrbufToDouble() returns NaN if the string couldn't be parsed
|
||||
value->value = ffStrbufToDouble(&valueString);
|
||||
if(value->value != value->value)
|
||||
continue;
|
||||
|
||||
value->value /= 1000.0; //millidegrees to degrees
|
||||
break;
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
ffStrbufDestroy(&valueString);
|
||||
ffStrbufDestroy(&valueBuffer);
|
||||
|
||||
if(value->value != value->value)
|
||||
return false;
|
||||
@@ -63,7 +35,7 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
|
||||
return value->name.length > 0 || value->deviceClass.length > 0;
|
||||
}
|
||||
|
||||
const FFTempsResult* ffDetectTemps()
|
||||
const FFTempsResult* ffDetectTemps(const FFinstance* instance)
|
||||
{
|
||||
static FFTempsResult result;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -77,6 +49,13 @@ const FFTempsResult* ffDetectTemps()
|
||||
}
|
||||
init = true;
|
||||
|
||||
if(!instance->config.allowSlowOperations)
|
||||
{
|
||||
ffListInitA(&result.values, sizeof(FFTempValue), 0);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
|
||||
ffListInitA(&result.values, sizeof(FFTempValue), 16);
|
||||
|
||||
FFstrbuf baseDir;
|
||||
@@ -88,6 +67,7 @@ const FFTempsResult* ffDetectTemps()
|
||||
DIR* dirp = opendir(baseDir.chars);
|
||||
if(dirp == NULL)
|
||||
{
|
||||
ffStrbufDestroy(&baseDir);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
@@ -114,6 +94,9 @@ const FFTempsResult* ffDetectTemps()
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
ffStrbufDestroy(&baseDir);
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_temps
|
||||
#define FF_INCLUDED_detection_temps
|
||||
#ifndef FF_INCLUDED_detection_temps_linux
|
||||
#define FF_INCLUDED_detection_temps_linux
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
@@ -17,6 +17,6 @@ typedef struct FFTempsResult
|
||||
FFlist values; //List of FFTempValue
|
||||
} FFTempsResult;
|
||||
|
||||
const FFTempsResult* ffDetectTemps();
|
||||
const FFTempsResult* ffDetectTemps(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
@@ -130,6 +130,13 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
getenv("WT_PROFILE_ID") != NULL
|
||||
)) term = "Windows Terminal";
|
||||
|
||||
//Alacritty
|
||||
if(!ffStrSet(term) && (
|
||||
getenv("ALACRITTY_SOCKET") != NULL ||
|
||||
getenv("ALACRITTY_LOG") != NULL ||
|
||||
getenv("ALACRITTY_WINDOW_ID") != NULL
|
||||
)) term = "Alacritty";
|
||||
|
||||
//Termux
|
||||
if(!ffStrSet(term) && (
|
||||
getenv("TERMUX_VERSION") != NULL ||
|
||||
@@ -137,10 +144,23 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
getenv("TMUX_TMPDIR") != NULL
|
||||
)) term = "Termux";
|
||||
|
||||
//Konsole
|
||||
if(!ffStrSet(term) && (
|
||||
getenv("KONSOLE_VERSION") != NULL
|
||||
)) term = "konsole";
|
||||
|
||||
//MacOS
|
||||
if(!ffStrSet(term))
|
||||
term = getenv("TERM_PROGRAM");
|
||||
|
||||
//We are in WSL but not in Windows Terminal
|
||||
if(!ffStrSet(term) && (
|
||||
getenv("WSLENV") != NULL ||
|
||||
getenv("WSL_DISTRO") != NULL ||
|
||||
getenv("WSL_INTEROP") != NULL
|
||||
))
|
||||
term = "conhost";
|
||||
|
||||
//Normal Terminal
|
||||
if(!ffStrSet(term))
|
||||
term = getenv("TERM");
|
||||
@@ -240,7 +260,7 @@ static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* versio
|
||||
getShellVersionGeneric(exe, exeName, version);
|
||||
}
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell(FFinstance* instance)
|
||||
const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "terminalfont.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/processing.h"
|
||||
#include "detection/internal.h"
|
||||
#include "detection/terminalshell.h"
|
||||
|
||||
static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* terminalFont) {
|
||||
FFstrbuf fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
|
||||
FFstrbuf fontSize;
|
||||
ffStrbufInit(&fontSize);
|
||||
|
||||
FFpropquery fontQuery[] = {
|
||||
{"family:", &fontName},
|
||||
{"size:", &fontSize},
|
||||
};
|
||||
|
||||
// alacritty parses config files in this order
|
||||
ffParsePropFileConfigValues(instance, "alacritty/alacritty.yml", 2, fontQuery);
|
||||
if(fontName.length == 0 || fontSize.length == 0)
|
||||
ffParsePropFileConfigValues(instance, "alacritty.yml", 2, fontQuery);
|
||||
if(fontName.length == 0 || fontSize.length == 0)
|
||||
ffParsePropFileConfigValues(instance, ".alacritty.yml", 2, fontQuery);
|
||||
|
||||
//by default alacritty uses its own font called alacritty
|
||||
if(fontName.length == 0)
|
||||
ffStrbufAppendS(&fontName, "alacritty");
|
||||
|
||||
// the default font size is 11
|
||||
if(fontSize.length == 0)
|
||||
ffStrbufAppendS(&fontSize, "11");
|
||||
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||
|
||||
ffStrbufDestroy(&fontName);
|
||||
ffStrbufDestroy(&fontSize);
|
||||
}
|
||||
|
||||
static void detectTTY(FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FFstrbuf fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_ETC"/vconsole.conf", "Font =", &fontName);
|
||||
|
||||
if(fontName.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&fontName, "VGA default kernel font ");
|
||||
ffProcessAppendStdOut(&fontName, (char* const[]){
|
||||
"showconsolefont",
|
||||
"--info",
|
||||
NULL
|
||||
});
|
||||
|
||||
ffStrbufTrimRight(&fontName, ' ');
|
||||
}
|
||||
|
||||
if(fontName.length > 0)
|
||||
ffFontInitCopy(&terminalFont->font, fontName.chars);
|
||||
else
|
||||
ffStrbufAppendS(&terminalFont->error, "Couldn't find Font in "FASTFETCH_TARGET_DIR_ETC"/vconsole.conf");
|
||||
|
||||
ffStrbufDestroy(&fontName);
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont);
|
||||
|
||||
const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECTION_INTERNAL_GUARD(FFTerminalFontResult,
|
||||
ffStrbufInitA(&result.error, 0);
|
||||
|
||||
const FFTerminalShellResult* terminalShell = ffDetectTerminalShell(instance);
|
||||
|
||||
if(terminalShell->terminalProcessName.length == 0)
|
||||
ffStrbufAppendS(&result.error, "Terminal font needs successfull terminal detection");
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "alacritty") == 0)
|
||||
detectAlacritty(instance, &result);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty"))
|
||||
detectTTY(&result);
|
||||
else
|
||||
ffDetectTerminalFontPlatform(instance, terminalShell, &result);
|
||||
|
||||
if(result.error.length == 0 && result.font.pretty.length == 0)
|
||||
ffStrbufAppendF(&result.error, "Unknown terminal: %s", terminalShell->terminalProcessName.chars);
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_terminalfont_terminalfont
|
||||
#define FF_INCLUDED_detection_terminalfont_terminalfont
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "common/font.h"
|
||||
|
||||
typedef struct FFTerminalFontResult
|
||||
{
|
||||
FFstrbuf error;
|
||||
FFfont font;
|
||||
} FFTerminalFontResult;
|
||||
|
||||
const FFTerminalFontResult* ffDetectTerminalFont(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "fastfetch.h"
|
||||
#include "terminalfont.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef FF_HAVE_FREETYPE
|
||||
#include "common/library.h"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
#define FF_TERMUX_FONT_PATH FASTFETCH_TARGET_DIR_HOME "/.termux/font.ttf"
|
||||
|
||||
const char* detectTermux(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
#ifdef FF_HAVE_FREETYPE
|
||||
|
||||
FF_LIBRARY_LOAD(freetype, &instance->config.libfreetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Init_FreeType);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_New_Face);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Done_Face);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Done_FreeType);
|
||||
|
||||
FT_Library library = NULL;
|
||||
FT_Face face = NULL;
|
||||
const char* error = NULL;
|
||||
|
||||
if(ffFT_Init_FreeType(&library))
|
||||
{
|
||||
error = "FT_Init_FreeType() failed";
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(ffFT_New_Face(library, FF_TERMUX_FONT_PATH, 0, &face ))
|
||||
{
|
||||
error = "FT_NEW_Face(" FF_TERMUX_FONT_PATH ") failed";
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ffFontInitCopy(&terminalFont->font, face->family_name);
|
||||
|
||||
exit:
|
||||
if(face) ffFT_Done_Face(face);
|
||||
if(library) ffFT_Done_FreeType(library);
|
||||
dlclose(freetype);
|
||||
|
||||
return error;
|
||||
|
||||
#else
|
||||
|
||||
FF_UNUSED(terminalFont);
|
||||
ffStrbufSetS(&terminalFont->error, "fastfetch is built without freetype2 support");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufCompS(&terminalShell->terminalProcessName, "Termux") != 0)
|
||||
{
|
||||
ffStrbufSetS(&terminalFont->error, "Unsupported terminal");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ffFileExists(FF_TERMUX_FONT_PATH, S_IFREG))
|
||||
{
|
||||
ffFontInitCopy(&terminalFont->font, "monospace");
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufSetS(&terminalFont->error, detectTermux(instance, terminalFont));
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "terminalfont.h"
|
||||
#include "common/font.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "util/apple/osascript.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
const char* profile = getenv("ITERM_PROFILE");
|
||||
if (profile == NULL)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "environment variable ITERM_PROFILE not set");
|
||||
return;
|
||||
}
|
||||
|
||||
NSError* error;
|
||||
NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.googlecode.iterm2.plist", instance->state.passwd->pw_dir];
|
||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
|
||||
error:&error];
|
||||
if(error)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, [error localizedDescription].UTF8String);
|
||||
return;
|
||||
}
|
||||
|
||||
for(NSDictionary* bookmark in [dict valueForKey:@"New Bookmarks"])
|
||||
{
|
||||
if(![[bookmark valueForKey:@"Name"] isEqualToString:@(profile)])
|
||||
continue;
|
||||
|
||||
NSString* normalFont = [bookmark valueForKey:@"Normal Font"];
|
||||
if(!normalFont)
|
||||
{
|
||||
ffStrbufAppendF(&terminalFont->error, "`Normal Font` key in profile `%s` doesn't exist", profile);
|
||||
return;
|
||||
}
|
||||
ffFontInitWithSpace(&terminalFont->font, normalFont.UTF8String);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufAppendF(&terminalFont->error, "find profile `%s` bookmark failed", profile);
|
||||
}
|
||||
|
||||
static void detectAppleTerminal(FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FFstrbuf fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
ffOsascript("tell application \"Terminal\" to font name of window frontmost", &fontName);
|
||||
|
||||
if(fontName.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "executing osascript failed");
|
||||
ffStrbufDestroy(&fontName);
|
||||
return;
|
||||
}
|
||||
|
||||
FFstrbuf fontSize;
|
||||
ffStrbufInit(&fontSize);
|
||||
ffOsascript("tell application \"Terminal\" to font size of window frontmost", &fontSize);
|
||||
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||
|
||||
ffStrbufDestroy(&fontName);
|
||||
ffStrbufDestroy(&fontSize);
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "iterm.app") == 0)
|
||||
detectIterm2(instance, terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Apple_Terminal") == 0)
|
||||
detectAppleTerminal(terminalFont);
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
#include "terminalfont.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
#include "detection/terminalshell.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
static const char* getSystemMonospaceFont(const FFinstance* instance)
|
||||
{
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0)
|
||||
{
|
||||
const char* systemMonospaceFont = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(systemMonospaceFont))
|
||||
return systemMonospaceFont;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0)
|
||||
{
|
||||
const char* systemMonospaceFont = ffSettingsGet(instance, "/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(systemMonospaceFont))
|
||||
return systemMonospaceFont;
|
||||
}
|
||||
|
||||
return ffSettingsGet(instance, "/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
}
|
||||
|
||||
static void detectFromGSettings(const FFinstance* instance, char* profilePath, char* profileList, char* profile, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
const char* defaultProfile = ffSettingsGetGSettings(instance, profileList, NULL, "default", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(!ffStrSet(defaultProfile))
|
||||
{
|
||||
ffStrbufAppendF(&terminalFont->error, "Could not get default profile from gsettings: %s", profileList);
|
||||
return;
|
||||
}
|
||||
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
ffStrbufAppendS(&path, profilePath);
|
||||
ffStrbufAppendS(&path, defaultProfile);
|
||||
ffStrbufAppendC(&path, '/');
|
||||
|
||||
if(!ffSettingsGetGSettings(instance, profile, path.chars, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue)
|
||||
{
|
||||
const char* fontName = ffSettingsGetGSettings(instance, profile, path.chars, "font", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(fontName))
|
||||
ffFontInitPango(&terminalFont->font, fontName);
|
||||
else
|
||||
ffStrbufAppendF(&terminalFont->error, "Couldn't get terminal font from GSettings (%s::%s::font)", profile, path.chars);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* fontName = getSystemMonospaceFont(instance);
|
||||
if(ffStrSet(fontName))
|
||||
ffFontInitPango(&terminalFont->font, fontName);
|
||||
else
|
||||
ffStrbufAppendS(&terminalFont->error, "Could't get system monospace font name from GSettings / DConf");
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
static void detectFromConfigFile(const FFinstance* instance, const char* configFile, const char* start, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FFstrbuf fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
ffParsePropFileConfig(instance, configFile, start, &fontName);
|
||||
|
||||
if(fontName.length == 0)
|
||||
ffStrbufAppendF(&terminalFont->error, "Couldn't find %s in .config/%s", start, configFile);
|
||||
else
|
||||
ffFontInitPango(&terminalFont->font, fontName.chars);
|
||||
|
||||
ffStrbufDestroy(&fontName);
|
||||
}
|
||||
|
||||
static void detectKonsole(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FFstrbuf profile;
|
||||
ffStrbufInit(&profile);
|
||||
ffParsePropFileConfig(instance, "konsolerc", "DefaultProfile =", &profile);
|
||||
|
||||
if(profile.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "Couldn't find \"DefaultProfile=%[^\\n]\" in \".config/konsolerc\"");
|
||||
ffStrbufDestroy(&profile);
|
||||
return;
|
||||
}
|
||||
|
||||
FFstrbuf profilePath;
|
||||
ffStrbufInitA(&profilePath, 64);
|
||||
ffStrbufAppendS(&profilePath, ".local/share/konsole/");
|
||||
ffStrbufAppend(&profilePath, &profile);
|
||||
|
||||
ffStrbufDestroy(&profile);
|
||||
|
||||
FFstrbuf fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
ffParsePropFileHome(instance, profilePath.chars, "Font =", &fontName);
|
||||
|
||||
if(fontName.length == 0)
|
||||
ffStrbufAppendF(&terminalFont->error, "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath.chars);
|
||||
else
|
||||
ffFontInitQt(&terminalFont->font, fontName.chars);
|
||||
|
||||
ffStrbufDestroy(&fontName);
|
||||
ffStrbufDestroy(&profilePath);
|
||||
}
|
||||
|
||||
static void detectXFCETerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FFstrbuf useSysFont;
|
||||
ffStrbufInit(&useSysFont);
|
||||
|
||||
FFstrbuf fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
|
||||
ffParsePropFileConfigValues(instance, "xfce4/terminal/terminalrc", 2, (FFpropquery[]) {
|
||||
{"FontUseSystem = ", &useSysFont},
|
||||
{"FontName = ", &fontName}
|
||||
});
|
||||
|
||||
if(useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0)
|
||||
{
|
||||
if(fontName.length == 0)
|
||||
ffStrbufAppendS(&terminalFont->error, "Couldn't find FontName in .config/xfce4/terminal/terminalrc");
|
||||
else
|
||||
ffFontInitPango(&terminalFont->font, fontName.chars);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* systemFontName = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/MonospaceFontName", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(systemFontName))
|
||||
ffFontInitPango(&terminalFont->font, systemFontName);
|
||||
else
|
||||
ffStrbufAppendS(&terminalFont->error, "Couldn't find xsettings::/Gtk/MonospaceFontName in XFConf");
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&fontName);
|
||||
ffStrbufDestroy(&useSysFont);
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_LIBCJSON
|
||||
|
||||
#include "common/library.h"
|
||||
#include "common/processing.h"
|
||||
|
||||
#include <cjson/cJSON.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct CJSONData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(cJSON_Parse)
|
||||
FF_LIBRARY_SYMBOL(cJSON_IsObject)
|
||||
FF_LIBRARY_SYMBOL(cJSON_GetObjectItemCaseSensitive)
|
||||
FF_LIBRARY_SYMBOL(cJSON_IsString)
|
||||
FF_LIBRARY_SYMBOL(cJSON_GetStringValue)
|
||||
FF_LIBRARY_SYMBOL(cJSON_IsNumber)
|
||||
FF_LIBRARY_SYMBOL(cJSON_GetNumberValue)
|
||||
FF_LIBRARY_SYMBOL(cJSON_IsArray)
|
||||
FF_LIBRARY_SYMBOL(cJSON_Delete)
|
||||
} CJSONData;
|
||||
|
||||
static const char* detectWTProfile(CJSONData* cjsonData, cJSON* profile, FFstrbuf* name, int* size)
|
||||
{
|
||||
if(!cjsonData->ffcJSON_IsObject(profile))
|
||||
return "cJSON_IsObject(profile) returns false";
|
||||
|
||||
cJSON* font = cjsonData->ffcJSON_GetObjectItemCaseSensitive(profile, "font");
|
||||
if(!cjsonData->ffcJSON_IsObject(font))
|
||||
return "cJSON_IsObject(font) returns false";
|
||||
|
||||
if(name->length == 0)
|
||||
{
|
||||
cJSON* pface = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "face");
|
||||
if(cjsonData->ffcJSON_IsString(pface))
|
||||
ffStrbufAppendS(name, cjsonData->ffcJSON_GetStringValue(pface));
|
||||
}
|
||||
if(*size < 0)
|
||||
{
|
||||
cJSON* psize = cjsonData->ffcJSON_GetObjectItemCaseSensitive(font, "size");
|
||||
if(cjsonData->ffcJSON_IsNumber(psize))
|
||||
*size = (int)cjsonData->ffcJSON_GetNumberValue(psize);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectFromWTImpl(const FFinstance* instance, FFstrbuf* content, FFstrbuf* name, int* size)
|
||||
{
|
||||
CJSONData cjsonData;
|
||||
|
||||
FF_LIBRARY_LOAD(libcjson, &instance->config.libcJSON, "dlopen libcjson failed", "libcjson"FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Parse)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsObject)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetObjectItemCaseSensitive)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsString)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetStringValue)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsNumber)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_GetNumberValue)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_IsArray)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libcjson, cjsonData, cJSON_Delete)
|
||||
|
||||
const char* error = NULL;
|
||||
|
||||
cJSON* root = cjsonData.ffcJSON_Parse(content->chars);
|
||||
if(!cjsonData.ffcJSON_IsObject(root))
|
||||
{
|
||||
error = "cJSON_Parse() failed";
|
||||
goto exit;
|
||||
}
|
||||
|
||||
cJSON* profiles = cjsonData.ffcJSON_GetObjectItemCaseSensitive(root, "profiles");
|
||||
if(!cjsonData.ffcJSON_IsObject(profiles))
|
||||
{
|
||||
error = "cJSON_GetObjectItemCaseSensitive(root, \"profiles\") failed";
|
||||
goto exit;
|
||||
}
|
||||
|
||||
FFstrbuf wtProfileId;
|
||||
ffStrbufInitS(&wtProfileId, getenv("WT_PROFILE_ID"));
|
||||
ffStrbufTrim(&wtProfileId, '\'');
|
||||
if(wtProfileId.length > 0)
|
||||
{
|
||||
cJSON* list = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "list");
|
||||
if(cjsonData.ffcJSON_IsArray(list))
|
||||
{
|
||||
cJSON* profile;
|
||||
cJSON_ArrayForEach(profile, list)
|
||||
{
|
||||
if(!cjsonData.ffcJSON_IsObject(profile))
|
||||
continue;
|
||||
cJSON* guid = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profile, "guid");
|
||||
if(!cjsonData.ffcJSON_IsString(guid))
|
||||
continue;
|
||||
if(ffStrbufCompS(&wtProfileId, cjsonData.ffcJSON_GetStringValue(guid)) == 0)
|
||||
{
|
||||
detectWTProfile(&cjsonData, profile, name, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ffStrbufDestroy(&wtProfileId);
|
||||
|
||||
cJSON* defaults = cjsonData.ffcJSON_GetObjectItemCaseSensitive(profiles, "defaults");
|
||||
detectWTProfile(&cjsonData, defaults, name, size);
|
||||
|
||||
if(name->length == 0)
|
||||
ffStrbufSetS(name, "Cascadia Mono");
|
||||
if(*size < 0)
|
||||
*size = 12;
|
||||
|
||||
exit:
|
||||
cjsonData.ffcJSON_Delete(root);
|
||||
dlclose(libcjson);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
//https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file
|
||||
FFstrbuf json;
|
||||
ffStrbufInit(&json);
|
||||
const char* error;
|
||||
error = ffProcessAppendStdOut(&json, (char* const[]) {
|
||||
"cmd.exe",
|
||||
"/c",
|
||||
//print the file content directly, so we don't need to handle the difference of Windows and POSIX path
|
||||
"if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json "
|
||||
"( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json ) "
|
||||
"else if exist %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json "
|
||||
"( type %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\\LocalState\\settings.json ) "
|
||||
"else if exist \"%LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json\" "
|
||||
"( type %LOCALAPPDATA%\\Microsoft\\Windows Terminal\\settings.json ) "
|
||||
"else ( call )",
|
||||
NULL
|
||||
});
|
||||
if(error)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, error);
|
||||
ffStrbufDestroy(&json);
|
||||
return;
|
||||
}
|
||||
ffStrbufTrimRight(&json, '\n');
|
||||
if(json.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "Cannot find file \"settings.json\"");
|
||||
ffStrbufDestroy(&json);
|
||||
return;
|
||||
}
|
||||
|
||||
FFstrbuf name;
|
||||
ffStrbufInit(&name);
|
||||
int size = -1;
|
||||
detectFromWTImpl(instance, &json, &name, &size);
|
||||
ffStrbufDestroy(&json);
|
||||
|
||||
char sizeStr[16];
|
||||
snprintf(sizeStr, sizeof(sizeStr), "%d", size);
|
||||
ffFontInitValues(&terminalFont->font, name.chars, sizeStr);
|
||||
|
||||
ffStrbufDestroy(&name);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void detectFromWindowsTeriminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
FF_UNUSED(instance, terminalFont);
|
||||
ffStrbufAppendS(&terminalFont->error, "fastfetch is built without libcjson support");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0)
|
||||
detectKonsole(instance, terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "xfce4-terminal") == 0)
|
||||
detectXFCETerminal(instance, terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "lxterminal") == 0)
|
||||
detectFromConfigFile(instance, "lxterminal/lxterminal.conf", "fontname =", terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "tilix") == 0)
|
||||
detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "gnome-terminal-") == 0)
|
||||
detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", terminalFont);
|
||||
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0)
|
||||
detectFromWindowsTeriminal(instance, terminalFont);
|
||||
}
|
||||
@@ -21,6 +21,6 @@ typedef struct FFTerminalShellResult
|
||||
FFstrbuf userShellVersion;
|
||||
} FFTerminalShellResult;
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell(FFinstance* instance);
|
||||
const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
|
||||
+25
-20
@@ -10,6 +10,29 @@
|
||||
#define HOST_NAME_MAX 64
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
static void detectFQDN(FFTitleResult* title)
|
||||
{
|
||||
struct addrinfo hints = {0};
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
|
||||
struct addrinfo* info = NULL;
|
||||
|
||||
if(getaddrinfo(title->hostname.chars, "80", &hints, &info) == 0)
|
||||
{
|
||||
struct addrinfo* current = info;
|
||||
while(title->fqdn.length == 0 && current != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&title->fqdn, current->ai_canonname);
|
||||
current = current->ai_next;
|
||||
}
|
||||
|
||||
freeaddrinfo(info);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const FFTitleResult* ffDetectTitle(const FFinstance* instance)
|
||||
{
|
||||
static FFTitleResult result;
|
||||
@@ -31,27 +54,9 @@ const FFTitleResult* ffDetectTitle(const FFinstance* instance)
|
||||
ffStrbufAppendS(&result.hostname, instance->state.utsname.nodename);
|
||||
|
||||
ffStrbufInitA(&result.fqdn, HOST_NAME_MAX);
|
||||
|
||||
#ifndef __APPLE__
|
||||
struct addrinfo hints = {0};
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
|
||||
struct addrinfo* info = NULL;
|
||||
|
||||
if(getaddrinfo(result.hostname.chars, "80", &hints, &info) == 0)
|
||||
{
|
||||
struct addrinfo* current = info;
|
||||
while(result.fqdn.length == 0 && current != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&result.fqdn, current->ai_canonname);
|
||||
current = current->ai_next;
|
||||
}
|
||||
|
||||
freeaddrinfo(info);
|
||||
}
|
||||
#ifdef __linux
|
||||
detectFQDN(&result);
|
||||
#endif
|
||||
|
||||
if(result.fqdn.length == 0)
|
||||
ffStrbufAppend(&result.fqdn, &result.hostname);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user