Compare commits

..

157 Commits

Author SHA1 Message Date
Linus Dierheimer 8be4921bd0 Release 1.7.0 2022-09-06 18:59:03 +02:00
Linus Dierheimer b22bcba220 Don't use LC_CTYPE for locale detection 2022-09-06 09:17:26 -07:00
Linus Dierheimer 5ee7ea46e7 Better variable naming 2022-09-06 18:03:31 +02:00
Linus Dierheimer d93c934269 MacOS Resolution support 2022-09-06 08:04:45 -07:00
Linus Dierheimer 5c1ac33df2 MacOS WM & DE support 2022-09-06 06:52:50 -07:00
Linus Dierheimer 0b3bf3c273 Only build display server code on linux 2022-09-06 15:42:37 +02:00
Linus Dierheimer 7fd98829b0 Fix unused variable 2022-09-06 14:23:07 +02:00
Linus Dierheimer 282271a65a MacOS disk support 2022-09-06 05:19:21 -07:00
Linus Dierheimer 9ef4b82cb9 Refactor disk module 2022-09-06 13:24:57 +02:00
Linus Dierheimer 10973dd9d1 Better MacOS GPU support 2022-09-06 02:28:32 -07:00
Linus Dierheimer dfdffec1c9 MacOS GPU support 2022-09-05 13:41:05 -07:00
Linus Dierheimer 2283700a99 Refactor CMakeLists.txt 2022-09-05 19:56:00 +02:00
Linus Dierheimer 7b647e09da Only enable library features on linux by default 2022-09-05 18:30:30 +02:00
Linus Dierheimer 54cb74c999 Separate gpu detection and printing logic 2022-09-05 17:42:42 +02:00
Linus Dierheimer 0f70cb408f Updated presets 2022-09-05 16:11:35 +02:00
Linus Dierheimer c80b1761dd brew package support 2022-09-05 05:15:19 -07:00
Linus Dierheimer a1fde6f922 MacOS memory support 2022-09-05 02:46:53 -07:00
Linus Dierheimer 6a44515cf2 Separate memory detection and printing logic 2022-09-05 10:57:09 +02:00
Linus Dierheimer cfcc4c8375 MacOS cpu support 2022-09-04 14:12:04 -07:00
Linus Dierheimer ea60fd0a0d Separate cpu detection and printing logic 2022-09-04 22:20:12 +02:00
Linus Dierheimer a4e0275263 Update README.md 2022-09-04 18:07:15 +02:00
Linus Dierheimer 71779fa4b1 Basic MacOS support 2022-09-04 09:02:11 -07:00
Linus Dierheimer 475099696f MacOS logo 2022-09-04 16:32:45 +02:00
Linus Dierheimer 14670b6144 Always cast to right tv_usec type 2022-09-04 14:41:00 +02:00
Linus Dierheimer 327b1b142e guard get_nproc with FF_HAVE_SYSCONF_H 2022-09-04 14:37:57 +02:00
Linus Dierheimer 9d106c6672 Enable build on MacOS
Note that this commit just makes fastfetch compile, not work properly
2022-09-04 14:30:52 +02:00
Linus Dierheimer df0e13b198 Fix possible segfault 2022-09-04 13:56:14 +02:00
Linus Dierheimer 6d0675820e Fix build on Android 2022-09-04 13:36:56 +02:00
Linus Dierheimer 08b0bac2b9 Refactor os detection code 2022-09-04 13:33:18 +02:00
Linus Dierheimer d387800bda Separate host detection and printing logic 2022-09-04 12:43:30 +02:00
Linus Dierheimer 542ad5eab6 Small fixes to gpu code 2022-09-03 10:53:30 +02:00
Linus Dierheimer 99f42d0953 Fix build with old libpci versions 2022-09-01 17:22:35 +02:00
Linus Dierheimer 3b316bdd3f Refactor pci code 2022-09-01 17:14:50 +02:00
Linus Dierheimer f011f8851e recache between commits too 2022-09-01 17:14:10 +02:00
Linus Dierheimer 8f23a52f53 Fix typos 2022-08-30 19:46:36 +02:00
Linus Dierheimer 8f53d33f29 Fix --file option 2022-08-29 11:01:29 +02:00
Linus Dierheimer e6fa269f52 Update README.md 2022-08-29 09:24:03 +02:00
Linus Dierheimer ca4a327de4 Update README.md 2022-08-28 18:42:53 +02:00
Linus Dierheimer f4e777f3d2 Update README.md 2022-08-28 18:34:54 +02:00
Linus Dierheimer 136f73ea0b Updated screenshots 2022-08-28 17:39:01 +02:00
Linus Dierheimer 28270541e6 use pci_read_byte to support older libpci versions 2022-08-28 16:01:34 +02:00
Linus Dierheimer 8197eddea8 Much better AMD gpu names 2022-08-28 15:51:28 +02:00
Linus Dierheimer 23bccc4802 MSYS2 logo
#219
2022-08-27 16:15:31 +02:00
Linus Dierheimer 873c7d93b6 Fix ffStrSet 2022-08-27 12:22:03 +02:00
Linus Dierheimer f4ee8667b1 Binary prefix option 2022-08-26 16:02:04 +02:00
Linus Dierheimer 50d3d4cdf4 Merge pull request #220 from sirlucjan/patch-1
Add CachyOS small logo
2022-08-25 12:41:51 +02:00
Piotr Gorski df048035b5 Add CachyOS small logo
Signed-off-by: Piotr Gorski <lucjan.lucjanov@gmail.com>
2022-08-24 20:44:36 +02:00
Linus Dierheimer 952989c1e8 Show huge ram values in GiB
#218
2022-08-23 13:53:12 +02:00
Linus Dierheimer aa1237b0fd Simplified config file loading logic 2022-08-22 12:45:20 +02:00
Linus Dierheimer b87983c86b Fix parsing quoted values in config files 2022-08-22 12:14:08 +02:00
Linus Dierheimer 779dbab647 Release 1.6.4 2022-08-22 00:13:13 +02:00
Linus Dierheimer 47373998d5 replace gethostbyname with getaddrinfo
#217
2022-08-21 23:35:22 +02:00
Linus Dierheimer 11809e30b5 Parse config files faster 2022-08-21 21:08:11 +02:00
Linus Dierheimer 35253e085c Unified storage of --set and --set-keyless values 2022-08-20 18:17:00 +02:00
Linus Dierheimer 112e83b7c3 Provide apk count to package format string 2022-08-18 22:02:21 +02:00
Linus Dierheimer c74b34aa39 Merge pull request #216 from mxkrsv/apk-support
Add APK (Alpine Package Keeper) support
2022-08-18 21:56:20 +02:00
Maxim Karasev b2e0034c34 Add APK (Alpine Package Keeper) support 2022-08-18 22:28:40 +03:00
Linus Dierheimer e3cdf9d9fd Reset color after custom module 2022-08-18 11:45:44 +02:00
Linus Dierheimer 6cdb694e33 Do simple \ replacement in user strings 2022-08-18 11:36:30 +02:00
Linus Dierheimer 83016289e9 --set-keyless option 2022-08-18 10:44:21 +02:00
Linus Dierheimer f9562d7132 Merge pull request #214 from jonathanspw/master
add AlmaLinux logo
2022-08-17 09:19:38 +02:00
jonathanspw 2f66bc2c95 add AlmaLinux logo 2022-08-16 20:10:47 -05:00
Linus Dierheimer d7c848225c Update CHANGELOG.md 2022-08-12 21:52:29 +02:00
Linus Dierheimer 8404ae8e70 Merge pull request #212 from ceamac/bugs/install-presets
Fix installation of presets/ directory
2022-08-12 21:50:49 +02:00
Viorel d75f72c8fe Fix installation of presets/ directory 2022-08-12 22:35:31 +03:00
Linus Dierheimer 9fa00081e3 Release 1.6.2 2022-08-12 16:01:52 +02:00
Linus Dierheimer fca37b59c8 Print xbps package count once again
#209
2022-08-12 09:40:02 +02:00
Linus Dierheimer 2fe7476c67 Better xbps package count
#209
2022-08-07 19:42:16 +02:00
Linus Dierheimer 03cbd64d8a Merge pull request #208 from hervyqa/langitketujuh
Add LangitKetujuh Linux logo
2022-08-03 13:03:06 +02:00
Hervy Qurrotul Ainur Rozi f65aeed96f Add LangitKetujuh Linux logo 2022-08-03 16:46:14 +07:00
Linus Dierheimer b63f419cde Merge pull request #207 from draumaz/master
Add KISS Linux logo
2022-08-02 15:14:41 +02:00
draumaz 99aa2f7b45 swap order 2022-08-02 12:29:44 +00:00
draumaz b251c32c12 fix colors, update README 2022-08-02 12:24:15 +00:00
draumaz 034e23d7e3 Merge branch 'LinusDierheimer:master' into master 2022-08-02 05:13:30 -07:00
Linus Dierheimer bba912d42e Add missing include 2022-08-02 10:24:54 +02:00
draumaz 597652c35a one more backslash 2022-08-02 05:56:20 +00:00
draumaz 7f67846ad9 add KISS Linux logo 2022-08-02 05:51:15 +00:00
Linus Dierheimer bc2e292e22 Update issue templates 2022-07-31 17:44:07 +02:00
Linus Dierheimer 75dc228120 Update issue templates 2022-07-31 17:39:54 +02:00
Linus Dierheimer bc783f6efd Update issue templates 2022-07-31 17:33:03 +02:00
Linus Dierheimer 85e1d2b40c Add logo request template 2022-07-31 17:31:30 +02:00
Linus Dierheimer 3338189354 Rosa Linux logo 2022-07-31 17:22:03 +02:00
Linus Dierheimer d4c836fd25 Handle empty xdg env vars better 2022-07-30 23:30:46 +02:00
Linus Dierheimer 6787f1eba8 Merge branches 'master' and 'master' of github.com:LinusDierheimer/fastfetch 2022-07-27 21:56:42 +02:00
Linus Dierheimer eedc277bcf Respect target dir config during installation 2022-07-27 21:56:28 +02:00
Linus Dierheimer d4b32eaaec Merge pull request #205 from licy183/fix-android-header
Fix build error on Android
2022-07-27 19:31:29 +02:00
Linus Dierheimer 910f63f0ad Update changelog 2022-07-27 19:31:14 +02:00
Linus Dierheimer 9a0aa2ac72 Fix compilation issues
1) when building for android
2) when building without wayland
2022-07-27 19:28:55 +02:00
Chongyun Lee dce81055fe Release 1.6.1 2022-07-28 01:28:17 +08:00
Chongyun Lee 66a4fc1600 Fix build error on Android
host.c has an #elif, but actually #else is needed.
2022-07-27 22:50:11 +08:00
Linus Dierheimer 159a114bb7 Release 1.6.0
tag correctly
2022-07-26 22:38:40 +02:00
Linus Dierheimer ac08b46e71 Release 1.6.0
this time with correct packaging the second
2022-07-26 22:27:13 +02:00
Linus Dierheimer ceb92dafd7 Release 1.6.0
this time with correct packaging
2022-07-26 22:13:09 +02:00
Linus Dierheimer 31eeb6dd08 Release 1.6.0 2022-07-26 20:35:15 +02:00
Linus Dierheimer c021689a2b Better nix package sorting
#195
2022-07-26 19:15:00 +02:00
Linus Dierheimer 2ac2762c9f Print nix-default packages
#195
2022-07-26 19:03:15 +02:00
Linus Dierheimer 27dd097671 Improved Nix package detection
#195
2022-07-26 18:36:10 +02:00
Linus Dierheimer c7bf471e29 Refactor: move vulkan detection to own header 2022-07-26 18:18:14 +02:00
Linus Dierheimer 298bc10e5f Refactor: move media detection to own header 2022-07-26 18:15:45 +02:00
Linus Dierheimer 676485ef74 Refactor: move temps detection to own header 2022-07-26 18:13:12 +02:00
Linus Dierheimer fb6da20b0c Refactor: move date/time detection to own header 2022-07-26 18:09:25 +02:00
Linus Dierheimer 0c81d3e894 Refactor: move terminal/shell detection to own header 2022-07-26 18:06:30 +02:00
Linus Dierheimer 5c1aa20042 Refactor: move wm/de detection to own header 2022-07-26 17:56:42 +02:00
Linus Dierheimer 46a27c4e39 Refactor: move gtk detection to own header 2022-07-26 17:47:08 +02:00
Linus Dierheimer 128302596e Refactor: move qt detection to own header 2022-07-26 17:42:28 +02:00
Linus Dierheimer 7a15dee2be Refactor: move os detection to own header 2022-07-26 17:33:51 +02:00
Linus Dierheimer 000bd37f1d Refactor: move title detection to own header 2022-07-26 17:29:09 +02:00
Linus Dierheimer 707e0f930d Refactor: don't include FFvaluestore global 2022-07-25 19:54:33 +02:00
Linus Dierheimer 7676a313c5 Refactor: move threading functions to init 2022-07-25 15:01:11 +02:00
Linus Dierheimer 6e0d76a2fb Refactor: move networking functions to own header 2022-07-25 14:48:59 +02:00
Linus Dierheimer 4c7b7e4a4d Refactor: move processing functions to own header 2022-07-25 14:45:41 +02:00
Linus Dierheimer 4d34091573 Refactor: move format functions to own header 2022-07-25 14:26:08 +02:00
Linus Dierheimer c971e28aca Refactor: move setting functions to own header 2022-07-25 14:20:07 +02:00
Linus Dierheimer c41a29a5c1 Refactor: move parsing functions to own header 2022-07-25 13:59:19 +02:00
Linus Dierheimer 5c73125693 Refactor: move font functions to own header 2022-07-25 13:44:55 +02:00
Linus Dierheimer cea48474a1 Refactor: move caching functions to own header 2022-07-25 13:36:58 +02:00
Linus Dierheimer 536f914f3e Refactor: move printing functions to own header 2022-07-25 13:15:01 +02:00
Linus Dierheimer 778856dd57 Refactor: move property functions to own header 2022-07-25 12:24:23 +02:00
Linus Dierheimer 4a43144991 Refactor: move io functions to own header 2022-07-25 11:48:48 +02:00
Linus Dierheimer ac96cfc748 Refactor: move FFInitState to settings.c 2022-07-25 11:24:50 +02:00
Linus Dierheimer f18ffe3239 Refactor: move library functions and macros to own header 2022-07-25 11:20:38 +02:00
Linus Dierheimer 986bbeebb3 Don't segfault if invalid structure is given
#204
2022-07-25 11:00:41 +02:00
Linus Dierheimer b9d360af97 --title-fqdn option
#203
2022-07-22 19:36:00 +02:00
Linus Dierheimer ec1981c545 Use [QT] instead of [Plasma]
#198 #199
2022-07-22 17:18:36 +02:00
Linus Dierheimer f7e7d8e9f2 Update README.md 2022-07-22 13:42:26 +02:00
Linus Dierheimer ad9fc5845a GTK: Fix detection on XFCE DE
#198 #199
2022-07-22 12:23:35 +02:00
Linus Dierheimer a6b169f3e2 Disk: Print one decimal point if < 100GiB
#202
2022-07-22 11:47:20 +02:00
Linus Dierheimer 8aff9939bc GTK: prefer dconf over config files on certain DEs
#198 #199
2022-07-22 11:24:29 +02:00
Linus Dierheimer 0b8f51188b gh actions: configure correct path for packaging
the follow up
2022-07-21 22:58:38 +02:00
Linus Dierheimer 3c99a82619 gh actions: configure correct path for packaging 2022-07-21 22:55:47 +02:00
Linus Dierheimer d5f3ff1cfe Update README.md 2022-07-21 20:20:40 +02:00
Linus Dierheimer 011c033091 Update README.md 2022-07-21 20:18:34 +02:00
Linus Dierheimer 63bf22fb00 Load system config
#196
2022-07-21 14:37:13 +02:00
Linus Dierheimer f74973db65 Special NixOS OS output
#194
2022-07-21 11:33:19 +02:00
Linus Dierheimer 85656fd515 Fix Mutter detection
#200
2022-07-20 21:32:17 +02:00
Linus Dierheimer 23bf7a407b Fix alacritty term font size
#197
2022-07-20 20:56:02 +02:00
Linus Dierheimer e570cacbc9 Fix typos
#201
2022-07-20 20:44:16 +02:00
Linus Dierheimer a96f79795b Merge pull request #193 from Izorkin/update-nixos-logo
Update old nixos logo
2022-07-19 12:09:25 +02:00
Izorkin 2d51d935c8 update old nixos logo 2022-07-19 12:57:15 +03:00
Linus Dierheimer 9d395f7235 don't print GPU in WSL 2022-07-17 16:11:08 +02:00
Linus Dierheimer 5f16394916 Add alacritty to readme 2022-07-12 16:49:39 +02:00
Linus Dierheimer 6581c9d378 Merge pull request #191 from x-zvf/alacritty-term-support
[enhancement] Add best effort terminal font detection for alacritty.
2022-07-12 16:46:22 +02:00
Péter Bohner (xzvf) 67ac7eef59 buxfix: missing fontSize/fontName would overwrite the other 2022-07-12 16:43:21 +02:00
Péter Bohner (xzvf) b95e83e9e5 Use ffStrbufAppend instead of ffStrbugInitCopy 2022-07-12 16:41:20 +02:00
Péter Bohner (xzvf) e9d9b942fa Cleanup diff 2022-07-12 16:34:35 +02:00
Péter Bohner (xzvf) c95ad74ea2 Refactor to use ffFontInitCopy and detect font size
printAlacritty now usese ffFontInitCopy instead of ffFontInitPango
and also detects font size.
2022-07-12 16:31:19 +02:00
Péter Bohner (xzvf) 85b0be5213 Add best effort terminal font detection for alacritty.
Alacritty's config files are technically YML files, so
simply looking for a prop value "family:" may break some of the time,
but is in fact better than what neofetch does and much easier
to implement then writing a YML parser :)
2022-07-12 14:38:06 +02:00
Linus Dierheimer da671d6cfe Start cleaning up of config struct 2022-07-10 18:28:17 +02:00
Linus Dierheimer 18af9ab902 Wayland: don't destroy proxies our self 2022-07-08 11:48:43 +02:00
Linus Dierheimer 558fbc20e2 Don't detect guake-wrapped as terminal 2022-07-08 11:24:11 +02:00
Linus Dierheimer d9bbbd4fa8 Merge pull request #189 from x-zvf/alacritty-term-support
Fix memory leak in ffParsePropFileValues
2022-07-08 10:46:11 +02:00
Péter Bohner (xzvf) 292a809703 ffParsePropValues: Hoisted fopen call to simplify error handling 2022-07-08 09:09:59 +02:00
Péter Bohner (xzvf) fa13826043 Revert "Coalesce cleanup in ffParsePropFileValues"
This reverts commit 7bc85b2397.
2022-07-08 09:05:00 +02:00
Péter Bohner (xzvf) 7bc85b2397 Coalesce cleanup in ffParsePropFileValues 2022-07-07 15:19:56 +02:00
Péter Bohner (xzvf) 1863d8377a Fix memory leak in ffParseProfFileValues, if more than 4 queries are passed (unsetValues is on the heap) and the file
is not found.
2022-07-07 14:35:59 +02:00
xzvf f9e17f44b1 Merge branch 'LinusDierheimer:master' into master 2022-07-04 20:10:01 +02:00
xzvf fa9b38eb2d Merge pull request #1 from LinusDierheimer/master
build temps file
2022-06-16 12:54:28 +02:00
155 changed files with 3920 additions and 2229 deletions
-1
View File
@@ -41,4 +41,3 @@ Output of `fastfetch --list-features`:
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
If this isn't possible (or too much work) for you, post the output of `fastfetch --show-errors --recache --multithreading false --disable-linewrap false`.
-->
+18
View File
@@ -0,0 +1,18 @@
---
name: Logo request
about: Request a new logo
title: ''
labels: logo request
assignees: ''
---
# OS
```
paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
```
# Ascii
```
paste ascii art here. If you leave this empty, i will try to find the logo myself.
```
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
- name: configure project
# We reuse the build binary only for the releases.
# We set tweak version to off, because it is wrong, as git tag will happen after this step. Releases don't have a tweak, so this is ok.
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . -j$(nproc) --target package
+84
View File
@@ -0,0 +1,84 @@
# 1.7.0
This release brings support for MacOS!
The basics things are working, but it is far from feature parity with Linux.
I developed this in a VM, so bugs on real hardware are likely.
If you have a Mac and no idea what to do with your free time, i am very happy to accept pull requests / work on issues.
A lot of things were changed under the hood to make this possible, which should bring better performance and stability on all platforms.
Besides that, the following things have changed:
Features:
* The binary prefix used can now be configured, and is used consistently across all modules. Set `--binary-prefix` to `iec` (default), `si` or `jedec`.
* AMD GPUs now have a much better name, if the file `/usr/share/libdrm/amdgpu.ids` exists. For example my dedicated GPU, which was displayed as `AMD/ATI Radeon RX 5600 OEM/5600 XT / 5700/5700 XT`, is now `AMD Radeon RX 5600M`.
Logos:
* MacOS
* CachyOS small (@sirlucjan, #220)
* MSYS2 (#219)
Bugfixes:
* the `--file` option, which can be used to display the contents of a file as the logo, is now working again.
# 1.6.5
Fixes parsing quoted values in config files
# 1.6.4
Releasing this, so fedora can package fastfetch. Thanks to @jonathanspw for doing that!
Features:
* --set-keyless option (#215)
* Replace `\n`, `\t`, `\e` and `\\` in user provided strings, just like c would do it (#215)
* APK (Alpine Package Keeper) support (@mxkrsv, #216)
Logos:
* Alma Linux (@jonathanspw, #214)
Bugfixes:
* replace deprecated gethostbyname call with getaddrinfo (#217)
# 1.6.3
Fixes installing presets in their own directory (@ceamac, #212)
# 1.6.2
Releasing this, so void linux can package fastfetch.
Logos:
* Rosa linux (#206)
* KISS linux (@draumaz, #207)
* LangitKetujuh (@hervyqa, #208)
Bugfixes:
* Using musl as libc does work now (#210)
* XBPS packages are once again printed (#209)
* configured target dirs are applied to install directories too
* empty XDG_* env vars don't cause a crash anymore
# 1.6.1
Fixes build on android (#205)
# 1.6.0
Features:
* Detect QT on more DEs than just KDE Plasma. The [Plasma] category was therefore renamed to [QT]
* Alacritty font detection
* Load `/etc/fastfetch/config.conf` before user config
* Disk: print one decimal point if size < 100GB
* `--title-fqdn` option, to print fully qualified domain name instead of host name in title
Logos:
* updated old NixOS logo
Bugfixes:
* Correctly detect GTK on DEs that store their settings in dconf
* Correctly detect NixOS packages
* Mutter WM detected once again
* Show full NixOS version in OS output
* Don't segfault if an invalid structure is given
* WSL doesn't output GPU anymore, as the name is always meaningless
+150 -274
View File
@@ -1,38 +1,52 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs
project(fastfetch
VERSION 1.5.6
VERSION 1.7.0
LANGUAGES C
)
###################
# Target Platform #
###################
if(APPLE OR ANDROID)
set(LINUX FALSE CACHE BOOL "...") # Linux true means we have full linux userland, not just the kernel
elseif(UNIX)
set(LINUX TRUE CACHE BOOL "...")
else()
message(FATAL_ERROR "Unsupported platform")
endif()
#####################
# Configure options #
#####################
OPTION(ENABLE_LIBPCI "Enable libpci" ON)
OPTION(ENABLE_VULKAN "Enable vulkan" ON)
OPTION(ENABLE_WAYLAND "Enable wayland-client" ON)
OPTION(ENABLE_XCB_RANDR "Enable xcb-randr" ON)
OPTION(ENABLE_XCB "Enable xcb" ON)
OPTION(ENABLE_XRANDR "Enable xrandr" ON)
OPTION(ENABLE_X11 "Enable x11" ON)
OPTION(ENABLE_GIO "Enable gio-2.0" ON)
OPTION(ENABLE_DCONF "Enable dconf" ON)
OPTION(ENABLE_DBUS "Enable dbus-1" ON)
OPTION(ENABLE_XFCONF "Enable libxfconf-0" ON)
OPTION(ENABLE_SQLITE3 "Enable sqlite3" ON)
OPTION(ENABLE_RPM "Enable rpm" ON)
OPTION(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON)
OPTION(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON)
OPTION(ENABLE_ZLIB "Enable zlib" ON)
OPTION(ENABLE_CHAFA "Enable chafa" ON)
OPTION(ENABLE_EGL "Enable egl" ON)
OPTION(ENABLE_GLX "Enable glx" ON)
OPTION(ENABLE_OSMESA "Enable osmesa" ON)
OPTION(ENABLE_OPENCL "Enable opencl" ON)
include(CMakeDependentOption)
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
cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX" 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_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_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_CHAFA" 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)
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
#############################
# Compile time dependencies #
@@ -43,6 +57,8 @@ find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED)
include(CheckIncludeFile)
####################
# Compiler options #
####################
@@ -81,10 +97,12 @@ if(NOT TARGET_DIR_USR)
endif()
if(NOT TARGET_DIR_HOME)
if(NOT ANDROID)
set(TARGET_DIR_HOME "${TARGET_DIR_ROOT}/home")
else()
if(APPLE)
set(TARGET_DIR_HOME "${TARGET_DIR_ROOT}/Users")
elseif(ANDROID)
set(TARGET_DIR_HOME "/data/data/com.termux/files/home")
else()
set(TARGET_DIR_HOME "${TARGET_DIR_ROOT}/home")
endif()
endif()
@@ -115,7 +133,8 @@ function(fastfetch_load_text FILENAME OUTVAR)
endfunction(fastfetch_load_text)
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
fastfetch_load_text(src/data/config.txt DATATEXT_CONFIG)
fastfetch_load_text(src/data/config_system.txt DATATEXT_CONFIG_SYSTEM)
fastfetch_load_text(src/data/config_user.txt DATATEXT_CONFIG_USER)
fastfetch_load_text(src/data/modules.txt DATATEXT_MODULES)
fastfetch_load_text(src/data/help.txt DATATEXT_HELP)
fastfetch_load_text(src/data/help_color.txt DATATEXT_HELP_COLOR)
@@ -132,12 +151,11 @@ configure_file(src/fastfetch_config.h.in fastfetch_config.h)
# libfastfetch target #
#######################
add_library(libfastfetch OBJECT
set(LIBFASTFETCH_SRC
src/util/FFstrbuf.c
src/util/FFlist.c
src/util/FFvaluestore.c
src/common/init.c
src/common/threading.c
src/common/io.c
src/common/printing.c
src/common/caching.c
@@ -154,19 +172,20 @@ add_library(libfastfetch OBJECT
src/logo/image/image.c
src/logo/image/im7.c
src/logo/image/im6.c
src/detection/os.c
src/detection/plasma.c
src/detection/qt.c
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/displayserver/displayServer.c
src/detection/displayserver/wayland.c
src/detection/displayserver/xcb.c
src/detection/displayserver/xlib.c
src/detection/displayserver/wmde.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/displayserver/displayserver.c
src/modules/break.c
src/modules/custom.c
src/modules/title.c
@@ -208,245 +227,91 @@ add_library(libfastfetch OBJECT
src/modules/opencl.c
)
if(ENABLE_LIBPCI)
pkg_check_modules(LIBPCI libpci)
if(LIBPCI_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBPCI=1)
else()
message(WARNING "Package libpci not found. Building without support.")
endif()
if(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
)
elseif(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()
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/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
)
endif()
if(ENABLE_VULKAN)
pkg_check_modules(VULKAN vulkan)
if(VULKAN_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_VULKAN=1)
else()
message(WARNING "Package vulkan not found. Building without support.")
endif()
add_library(libfastfetch OBJECT
${LIBFASTFETCH_SRC}
)
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()
if(ENABLE_WAYLAND)
pkg_check_modules (WAYLAND wayland-client)
if(WAYLAND_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WAYLAND=1)
else()
message(WARNING "Package wayland-client not found. Building without support.")
endif()
endif()
if(ENABLE_XCB_RANDR)
pkg_check_modules(XCB_RANDR xcb-randr)
if(XCB_RANDR_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XCB_RANDR=1)
else()
message(WARNING "Package xcb-randr not found. Building without support.")
endif()
endif()
if(ENABLE_XCB)
pkg_check_modules (XCB xcb)
if(XCB_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XCB=1)
else()
message(WARNING "Package xcb not found. Building without support.")
endif()
endif()
if(ENABLE_XRANDR)
pkg_check_modules(XRANDR xrandr)
if(XRANDR_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XRANDR=1)
else()
message(WARNING "Package xrandr not found. Building without support.")
endif()
endif()
if(ENABLE_X11)
pkg_check_modules(X11 x11)
if(X11_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_X11=1)
else()
message(WARNING "Package x11 not found. Building without support.")
endif()
endif()
if(ENABLE_GIO)
pkg_check_modules(GIO gio-2.0)
if(GIO_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_GIO=1)
else()
message(WARNING "Package gio-2.0 not found. Building without support.")
endif()
endif()
if(ENABLE_DCONF)
pkg_check_modules(DCONF dconf)
if(DCONF_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_DCONF=1)
else()
message(WARNING "Package dconf not found. Building without support.")
endif()
endif()
if(ENABLE_DBUS)
pkg_check_modules(DBUS dbus-1)
if(DBUS_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_DBUS=1)
else()
message(WARNING "Package dbus-1 not found. Building without support.")
endif()
endif()
if(ENABLE_XFCONF)
pkg_check_modules(XFCONF libxfconf-0)
if(XFCONF_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XFCONF=1)
else()
message(WARNING "Package libxfconf-0 not found. Building without support.")
endif()
endif()
if(ENABLE_SQLITE3)
pkg_check_modules(SQLITE3 sqlite3)
if(SQLITE3_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_SQLITE3=1)
else()
message(WARNING "Package sqlite3 not found. Building without support.")
endif()
endif()
if(ENABLE_RPM)
pkg_check_modules(RPM rpm)
if(RPM_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_RPM=1)
else()
message(WARNING "Package rpm not found. Building without support.")
endif()
endif()
if(ENABLE_IMAGEMAGICK7)
pkg_check_modules(IMAGEMAGICK7 MagickCore-7.Q16HDRI)
if(NOT IMAGEMAGICK7_FOUND)
pkg_check_modules(IMAGEMAGICK7 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc)
endif()
if(NOT IMAGEMAGICK7_FOUND)
pkg_check_modules(IMAGEMAGICK7 MagickCore-7.Q16)
endif()
if(NOT IMAGEMAGICK7_FOUND)
pkg_check_modules(IMAGEMAGICK7 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc)
function(ff_check_lib VARNAME)
if(NOT ENABLE_${VARNAME})
return()
endif()
if(IMAGEMAGICK7_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_IMAGEMAGICK7=1)
else()
message(WARNING "Package MagickCore-7.Q16HDRI or MagickCore-7.Q16 not found. Building without support.")
endif()
endif()
if(ENABLE_IMAGEMAGICK6)
pkg_check_modules(IMAGEMAGICK6 MagickCore-6.Q16HDRI)
if(NOT IMAGEMAGICK6_FOUND)
pkg_check_modules(IMAGEMAGICK6 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc)
endif()
if(NOT IMAGEMAGICK6_FOUND)
pkg_check_modules(IMAGEMAGICK6 MagickCore-6.Q16)
endif()
if(NOT IMAGEMAGICK6_FOUND)
pkg_check_modules(IMAGEMAGICK6 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc)
endif()
if(IMAGEMAGICK6_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_IMAGEMAGICK6=1)
else()
message(WARNING "Package MagickCore-6.Q16HDRI or MagickCore-6.Q16 not found. Building without support.")
endif()
endif()
if(ENABLE_ZLIB)
pkg_check_modules(ZLIB zlib)
if(ZLIB_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_ZLIB=1)
else()
message(WARNING "Package zlib not found. Building without support")
endif()
endif()
if(ENABLE_CHAFA)
if(IMAGEMAGICK6_FOUND OR IMAGEMAGICK7_FOUND)
pkg_check_modules(CHAFA chafa>=1.10)
if(CHAFA_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_CHAFA=1)
else()
message(WARNING "Package chafa>=1.10 not found. Building without support.")
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})
return()
endif()
else()
message(WARNING "Chafa not enabled, because neither ImageMagick6 nor ImageMagick7 were found. Building without support.")
endif()
endif()
endforeach()
if(ENABLE_EGL)
pkg_check_modules(EGL egl)
if(EGL_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EGL=1)
else()
message(WARNING "Package egl not found. Building without support.")
endif()
endif()
message(WARNING "Package ${ARGV1} not found, building without support.")
endfunction()
if(ENABLE_GLX)
pkg_check_modules(GLX glx)
if(GLX_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_GLX=1)
else()
message(WARNING "Package glx not found. Building without support.")
endif()
endif()
if(ENABLE_OSMESA)
pkg_check_modules(OSMESA osmesa)
if(OSMESA_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_OSMESA=1)
else()
message(WARNING "Package osmesa not found. Building without support.")
endif()
endif()
if(ENABLE_OPENCL)
pkg_check_modules(OPENCL OpenCL)
if(OPENCL_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_OPENCL=1)
else()
message(WARNING "Package opencl not found. Building without support.")
endif()
endif()
ff_check_lib(LIBPCI libpci)
ff_check_lib(VULKAN vulkan)
ff_check_lib(WAYLAND wayland-client)
ff_check_lib(XCB_RANDR xcb-randr)
ff_check_lib(XCB xcb)
ff_check_lib(XRANDR xrandr)
ff_check_lib(X11 x11)
ff_check_lib(GIO gio-2.0)
ff_check_lib(DCONF dconf)
ff_check_lib(DBUS dbus-1)
ff_check_lib(XFCONF libxfconf-0)
ff_check_lib(SQLITE3 sqlite3)
ff_check_lib(RPM rpm)
ff_check_lib(IMAGEMAGICK7 MagickCore-7.Q16HDRI MagickCore-7.Q16 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc)
ff_check_lib(IMAGEMAGICK6 MagickCore-6.Q16HDRI MagickCore-6.Q16 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc)
ff_check_lib(ZLIB zlib)
ff_check_lib(CHAFA chafa>=1.10)
ff_check_lib(EGL egl)
ff_check_lib(GLX glx)
ff_check_lib(OSMESA osmesa)
ff_check_lib(OPENCL OpenCL)
target_include_directories(libfastfetch
PUBLIC ${PROJECT_BINARY_DIR}
PUBLIC ${PROJECT_SOURCE_DIR}/src
PRIVATE ${LIBPCI_INCLUDE_DIRS}
PRIVATE ${VULKAN_INCLUDE_DIRS}
PRIVATE ${WAYLAND_INCLUDE_DIRS}
PRIVATE ${XCB_RANDR_INCLUDE_DIRS}
PRIVATE ${XCB_INCLUDE_DIRS}
PRIVATE ${XRANDR_INCLUDE_DIRS}
PRIVATE ${X11_INCLUDE_DIRS}
PRIVATE ${GIO_INCLUDE_DIRS}
PRIVATE ${DCONF_INCLUDE_DIRS}
PRIVATE ${DBUS_INCLUDE_DIRS}
PRIVATE ${XFCONF_INCLUDE_DIRS}
PRIVATE ${SQLITE3_INCLUDE_DIRS}
PRIVATE ${RPM_INCLUDE_DIRS}
PRIVATE ${IMAGEMAGICK7_INCLUDE_DIRS}
PRIVATE ${IMAGEMAGICK6_INCLUDE_DIRS}
PRIVATE ${ZLIB_INCLUDE_DIRS}
PRIVATE ${CHAFA_INCLUDE_DIRS}
PRIVATE ${VULKAN_INCLUDE_DIRS}
PRIVATE ${EGL_INCLUDE_DIRS}
PRIVATE ${GLX_INCLUDE_DIRS}
PRIVATE ${OSMESA_INCLUDE_DIRS}
PRIVATE ${OPENCL_INCLUDE_DIRS}
)
target_link_libraries(libfastfetch
@@ -492,32 +357,42 @@ 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")
endif()
include(GNUInstallDirs)
install(
TARGETS fastfetch
DESTINATION ${CMAKE_INSTALL_BINDIR}
TARGETS fastfetch flashfetch
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
install(
TARGETS flashfetch
DESTINATION ${CMAKE_INSTALL_BINDIR}
FILES "${CMAKE_SOURCE_DIR}/src/data/config_system.txt"
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/${CMAKE_PROJECT_NAME}"
RENAME "config.conf"
)
install(
FILES completions/bash
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions
RENAME ${CMAKE_PROJECT_NAME}
FILES "${CMAKE_SOURCE_DIR}/completions/bash"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions"
RENAME "${CMAKE_PROJECT_NAME}"
)
install(
DIRECTORY presets
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}
DIRECTORY "${CMAKE_SOURCE_DIR}/presets"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}"
)
install(
FILES ./LICENSE
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/licenses/${CMAKE_PROJECT_NAME}
FILES "${CMAKE_SOURCE_DIR}/LICENSE"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${CMAKE_PROJECT_NAME}"
)
##################
@@ -525,6 +400,7 @@ install(
##################
set(CPACK_GENERATOR "DEB;RPM;TGZ;ZIP")
set(CPACK_SET_DESTDIR ON)
set(CPACK_PACKAGE_CONTACT "Linus Dierheimer <Linus@Dierheimer.de>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Neofetch clone written in C")
+18 -15
View File
@@ -1,9 +1,14 @@
# fastfetch
# <center> Fastfetch </center>
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 c to achieve much better performance, in return only Linux and Android are supported. It also uses mechanisms like multithreading and caching to finish as fast as possible.
The output on my personal machine with default configurations looks like this:
<img src="screenshots/example.png" alt="example output" width="100%"/>
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.
<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" />
<img src="screenshots/example4.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" />
<img src="screenshots/example2.png" width="48%" align="top" />
<img src="screenshots/example3.png" width="48%" align="top" />
<img src="screenshots/example5.png" height="15%" align="top" />
## Customization
@@ -11,8 +16,8 @@ With customization and speed being two competing goals, this project actually bu
The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `~/.config/fastfetch/config.conf`. To view the available options run `fastfetch --help`.
The second executable being built is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c).
At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference.
There are some presets defined for fastfech in [`presets`](presets), you can can load them with `--load-config`. They may also serve as a good example for format arguments.
There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config <filename>`. They may also serve as a good example for format arguments.
## Dependencies
@@ -45,12 +50,12 @@ All categories not listed here should work without needing a specific implementa
##### 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, Disk, Battery, Player, Song, 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, Disk, Battery, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom
```
##### Logos
```
Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Debian, Devuan, Deepin, Endeavour, Fedora, Garuda, Gentoo, KDE Neon, Kubuntu, Linux, Manjaro, Mint, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Ubuntu, Void, Zorin
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, 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.
@@ -60,7 +65,7 @@ Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Debian, Devuan, De
##### Package managers
```
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, brew
```
##### WM themes
@@ -75,7 +80,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt
##### Terminal fonts
```
konsole, gnome-terminal-server, tilix, xfce4-terminal, lxterminal, TTY
konsole, gnome-terminal-server, tilix, xfce4-terminal, alacritty, lxterminal, TTY
```
## Building
@@ -98,10 +103,8 @@ If pkg-config fails to find the headers for a library listed in [dependencies](#
### Manual
Build: Follow the [build instructions](#building).
* Create DEB / RPM: Run `cmake --build . --target package`.
* Install directly: Run `sudo cmake --install . --prefix /usr/local`
* DEB / RPM package: `cmake --build . --target package`
* Install directly: `cmake --install . --prefix /usr/local`
## FAQ
+5 -1
View File
@@ -108,7 +108,8 @@ __fastfetch_completion()
"--list-presets"
"--list-features"
"--print-logos"
"--print-config"
"--print-config-system"
"--print-config-user"
"--print-structure"
)
@@ -132,6 +133,7 @@ __fastfetch_completion()
"--localip-show-loop"
"--escape-bedrock"
"--pipe"
"--title-fqdn"
)
local FF_OPTIONS_STRING=(
@@ -154,7 +156,9 @@ __fastfetch_completion()
"-s"
"--structure"
"--set"
"--set-keyless"
"--gl"
"--binary-prefix"
"--os-format"
"--os-key"
"--host-format"
+1 -1
View File
@@ -1,4 +1,4 @@
--disable-linewrap false
--multithreading false
--show-errors true
--show-errors
--recache
+2 -1
View File
@@ -1,2 +1,3 @@
--load-config verbose
--load-config devinfo
--load-config all
--load-config verbose
+1
View File
@@ -0,0 +1 @@
# Load with --load-config examples/1
+24
View File
@@ -0,0 +1,24 @@
# Load with --load-config examples/2
# Note that you must replace the image path to an existing image to display it.
--kitty /home/linus/Bilder/Gentoo.png
--logo-width 28
--separator "  "
--set-keyless HardwareStart=┌───────── \e[1mHardware Information\e[0m ─────────┐
--set-keyless SoftwareStart=├───────── \e[1mSoftware Information\e[0m ─────────┤
--set-keyless InformationEnd=└────────────────────────────────────────┘
--set-keyless Colors= \e[38m \e[37m \e[36m \e[35m \e[34m \e[33m \e[32m \e[31m
--structure HardwareStart:Host:CPU:GPU:SoftwareStart:OS:Kernel:WM:Shell:Terminal:TerminalFont:Packages:InformationEnd:Colors
--host-key " "
--cpu-key " "
--gpu-key " ﬙"
--os-key " "
--kernel-key " "
--wm-key " "
--shell-key " "
--terminal-key " "
--terminal-font-key " "
--packages-key " "
+7
View File
@@ -0,0 +1,7 @@
# Load with --load-config example/3
--logo debian_small
--structure Vulkan:OpenGL:OpenCL:Memory:Disk:LocalIP
--binary-prefix si
--localip-show-loop false
--disk-folders /:/home:/boot:/efi
+7
View File
@@ -0,0 +1,7 @@
# Load with --load-config examples/4
--color blue
--logo arch_small
--logo-padding-right 1
--separator "  "
--structure Date:Time:Break:Player:Media
+12
View File
@@ -0,0 +1,12 @@
# Load with --load-config examples/5
--logo none
--color reset_magenta
--structure Theme:Icons:Font:Cursor
--theme-key T
--theme-format {7}
--icons-key I
--icons-format {5}
--font-key F
--font-format {21}
--cursor-key C
+29 -31
View File
@@ -1,31 +1,29 @@
--load-config all
--os-format "System: {}; Name: {}; Pretty name: {}; ID: {}; ID like: {}; Variant: {}; Variant ID: {}; Version: {}; Version ID: {}; Version codename: {}; Build ID: {}; Architecture: {}"
--host-format "Family: "product_family: {}; product_name: {}; product_version: {}; product_sku: {}; bios_date: {}; bios_release: {}; bios_vendor: {}; bios_version: {}; board_name: {}; board_vendor: {}; board_version: {}; chassis_type: {}; chassis_vendor: {}; chassis_version: {}; sys_vendor: {}"
--kernel-format "Sysname: {}; Release: {}; Version: {}"
--uptime-format "Days: {}; Hours: {}; Minutes: {}; Seconds: {}"
--processes-format "Count: {}"
--packages-format "All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; flatpak: {}; snap: {}"
--shell-format "Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {}"
--resolution-format "Width: {}; Height: {}; Refresh rate: {}"
--de-format "Process name: {}; Pretty name: {}; Version: {}"
--wm-format "Process name: {}; Pretty name: {}; Protocol: {}"
--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: {}"
--cursor-format "Theme: {}; Size: {}"
--terminal-format "Process: {}; Path: {}; Exe: {}"
--terminal-font-format "Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}"
--cpu-format "Name: {}; Pretty: {}; Vendor: {}; Logical online: {}; Logical configured: {}; Physical: {}; Cores: {}; temperature: {}; bios: {}; scaling max: {}; scaling min: {}; info max: {}; info min: {}; cpuinfo: {}; frequency: {}"
--cpu-usage-format "Percentage: {}"
--gpu-format "Vendor: {}; Vendor pretty: {}; Name: {}; Name pretty: {}; Driver: {}; Temperature: {}"
--memory-format "Used: {}; Total: {}; Percentage: {}"
--disk-format "Used: {}; Total: {}; Files: {}; Percentage: {}"
--battery-format "Manufactor: {}; Model: {}; Technology: {}; Capacaty: {}; Status: {}"
--player-format "Name: {}"
--song-format "Song: {}; Artist: {}; Album: {}"
--datetime-format "year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}"
--vulkan-format "driver: {}; Api Version: {}; Conformance Version: {}"
--opengl-format "version: {}; renderer: {}; vendor: {}"
--opencl-format "version: {}; device: {}; vendor: {}"
--os-format System: {}; Name: {}; Pretty name: {}; ID: {}; ID like: {}; Variant: {}; Variant ID: {}; Version: {}; Version ID: {}; Version codename: {}; Build ID: {}; Architecture: {}
--host-format Family: product_family: {}; product_name: {}; product_version: {}; product_sku: {}; bios_date: {}; bios_release: {}; bios_vendor: {}; bios_version: {}; board_name: {}; board_vendor: {}; board_version: {}; chassis_type: {}; chassis_vendor: {}; chassis_version: {}; sys_vendor: {}
--kernel-format Sysname: {}; Release: {}; Version: {}
--uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {}
--processes-format Count: {}
--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {}
--shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {}
--resolution-format Width: {}; Height: {}; Refresh rate: {}
--de-format Process name: {}; Pretty name: {}; Version: {}
--wm-format Process name: {}; Pretty name: {}; Protocol: {}
--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: {}
--cursor-format Theme: {}; Size: {}
--terminal-format Process: {}; Path: {}; Exe: {}
--terminal-font-format Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}
--cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {}
--cpu-usage-format Percentage: {}
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}
--memory-format Used: {}; Total: {}; Percentage: {}
--disk-format Used: {}; Total: {}; Files: {}; Percentage: {}
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
--player-format Name: {}
--song-format Song: {}; Artist: {}; Album: {}
--datetime-format year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}
--vulkan-format driver: {}; Api Version: {}; Conformance Version: {}
--opengl-format version: {}; renderer: {}; vendor: {}
--opencl-format version: {}; device: {}; vendor: {}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

+13 -5
View File
@@ -1,7 +1,13 @@
#include "fastfetch.h"
#include "common/caching.h"
#include "common/io.h"
#include "common/printing.h"
#include <stdlib.h>
#define FF_CACHE_VERSION_NAME "cacheversion"
#define FF_CACHE_VERSION_EXTENSION "ffv"
#define FF_CACHE_VALUE_EXTENSION "ffcv"
#define FF_CACHE_SPLIT_EXTENSION "ffcs"
@@ -41,9 +47,11 @@ void ffCacheValidate(FFinstance* instance)
{
FFstrbuf content;
ffStrbufInit(&content);
readCacheFile(instance, "cacheversion", "ffv", &content);
readCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &content);
bool isSameVersion = ffStrbufCompS(&content, FASTFETCH_PROJECT_VERSION) == 0;
const char exactVersion[] = FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK;
bool isSameVersion = ffStrbufCompS(&content, exactVersion) == 0;
ffStrbufDestroy(&content);
if(isSameVersion)
return;
@@ -51,9 +59,9 @@ void ffCacheValidate(FFinstance* instance)
instance->config.recache = true;
FFstrbuf version;
ffStrbufInitA(&version, sizeof(FASTFETCH_PROJECT_VERSION));
ffStrbufAppendS(&version, FASTFETCH_PROJECT_VERSION);
writeCacheFile(instance, "cacheversion", "ffv", &version);
ffStrbufInitA(&version, sizeof(exactVersion));
ffStrbufAppendS(&version, exactVersion);
writeCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &version);
ffStrbufDestroy(&version);
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#ifndef FF_INCLUDED_common_caching
#define FF_INCLUDED_common_caching
#include "fastfetch.h"
#include "common/format.h"
typedef struct FFcache
{
FILE* value;
FILE* split;
} FFcache;
void ffCacheValidate(FFinstance* instance);
void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache);
void ffCacheClose(FFcache* cache);
bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs);
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);
#endif
+10 -1
View File
@@ -1,4 +1,5 @@
#include "fastfetch.h"
#include "common/font.h"
#include <string.h>
@@ -188,13 +189,21 @@ void ffFontInitPango(FFfont* font, const char* data)
fontInitPretty(font);
}
void ffFontInitCopy(FFfont* font, const char* name)
void ffFontInitValues(FFfont* font, const char* name, const char* size)
{
fontInit(font);
ffStrbufAppendS(&font->name, name);
ffStrbufAppendS(&font->size, size);
fontInitPretty(font);
}
void ffFontInitCopy(FFfont* font, const char* name)
{
ffFontInitValues(font, name, NULL);
}
void ffFontDestroy(FFfont* font)
{
ffStrbufDestroy(&font->pretty);
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#ifndef FF_INCLUDED_common_font
#define FF_INCLUDED_common_font
#include "util/FFstrbuf.h"
#include "util/FFlist.h"
typedef struct FFfont
{
FFstrbuf pretty;
FFstrbuf name;
FFstrbuf size;
FFlist styles;
} FFfont;
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 ffFontDestroy(FFfont* font);
#endif
+4 -3
View File
@@ -1,4 +1,6 @@
#include "fastfetch.h"
#include "common/format.h"
#include "common/parsing.h"
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
{
@@ -62,11 +64,10 @@ static inline void appendEmptyPlaceholder(FFstrbuf* buffer, const char* placehol
static inline bool formatArgSet(const FFformatarg* arg)
{
return arg->value != NULL && (
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value == *(double*)arg->value) || //NaN
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0.0) || //Also is false for NaN
(arg->type == FF_FORMAT_ARG_TYPE_INT && *(int*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRBUF && ((FFstrbuf*)arg->value)->length > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && *(const char*)arg->value != '\0') ||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet(arg->value)) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0)
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#ifndef FF_INCLUDED_common_format
#define FF_INCLUDED_common_format
typedef enum FFformatargtype
{
FF_FORMAT_ARG_TYPE_NULL = 0,
FF_FORMAT_ARG_TYPE_UINT,
FF_FORMAT_ARG_TYPE_UINT16,
FF_FORMAT_ARG_TYPE_UINT8,
FF_FORMAT_ARG_TYPE_INT,
FF_FORMAT_ARG_TYPE_STRING,
FF_FORMAT_ARG_TYPE_STRBUF,
FF_FORMAT_ARG_TYPE_DOUBLE,
FF_FORMAT_ARG_TYPE_LIST
} FFformatargtype;
typedef struct FFformatarg
{
FFformatargtype type;
const void* value;
} FFformatarg;
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
#endif
+102 -11
View File
@@ -1,9 +1,15 @@
#include "fastfetch.h"
#include "common/caching.h"
#include "common/parsing.h"
#include "detection/qt.h"
#include "detection/gtk.h"
#include "detection/displayserver/displayserver.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
#include <pthread.h>
static bool strbufEqualsAdapter(const void* first, const void* second)
{
@@ -15,7 +21,7 @@ static void initConfigDirs(FFstate* state)
ffListInit(&state->configDirs, sizeof(FFstrbuf));
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
if(xdgConfigHome != NULL)
if(ffStrSet(xdgConfigHome))
{
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
ffStrbufInitA(buffer, 64);
@@ -49,6 +55,12 @@ static void initConfigDirs(FFstate* state)
uint32_t colonIndex = ffStrbufNextIndexC(&xdgConfigDirs, startIndex, ':');
xdgConfigDirs.chars[colonIndex] = '\0';
if(!ffStrSet(xdgConfigDirs.chars + startIndex))
{
startIndex = colonIndex + 1;
continue;
}
FFstrbuf* buffer = (FFstrbuf*) ffListAdd(&state->configDirs);
ffStrbufInitA(buffer, 64);
ffStrbufAppendS(buffer, xdgConfigDirs.chars + startIndex);
@@ -98,7 +110,10 @@ static void initState(FFstate* state)
state->keysHeight = 0;
state->passwd = getpwuid(getuid());
uname(&state->utsname);
sysinfo(&state->sysinfo);
#if FF_HAVE_SYSINFO_H
sysinfo(&state->sysinfo);
#endif
initConfigDirs(state);
initCacheDir(state);
@@ -113,15 +128,15 @@ static void initModuleArg(FFModuleArgs* args)
static void defaultConfig(FFinstance* instance)
{
ffStrbufInit(&instance->config.logoSource);
instance->config.logoType = FF_LOGO_TYPE_AUTO;
ffStrbufInit(&instance->config.logo.source);
instance->config.logo.type = FF_LOGO_TYPE_AUTO;
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
ffStrbufInit(&instance->config.logoColors[i]);
instance->config.logoWidth = 0;
instance->config.logoHeight = 0; //preserve aspect ratio
instance->config.logoPaddingLeft = 0;
instance->config.logoPaddingRight = 4;
instance->config.logoPrintRemaining = true;
ffStrbufInit(&instance->config.logo.colors[i]);
instance->config.logo.width = 0;
instance->config.logo.height = 0; //preserve aspect ratio
instance->config.logo.paddingLeft = 0;
instance->config.logo.paddingRight = 4;
instance->config.logo.printRemaining = true;
ffStrbufInit(&instance->config.mainColor);
ffStrbufInit(&instance->config.separator);
@@ -134,8 +149,10 @@ static void defaultConfig(FFinstance* instance)
instance->config.disableLinewrap = true;
instance->config.hideCursor = true;
instance->config.escapeBedrock = true;
instance->config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
instance->config.glType = FF_GL_TYPE_AUTO;
instance->config.pipe = false;
instance->config.multithreading = true;
initModuleArg(&instance->config.os);
initModuleArg(&instance->config.host);
@@ -193,6 +210,8 @@ static void defaultConfig(FFinstance* instance)
ffStrbufInitA(&instance->config.libOSMesa, 0);
ffStrbufInitA(&instance->config.libOpenCL, 0);
instance->config.titleFQDN = false;
ffStrbufInitA(&instance->config.diskFolders, 0);
ffStrbufInitA(&instance->config.batteryDir, 0);
@@ -216,6 +235,75 @@ void ffInitInstance(FFinstance* instance)
defaultConfig(instance);
}
static inline void* detectPlasmaThreadMain(void* instance)
{
ffDetectQt((FFinstance*)instance);
return NULL;
}
static inline void* detectGTK2ThreadMain(void* instance)
{
ffDetectGTK2((FFinstance*)instance);
return NULL;
}
static inline void* detectGTK3ThreadMain(void* instance)
{
ffDetectGTK3((FFinstance*)instance);
return NULL;
}
static inline void* detectGTK4ThreadMain(void* instance)
{
ffDetectGTK4((FFinstance*)instance);
return NULL;
}
static inline void* connectDisplayServerThreadMain(void* instance)
{
ffConnectDisplayServer((FFinstance*)instance);
return NULL;
}
static inline void* startThreadsThreadMain(void* instance)
{
pthread_t dsThread;
pthread_create(&dsThread, NULL, connectDisplayServerThreadMain, instance);
pthread_detach(dsThread);
pthread_t gtk2Thread;
pthread_create(&gtk2Thread, NULL, detectGTK2ThreadMain, instance);
pthread_detach(gtk2Thread);
pthread_t gtk3Thread;
pthread_create(&gtk3Thread, NULL, detectGTK3ThreadMain, instance);
pthread_detach(gtk3Thread);
pthread_t gtk4Thread;
pthread_create(&gtk4Thread, NULL, detectGTK4ThreadMain, instance);
pthread_detach(gtk4Thread);
pthread_t plasmaThread;
pthread_create(&plasmaThread, NULL, detectPlasmaThreadMain, instance);
pthread_detach(plasmaThread);
return NULL;
}
void startDetectionThreads(FFinstance* instance)
{
//Android needs none of the things that are detected here
//And using gsettings sometimes hangs the program in android for some unknown reason,
//and since we don't need it we just never call it.
#if defined(__ANDROID__) || defined(__APPLE__)
return;
#endif
pthread_t startThreadsThread;
pthread_create(&startThreadsThread, NULL, startThreadsThreadMain, instance);
pthread_detach(startThreadsThread);
}
static volatile bool ffDisableLinewrap = true;
static volatile bool ffHideCursor = true;
@@ -237,6 +325,9 @@ static void exitSignalHandler(int signal)
void ffStart(FFinstance* instance)
{
if(instance->config.multithreading)
startDetectionThreads(instance);
ffDisableLinewrap = instance->config.disableLinewrap && !instance->config.pipe;
ffHideCursor = instance->config.hideCursor && !instance->config.pipe;
@@ -266,7 +357,7 @@ void ffStart(FFinstance* instance)
void ffFinish(FFinstance* instance)
{
if(instance->config.logoPrintRemaining)
if(instance->config.logo.printRemaining)
ffLogoPrintRemaining(instance);
resetConsole();
+1 -1
View File
@@ -1,4 +1,5 @@
#include "fastfetch.h"
#include "common/io.h"
#include <sys/stat.h>
#include <unistd.h>
@@ -22,7 +23,6 @@ static void createSubfolders(const char* fileName)
ffStrbufDestroy(&path);
}
bool ffWriteFDBuffer(int fd, const FFstrbuf* content)
{
return write(fd, content->chars, content->length) != -1;
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#ifndef FF_INCLUDED_common_io
#define FF_INCLUDED_common_io
#include <sys/types.h> //mode_t
bool ffWriteFDBuffer(int fd, const FFstrbuf* content);
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data);
bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer);
bool ffAppendFDBuffer(int fd, FFstrbuf* buffer);
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data);
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer);
bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer);
bool ffFileExists(const char* fileName, mode_t mode);
// Not thread safe!
void ffSuppressIO(bool suppress);
void ffGetTerminalResponse(const char* request, const char* format, ...);
#endif
+1 -1
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "common/library.h"
#include <stdarg.h>
#include <dlfcn.h>
static void* libraryLoad(const char* path, int maxVersion)
{
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#ifndef FF_INCLUDED_common_library
#define FF_INCLUDED_common_library
#include <dlfcn.h>
#define FF_LIBRARY_SYMBOL(symbolName) \
__typeof__(&symbolName) ff ## symbolName;
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
void* libraryObjectName = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL);\
if(libraryObjectName == NULL) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL_ADRESS(library, symbolMapping, symbolName, returnValue) \
symbolMapping = dlsym(library, #symbolName); \
if(symbolMapping == NULL) \
{ \
dlclose(library); \
return returnValue; \
}
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADRESS(library, ff ## symbolName, symbolName, returnValue);
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
#endif
+3 -2
View File
@@ -1,6 +1,8 @@
#include "fastfetch.h"
#include "common/networking.h"
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
@@ -9,7 +11,6 @@ void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, F
struct addrinfo hints = {0};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
struct addrinfo* addr;
@@ -27,7 +28,7 @@ void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, F
{
struct timeval timev;
timev.tv_sec = 0;
timev.tv_usec = timeout * 1000; //milliseconds to microseconds
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
}
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#ifndef FF_INCLUDED_common_networking
#define FF_INCLUDED_common_networking
#include "util/FFstrbuf.h"
void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, FFstrbuf* buffer);
#endif
+37 -6
View File
@@ -1,17 +1,17 @@
#include "fastfetch.h"
#include "common/parsing.h"
#include <ctype.h>
#include <inttypes.h>
bool ffStrSet(const char* str)
{
if(str == NULL)
return false;
while(*str != '\0')
{
if(*str != ' ' && *str != '\t' && *str != '\n' && *str != '\r')
return true;
}
while(isspace(*str))
str++;
return false;
return *str != '\0';
}
void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch)
@@ -65,6 +65,37 @@ void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty)
ffStrbufAppendF(pretty, ".%u", version->patch);
}
static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, uint8_t prefixesLength, const char** prefixes)
{
long double size = (long double) bytes;
uint8_t counter = 0;
while(size > base && counter < prefixesLength - 1)
{
size /= base;
counter++;
}
if(counter == 0)
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
else if(counter < 3 || (counter == 3 && size < 100.0))
ffStrbufAppendF(result, "%.2Lf %s", size, prefixes[counter]);
else
ffStrbufAppendF(result, "%.0Lf %s", size, prefixes[counter]);
}
void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result)
{
if(binaryPrefix == FF_BINARY_PREFIX_TYPE_IEC)
parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB"});
else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_SI)
parseSize(result, bytes, 1000, 5, (const char*[]) {"B", "kB", "MB", "GB", "TB"});
else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_JEDEC)
parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KB", "MB", "GB", "TB"});
else
parseSize(result, bytes, 1024, 1, (const char*[]) {"B"});
}
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4)
{
if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0)
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#ifndef FF_INCLUDED_parsing_h
#define FF_INCLUDED_parsing_h
#include <stdint.h>
typedef struct FFVersion
{
uint32_t major;
uint32_t minor;
uint32_t patch;
} FFVersion;
#define FF_VERSION_INIT ((FFVersion) {0})
bool ffStrSet(const char* str);
void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch);
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4);
void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty);
int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2);
void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result);
#endif
+39 -2
View File
@@ -1,9 +1,14 @@
#include "fastfetch.h"
#include "common/printing.h"
void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat)
{
ffLogoPrintLine(instance);
//This is used by --set-keyless, in this case we wan't neither the module name nor the separator
if(moduleName == NULL)
return;
if(!instance->config.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
@@ -25,7 +30,7 @@ void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t mod
ffParseFormatString(&key, customKeyFormat, 1, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex}
});
ffStrbufWriteTo(&key, stdout);
ffPrintUserString(key.chars);
ffStrbufDestroy(&key);
}
@@ -48,7 +53,8 @@ void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t m
if(buffer.length > 0)
{
ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat);
ffStrbufPutTo(&buffer, stdout);
ffPrintUserString(buffer.chars);
putchar('\n');
}
ffStrbufDestroy(&buffer);
@@ -124,3 +130,34 @@ void ffPrintCharTimes(char c, uint32_t times)
for(uint32_t i = 0; i < times; i++)
putchar(c);
}
void ffPrintUserString(const char* value)
{
while(*value != '\0')
{
if(*value != '\\')
{
putchar(*value);
++value;
continue;
}
++value;
if(*value == 'n')
putchar('\n');
else if(*value == 't')
putchar('\t');
else if(*value == 'e')
putchar('\e');
else if(*value == '\\')
putchar('\\');
else
{
putchar('\\');
putchar(*value);
}
++value;
}
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#ifndef FF_INCLUDED_common_printing
#define FF_INCLUDED_common_printing
#include "fastfetch.h"
#include "common/format.h"
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, ...);
void ffPrintColor(const FFstrbuf* colorValue);
void ffPrintCharTimes(char c, uint32_t times);
void ffPrintUserString(const char* str);
#endif
+2
View File
@@ -1,4 +1,6 @@
#include "fastfetch.h"
#include "common/processing.h"
#include "common/io.h"
#include <stdlib.h>
#include <unistd.h>
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#ifndef FF_INCLUDED_common_processing
#define FF_INCLUDED_common_processing
#include "util/FFstrbuf.h"
void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]);
#endif
+7 -13
View File
@@ -1,4 +1,5 @@
#include "fastfetch.h"
#include "common/properties.h"
#include <stdlib.h>
@@ -88,10 +89,13 @@ bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
// The following functions return true if the file was found, independently if start was found
// Buffers which already contain content are not overwritten
// The last occurence of start in the first file will be the one used
// The *Values methods always return true, if all properties were already found before, without testing if the file exists
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries)
{
FILE* file = fopen(filename, "r");
if(file == NULL)
return false;
bool valueStorage[4];
bool* unsetValues;
@@ -107,17 +111,8 @@ bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquer
allSet = false;
}
FILE* file = fopen(filename, "r");
if(file == NULL)
return false;
if(allSet)
{
fclose(file);
if(unsetValues != valueStorage)
free(unsetValues);
return true;
}
goto done;
char* line = NULL;
size_t len = 0;
@@ -139,11 +134,10 @@ bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquer
if(line != NULL)
free(line);
done:
fclose(file);
if(unsetValues != valueStorage)
free(unsetValues);
return true;
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#ifndef FF_INCLUDED_common_properties
#define FF_INCLUDED_common_properties
#include "util/FFstrbuf.h"
typedef struct FFpropquery
{
const char* start;
FFstrbuf* buffer;
} FFpropquery;
bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer);
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer);
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries);
bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer);
bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
bool ffParsePropFileHome(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer);
bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer);
#endif
+48 -5
View File
@@ -1,8 +1,17 @@
#include "fastfetch.h"
#include "common/settings.h"
#include "common/library.h"
#include "common/io.h"
#include <pthread.h>
#include <string.h>
#include <dlfcn.h>
typedef enum FFInitState
{
FF_INITSTATE_UNINITIALIZED = 0,
FF_INITSTATE_SUCCESSFUL = 1,
FF_INITSTATE_FAILED = 2
} FFInitState;
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
static dataObject data; \
@@ -343,10 +352,44 @@ int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, cons
#ifdef __ANDROID__
#include <sys/system_properties.h>
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
uint32_t originalLength = result->length;
void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
ffStrbufEnsureFree(result, PROP_VALUE_MAX);
result->length += (uint32_t) __system_property_get(propName, result->chars + result->length);
return result->length > originalLength;
result->chars[result->length] = '\0';
}
#endif
#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__
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#ifndef FF_INCLUDED_common_settings
#define FF_INCLUDED_common_settings
#include "fastfetch.h"
typedef enum FFvarianttype
{
FF_VARIANT_TYPE_STRING,
FF_VARIANT_TYPE_BOOL,
FF_VARIANT_TYPE_INT
} FFvarianttype;
typedef union FFvariant
{
const char* strValue;
int32_t intValue;
struct
{
bool boolValueSet;
bool boolValue;
};
} 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);
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query);
#ifdef __ANDROID__
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
-72
View File
@@ -1,72 +0,0 @@
#include "fastfetch.h"
#include <pthread.h>
static inline void* detectPlasmaThreadMain(void* instance)
{
ffDetectPlasma((FFinstance*)instance);
return NULL;
}
static inline void* detectGTK2ThreadMain(void* instance)
{
ffDetectGTK2((FFinstance*)instance);
return NULL;
}
static inline void* detectGTK3ThreadMain(void* instance)
{
ffDetectGTK3((FFinstance*)instance);
return NULL;
}
static inline void* detectGTK4ThreadMain(void* instance)
{
ffDetectGTK4((FFinstance*)instance);
return NULL;
}
static inline void* connectDisplayServerThreadMain(void* instance)
{
ffConnectDisplayServer((FFinstance*)instance);
return NULL;
}
static inline void* startThreadsThreadMain(void* instance)
{
pthread_t dsThread;
pthread_create(&dsThread, NULL, connectDisplayServerThreadMain, instance);
pthread_detach(dsThread);
pthread_t gtk2Thread;
pthread_create(&gtk2Thread, NULL, detectGTK2ThreadMain, instance);
pthread_detach(gtk2Thread);
pthread_t gtk3Thread;
pthread_create(&gtk3Thread, NULL, detectGTK3ThreadMain, instance);
pthread_detach(gtk3Thread);
pthread_t gtk4Thread;
pthread_create(&gtk4Thread, NULL, detectGTK4ThreadMain, instance);
pthread_detach(gtk4Thread);
pthread_t plasmaThread;
pthread_create(&plasmaThread, NULL, detectPlasmaThreadMain, instance);
pthread_detach(plasmaThread);
return NULL;
}
void ffStartDetectionThreads(FFinstance* instance)
{
//Android needs none of the things that are detected here
//And using gsettings sometimes hangs the program in android for some unknown reason,
//and since we don't need it we just never call it.
#ifdef __ANDROID__
return;
#endif
pthread_t startThreadsThread;
pthread_create(&startThreadsThread, NULL, startThreadsThreadMain, instance);
pthread_detach(startThreadsThread);
}
+16
View File
@@ -0,0 +1,16 @@
# Fastfetch system configuration
# This file sets the default config for all users of the system.
# For more information about how configuration files work,
# see ~/.config/fastfetch/config.conf, generated during first run.
# All options that can be put there (or passed as argument) can be put here too.
# Use fastfetch --print-config-system > /etc/fastfetch/config.conf
# to overwrite this file with the current default file.
# User config option
# Sets if fastfetch should load user provided configuration.
# If this is off, fastfetch ignores the user config file and any passed arguments
# Must be true or false
# Default is true.
#--load-user-config true
@@ -6,7 +6,7 @@
# Empty lines or lines starting with # are ignored.
# This file was shipped with $"FASTFETCH_PROJECT_VERSION$".
# Use fastfetch --print-config > ~/.config/fastfetch/config.conf to overwrite this with the current defaults
# Use fastfetch --print-config-user > ~/.config/fastfetch/config.conf to overwrite this file with the current defaults
# Below some often usefull options are listed. Uncomment and modify them so they take affect.
# Note that there are a lot more options than the ones listed here, take a look at "fastfetch --help".
@@ -120,6 +120,18 @@
# Use "fastfetch --help color" to learn more and see examples.
#--color magenta
# Binary prefix option:
# Sets the binary prefix to use.
# Must be a IEC, SI or JEDEC.
# Default is IEC.
#--binary-prefix IEC
# Title FQDN option:
# Sets if the title should use the fully qualified domain name.
# Must be true or false.
# Default is false.
#--title-fqdn false
# Separator option:
# Sets the string placed between a key and its value.
# Can be any string.
@@ -297,4 +309,4 @@
#--lib-egl /usr/lib/libEGL.so
#--lib-glx /usr/lib/libGLX.so
#--lib-osmesa /usr/lib/libOSMesa.so
#--lib-opencl /usr/lib/libOpenCL.so
#--lib-opencl /usr/lib/libOpenCL.so
+14 -10
View File
@@ -1,16 +1,17 @@
Usage: fastfetch <options>
Informative options:
-h,--help: shows this message and exits
-h,--help <command>: shows help for a specific command and exits
-v,--version: prints the version of fastfetch and exits
--list-logos: list available logos and exits
--list-modules: lists available modules and exits
--list-presets: list presets fastfetch knows about and exits. They can be loaded with --load-config. (+)
--list-features: list the supported features fastfetch was compiled with and exits. Mainly for development.
--print-logos: show available logos and exits
--print-config: prints the default config and exits
--print-structure: prints the default stucture and exits
-h,--help: shows this message and exits
-h,--help <command>: shows help for a specific command and exits
-v,--version: prints the version of fastfetch and exits
--list-logos: list available logos and exits
--list-modules: lists available modules and exits
--list-presets: list presets fastfetch knows about and exits. They can be loaded with --load-config. (+)
--list-features: list the supported features fastfetch was compiled with and exits. Mainly for development.
--print-logos: show available logos and exits
--print-config-system: prints the default system config and exits
--print-config-user: prints the default user config and exits
--print-structure: prints the default stucture and exits
General options:
-r,--recache <?value>: generate new cached values
@@ -42,9 +43,11 @@ Display options:
-c,--color <color>: sets the color of the keys. Must be a linux console color code or the name of a color (+)
--separator <str>: sets the separator between key and value. Default is a colon with a space
--set <key=value>: hard set the value of a key
--set-keyless <key=value>: hard set the value of a key, but don't print the key or the separator
--show-errors <?value>: print occuring errors
--disable-linewrap <?value>: weather to disable linewrap during the run
--hide-cursor <?value>: weather to hide the cursor during the run
--binary-prefix <value>: sets the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC
General module options:
--<module>-format <format>: Sets the format string to use for each specific module.
@@ -81,6 +84,7 @@ Library options: Set the path of a library to load
--lib-opencl <path>
Module specific options:
--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"
+1 -1
View File
@@ -15,6 +15,7 @@ Icons
Kernel
Locale
LocalIP
Media
Memory
OS
OpenCL
@@ -26,7 +27,6 @@ PublicIP
Resolution
Separator
Shell
Song
Terminal
TerminalFont
Theme
+22
View File
@@ -0,0 +1,22 @@
#include "cpu.h"
#include "detection/internal.h"
void ffDetectCPUImpl(FFCPUResult* cpu);
const FFCPUResult* ffDetectCPU()
{
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
);
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#ifndef FF_INCLUDED_detection_cpu_cpu
#define FF_INCLUDED_detection_cpu_cpu
#include "fastfetch.h"
#define FF_CPU_TEMP_UNSET (0/0.0)
typedef struct FFCPUResult
{
FFstrbuf name;
FFstrbuf vendor;
uint16_t coresPhysical;
uint16_t coresLogical;
uint16_t coresOnline;
double frequencyMin;
double frequencyMax;
double temperature;
} FFCPUResult;
const FFCPUResult* ffDetectCPU();
#endif
+42
View File
@@ -0,0 +1,42 @@
#include "cpu.h"
#include "common/settings.h"
static double getFrequency(const char* propName)
{
double herz = (double) ffSettingsGetAppleInt64(propName, 0);
if(herz <= 0.0)
return herz;
herz /= 1000.0; //to KHz
herz /= 1000.0; //to MHz
return herz / 1000.0; //to GHz
}
void ffDetectCPUImpl(FFCPUResult* cpu)
{
ffStrbufInit(&cpu->name);
ffSettingsGetAppleProperty("machdep.cpu.brand_string", &cpu->name);
ffStrbufInit(&cpu->vendor);
ffSettingsGetAppleProperty("machdep.cpu.vendor", &cpu->vendor);
cpu->coresPhysical = (uint16_t) ffSettingsGetAppleInt("hw.physicalcpu_max", 1);
if(cpu->coresPhysical == 1)
cpu->coresPhysical = (uint16_t) ffSettingsGetAppleInt("hw.physicalcpu", 1);
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;
}
+102
View File
@@ -0,0 +1,102 @@
#include "cpu.h"
#include "common/io.h"
#include "common/properties.h"
#include "detection/temps.h"
#include <stdlib.h>
#include <unistd.h>
static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer)
{
FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
if(cpuinfo == NULL)
return;
char* line = NULL;
size_t len = 0;
while(getline(&line, &len, cpuinfo) != -1)
{
//Stop after the first CPU
if(cpu->name.length > 0 && (*line == '\0' || *line == '\n'))
break;
(void)(
ffParsePropLine(line, "model name :", &cpu->name) ||
ffParsePropLine(line, "vendor_id :", &cpu->vendor) ||
ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) ||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) //For Android devices
);
}
if(line != NULL)
free(line);
fclose(cpuinfo);
}
static double getGHz(const char* file)
{
FFstrbuf content;
ffStrbufInit(&content);
ffReadFileBuffer(file, &content);
double herz = ffStrbufToDouble(&content);
ffStrbufDestroy(&content);
//ffStrbufToDouble failed
if(herz != herz)
return 0;
herz /= 1000.0; //to MHz
return herz / 1000.0; //to GHz
}
static double getFrequency(const char* info, const char* scaling)
{
double frequency = getGHz(info);
if(frequency > 0.0)
return frequency;
return getGHz(scaling);
}
static double detectCPUTemp()
{
const FFTempsResult *temps = ffDetectTemps();
for(uint32_t i = 0; i < temps->values.length; i++)
{
FFTempValue* value = ffListGet(&temps->values, i);
if(
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
ffStrbufCompS(&value->name, "coretemp") == 0
) return value->value;
}
return FF_CPU_TEMP_UNSET;
}
void ffDetectCPUImpl(FFCPUResult* cpu)
{
ffStrbufInit(&cpu->name);
ffStrbufInit(&cpu->vendor);
FFstrbuf physicalCoresBuffer;
ffStrbufInit(&physicalCoresBuffer);
parseCpuInfo(cpu, &physicalCoresBuffer);
cpu->coresPhysical = ffStrbufToUInt16(&physicalCoresBuffer, 1);
cpu->coresLogical = (uint16_t) get_nprocs_conf();
cpu->coresOnline = (uint16_t) get_nprocs();
#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);
}
+1
View File
@@ -1,4 +1,5 @@
#include "fastfetch.h"
#include "detection/datetime.h"
#include <time.h>
#include <pthread.h>
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#ifndef FF_INCLUDED_detection_datetime
#define FF_INCLUDED_detection_datetime
#include "fastfetch.h"
typedef struct FFDateTimeResult
{
//Examples for 21.02.2022 - 15:18:37
uint16_t year; //2022
uint8_t yearShort; //22
uint8_t month; //2
FFstrbuf monthPretty; //02
FFstrbuf monthName; //February
FFstrbuf monthNameShort; //Feb
uint8_t week; //8
FFstrbuf weekday; //Monday
FFstrbuf weekdayShort; //Mon
uint16_t dayInYear; //52
uint8_t dayInMonth; //21
uint8_t dayInWeek; //1
uint8_t hour; //15
FFstrbuf hourPretty; //15
uint8_t hour12; //3
FFstrbuf hour12Pretty; //03
uint8_t minute; //18
FFstrbuf minutePretty; //18
uint8_t second; //37
FFstrbuf secondPretty; //37
} FFDateTimeResult;
const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance);
#endif
-133
View File
@@ -1,133 +0,0 @@
#include "displayServer.h"
#include <pthread.h>
#include <dirent.h>
uint32_t ffdsParseRefreshRate(int32_t refreshRate)
{
if(refreshRate <= 0)
return 0;
int remainder = refreshRate % 5;
if(remainder >= 3)
refreshRate += (5 - remainder);
else
refreshRate -= remainder;
//All other typicall refresh rates are dividable by 5
if(refreshRate == 145)
refreshRate = 144;
return (uint32_t) refreshRate;
}
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate)
{
if(width == 0 || height == 0)
return false;
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
resolution->width = width;
resolution->height = height;
resolution->refreshRate = refreshRate;
return true;
}
static void parseDRM(FFDisplayServerResult* result)
{
const char* drmDirPath = "/sys/class/drm/";
DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return;
FFstrbuf drmDir;
ffStrbufInitA(&drmDir, 64);
ffStrbufAppendS(&drmDir, drmDirPath);
uint32_t drmDirLength = drmDir.length;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
ffStrbufAppendS(&drmDir, entry->d_name);
ffStrbufAppendS(&drmDir, "/modes");
FILE* modeFile = fopen(drmDir.chars, "r");
if(modeFile == NULL)
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
resolution->width = 0;
resolution->height = 0;
resolution->refreshRate = 0;
int scanned = fscanf(modeFile, "%ix%i", &resolution->width, &resolution->height);
if(scanned < 2 || resolution->width == 0 || resolution->height == 0)
--result->resolutions.length;
fclose(modeFile);
ffStrbufSubstrBefore(&drmDir, drmDirLength);
}
closedir(dirp);
ffStrbufDestroy(&drmDir);
}
const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance)
{
static FFDisplayServerResult 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.wmProcessName);
ffStrbufInit(&result.wmPrettyName);
ffStrbufInit(&result.wmProtocolName);
ffStrbufInit(&result.deProcessName);
ffStrbufInit(&result.dePrettyName);
ffStrbufInit(&result.deVersion);
ffListInitA(&result.resolutions, sizeof(FFResolutionResult), 4);
//We try wayland as our prefered display server, as it supports the most features.
//This method can't detect the name of our WM / DE
ffdsConnectWayland(instance, &result);
//Try the x11 libs, from most feature rich to least.
//We use the resolution list to detect if a connection is needed.
//They respect wmProtocolName, and only detect resolution if it is set.
if(result.resolutions.length == 0)
ffdsConnectXcbRandr(instance, &result);
if(result.resolutions.length == 0)
ffdsConnectXrandr(instance, &result);
if(result.resolutions.length == 0)
ffdsConnectXcb(instance, &result);
if(result.resolutions.length == 0)
ffdsConnectXlib(instance, &result);
//This resolution detection method is display server independent.
//Use it if all connections failed
if(result.resolutions.length == 0)
parseDRM(&result);
//This fills in missing information about WM / DE by using env vars and iterating processes
ffdsDetectWMDE(instance, &result);
pthread_mutex_unlock(&mutex);
return &result;
}
@@ -0,0 +1,42 @@
#include "displayserver.h"
#include "detection/internal.h"
uint32_t ffdsParseRefreshRate(int32_t refreshRate)
{
if(refreshRate <= 0)
return 0;
int remainder = refreshRate % 5;
if(remainder >= 3)
refreshRate += (5 - remainder);
else
refreshRate -= remainder;
//All other typicall refresh rates are dividable by 5
if(refreshRate == 145)
refreshRate = 144;
return (uint32_t) refreshRate;
}
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate)
{
if(width == 0 || height == 0)
return false;
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
resolution->width = width;
resolution->height = height;
resolution->refreshRate = refreshRate;
return true;
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance);
const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance)
{
FF_DETECTION_INTERNAL_GUARD(FFDisplayServerResult,
ffConnectDisplayServerImpl(&result, instance);
);
}
@@ -0,0 +1,32 @@
#pragma once
#ifndef FF_INCLUDED_detection_displayserver
#define FF_INCLUDED_detection_displayserver
#include "fastfetch.h"
typedef struct FFResolutionResult
{
uint32_t width;
uint32_t height;
uint32_t refreshRate;
} FFResolutionResult;
typedef struct FFDisplayServerResult
{
FFstrbuf wmProcessName;
FFstrbuf wmPrettyName;
FFstrbuf wmProtocolName;
FFstrbuf deProcessName;
FFstrbuf dePrettyName;
FFstrbuf deVersion;
FFlist resolutions; //List of FFResolutionResult
} FFDisplayServerResult;
const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance);
//Used internal
uint32_t ffdsParseRefreshRate(int32_t refreshRate);
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate);
#endif
@@ -0,0 +1,14 @@
#include "displayserver.h"
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
{
FF_UNUSED(instance);
ffStrbufInitA(&ds->wmProcessName, 0);
ffStrbufInitA(&ds->wmPrettyName, 0);
ffStrbufInitA(&ds->wmProtocolName, 0);
ffStrbufInitA(&ds->deProcessName, 0);
ffStrbufInitA(&ds->dePrettyName, 0);
ffStrbufInitA(&ds->deVersion, 0);
ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 0);
}
@@ -0,0 +1,88 @@
#include "displayserver.h"
#include "common/library.h"
#include <stdlib.h>
#include <ApplicationServices/ApplicationServices.h>
//Resolution code heavily inspired by displayplacer <3
typedef union
{
uint8_t rawData[0xDC];
struct
{
uint32_t mode;
uint32_t flags; // 0x4
uint32_t width; // 0x8
uint32_t height; // 0xC
uint32_t depth; // 0x10
uint32_t dc2[42];
uint16_t dc3;
uint16_t freq; // 0xBC
uint32_t dc4[4];
float density; // 0xD0
} derived;
} modes_D4;
void CGSGetCurrentDisplayMode(CGDirectDisplayID display, int* modeNum);
void CGSGetDisplayModeDescriptionOfLength(CGDirectDisplayID display, int idx, modes_D4* mode, int length);
static void detectResolution(FFDisplayServerResult* ds)
{
void* cg = dlopen(FASTFETCH_TARGET_DIR_ROOT"/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics", RTLD_LAZY);
if(cg == NULL)
return;
FF_LIBRARY_LOAD_SYMBOL(cg, CGGetOnlineDisplayList, )
FF_LIBRARY_LOAD_SYMBOL(cg, CGDisplayScreenSize, )
FF_LIBRARY_LOAD_SYMBOL(cg, CGSGetCurrentDisplayMode, )
FF_LIBRARY_LOAD_SYMBOL(cg, CGSGetDisplayModeDescriptionOfLength, )
CGDisplayCount screenCount;
ffCGGetOnlineDisplayList(INT_MAX, NULL, &screenCount);
if(screenCount == 0)
{
dlclose(cg);
return;
}
CGDirectDisplayID* screens = malloc(screenCount * sizeof(CGDirectDisplayID));
ffCGGetOnlineDisplayList(INT_MAX, screens, &screenCount);
for(uint32_t i = 0; i < screenCount; i++)
{
int modeID;
ffCGSGetCurrentDisplayMode(screens[i], &modeID);
modes_D4 mode;
ffCGSGetDisplayModeDescriptionOfLength(screens[i], modeID, &mode, 0xD4);
uint32_t refreshRate = ffdsParseRefreshRate(mode.derived.freq);
ffdsAppendResolution(ds, mode.derived.width, mode.derived.height, refreshRate);
}
free(screens);
dlclose(cg);
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
{
FF_UNUSED(instance);
ffStrbufInit(&ds->wmProcessName);
ffStrbufAppendS(&ds->wmProcessName, "quartz");
ffStrbufInit(&ds->wmPrettyName);
ffStrbufAppendS(&ds->wmPrettyName, "Quartz Compositor");
ffStrbufInit(&ds->deProcessName);
ffStrbufAppendS(&ds->deProcessName, "aqua");
ffStrbufInit(&ds->dePrettyName);
ffStrbufAppendS(&ds->dePrettyName, "Aqua");
ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 4);
detectResolution(ds);
ffStrbufInitA(&ds->deVersion, 0);
ffStrbufInitA(&ds->wmProtocolName, 0);
}
@@ -0,0 +1,86 @@
#include "displayserver_linux.h"
#include <dirent.h>
static void parseDRM(FFDisplayServerResult* result)
{
const char* drmDirPath = "/sys/class/drm/";
DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return;
FFstrbuf drmDir;
ffStrbufInitA(&drmDir, 64);
ffStrbufAppendS(&drmDir, drmDirPath);
uint32_t drmDirLength = drmDir.length;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
ffStrbufAppendS(&drmDir, entry->d_name);
ffStrbufAppendS(&drmDir, "/modes");
FILE* modeFile = fopen(drmDir.chars, "r");
if(modeFile == NULL)
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
resolution->width = 0;
resolution->height = 0;
resolution->refreshRate = 0;
int scanned = fscanf(modeFile, "%ix%i", &resolution->width, &resolution->height);
if(scanned < 2 || resolution->width == 0 || resolution->height == 0)
--result->resolutions.length;
fclose(modeFile);
ffStrbufSubstrBefore(&drmDir, drmDirLength);
}
closedir(dirp);
ffStrbufDestroy(&drmDir);
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
{
ffStrbufInit(&ds->wmProcessName);
ffStrbufInit(&ds->wmPrettyName);
ffStrbufInit(&ds->wmProtocolName);
ffStrbufInit(&ds->deProcessName);
ffStrbufInit(&ds->dePrettyName);
ffStrbufInit(&ds->deVersion);
ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 4);
//We try wayland as our prefered display server, as it supports the most features.
//This method can't detect the name of our WM / DE
ffdsConnectWayland(instance, ds);
//Try the x11 libs, from most feature rich to least.
//We use the resolution list to detect if a connection is needed.
//They respect wmProtocolName, and only detect resolution if it is set.
if(ds->resolutions.length == 0)
ffdsConnectXcbRandr(instance, ds);
if(ds->resolutions.length == 0)
ffdsConnectXrandr(instance, ds);
if(ds->resolutions.length == 0)
ffdsConnectXcb(instance, ds);
if(ds->resolutions.length == 0)
ffdsConnectXlib(instance, ds);
//This resolution detection method is display server independent.
//Use it if all connections failed
if(ds->resolutions.length == 0)
parseDRM(ds);
//This fills in missing information about WM / DE by using env vars and iterating processes
ffdsDetectWMDE(instance, ds);
}
@@ -3,15 +3,12 @@
#ifndef FASTFETCH_INCLUDED_DISPLAYSERVER
#define FASTFETCH_INCLUDED_DISPLAYSERVER
#include "fastfetch.h"
#include "detection/displayserver/displayserver.h"
#define FF_DISPLAYSERVER_PROTOCOL_WAYLAND "Wayland"
#define FF_DISPLAYSERVER_PROTOCOL_X11 "X11"
#define FF_DISPLAYSERVER_PROTOCOL_TTY "TTY"
uint32_t ffdsParseRefreshRate(int32_t refreshRate);
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate);
void ffdsConnectWayland(const FFinstance* instance, FFDisplayServerResult* result);
void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result);
@@ -1,13 +1,14 @@
#define _GNU_SOURCE //required for struct ucred
#include "displayServer.h"
#include "displayserver_linux.h"
#include <stdlib.h>
#include <string.h>
#ifdef FF_HAVE_WAYLAND
#include "common/library.h"
#include "common/io.h"
#include <pthread.h>
#include <dlfcn.h>
#include <wayland-client.h>
#include <sys/socket.h>
@@ -16,7 +17,6 @@ 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;
@@ -43,9 +43,9 @@ 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)
{
WaylandData* wldata = data;
FF_UNUSED(output);
wldata->ffwl_proxy_destroy((struct wl_proxy*) output);
WaylandData* wldata = data;
if(!(flags & WL_OUTPUT_MODE_CURRENT) || width <= 0 || height <= 0)
return;
@@ -111,7 +111,6 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_marshal_constructor_versioned, wl_proxy_marshal_constructor_versioned, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_add_listener, wl_proxy_add_listener, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_output_interface, wl_output_interface, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_destroy, wl_proxy_destroy, false)
struct wl_display* display = ffwl_display_connect(NULL);
if(display == NULL)
@@ -141,8 +140,7 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
ffwl_display_dispatch(display);
ffwl_display_roundtrip(display);
data.ffwl_proxy_destroy(registry);
ffwl_display_disconnect(display);
ffwl_display_disconnect(display); //This will also destroy our wl_registry and wl_output proxies
dlclose(wayland);
//We successfully connected to wayland and detected the resolution.
@@ -162,6 +160,8 @@ void ffdsConnectWayland(const FFinstance* instance, FFDisplayServerResult* resul
#ifdef FF_HAVE_WAYLAND
if(detectWayland(instance, result))
return;
#else
FF_UNUSED(instance);
#endif
const char* xdgSessionType = getenv("XDG_SESSION_TYPE");
@@ -1,4 +1,8 @@
#include "displayServer.h"
#include "displayserver_linux.h"
#include "common/io.h"
#include "common/properties.h"
#include "common/parsing.h"
#include "common/processing.h"
#include <stdlib.h>
#include <ctype.h>
@@ -64,6 +68,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* proce
strcasecmp(processName, "kwin") == 0
) ffStrbufSetS(&result->wmPrettyName, "KWin");
else if(
strcasecmp(processName, "gnome-shell") == 0 ||
strcasecmp(processName, "gnome shell") == 0 ||
strcasecmp(processName, "gnome-session-binary") == 0 ||
strcasecmp(processName, "Mutter") == 0
) ffStrbufSetS(&result->wmPrettyName, "Mutter");
@@ -1,9 +1,9 @@
#include "displayServer.h"
#include "displayserver_linux.h"
#ifdef FF_HAVE_XCB
#include "common/library.h"
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <xcb/xcb.h>
typedef struct XcbPropertyData
@@ -1,7 +1,8 @@
#include "displayServer.h"
#include "displayserver_linux.h"
#ifdef FF_HAVE_X11
#include <dlfcn.h>
#include "common/library.h"
#include "common/parsing.h"
#include <X11/Xlib.h>
typedef struct X11PropertyData
+12
View File
@@ -0,0 +1,12 @@
#include "gpu.h"
#include "detection/internal.h"
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance);
const FFlist* ffDetectGPU(const FFinstance* instance)
{
FF_DETECTION_INTERNAL_GUARD(FFlist,
ffListInit(&result, sizeof(FFGPUResult));
ffDetectGPUImpl(&result, instance);
);
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#ifndef FF_INCLUDED_detection_gpu_gpu
#define FF_INCLUDED_detection_gpu_gpu
#include "fastfetch.h"
#define FF_GPU_TEMP_UNSET (0/0.0)
typedef struct FFGPUResult
{
FFstrbuf vendor;
FFstrbuf name;
FFstrbuf driver;
double temperature;
} FFGPUResult;
const FFlist* ffDetectGPU(const FFinstance* instance);
#endif
+6
View File
@@ -0,0 +1,6 @@
#include "gpu.h"
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
{
FF_UNUSED(gpus, instance);
}
+72
View File
@@ -0,0 +1,72 @@
#include "gpu.h"
#include "common/library.h"
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/graphics/IOGraphicsLib.h>
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
{
FF_UNUSED(instance);
void* iokit = dlopen(FASTFETCH_TARGET_DIR_ROOT"/System/Library/Frameworks/IOKit.framework/IOKit", RTLD_LAZY);
if(iokit == NULL)
return;
FF_LIBRARY_LOAD_SYMBOL(iokit, IOServiceMatching, )
FF_LIBRARY_LOAD_SYMBOL(iokit, IOServiceGetMatchingServices, )
FF_LIBRARY_LOAD_SYMBOL(iokit, kIOMasterPortDefault, )
FF_LIBRARY_LOAD_SYMBOL(iokit, IOIteratorNext, )
FF_LIBRARY_LOAD_SYMBOL(iokit, IORegistryEntryCreateCFProperties, )
FF_LIBRARY_LOAD_SYMBOL(iokit, kCFAllocatorDefault, )
FF_LIBRARY_LOAD_SYMBOL(iokit, CFDictionaryGetValue, )
FF_LIBRARY_LOAD_SYMBOL(iokit, CFGetTypeID, )
FF_LIBRARY_LOAD_SYMBOL(iokit, CFStringCreateWithCStringNoCopy, )
FF_LIBRARY_LOAD_SYMBOL(iokit, CFStringGetLength, )
FF_LIBRARY_LOAD_SYMBOL(iokit, CFStringGetCString, )
FF_LIBRARY_LOAD_SYMBOL(iokit, CFRelease, )
FF_LIBRARY_LOAD_SYMBOL(iokit, CFDataGetTypeID, )
FF_LIBRARY_LOAD_SYMBOL(iokit, IOObjectRelease, )
CFMutableDictionaryRef matchDict = ffIOServiceMatching(kIOAcceleratorClassName);
io_iterator_t iterator;
if(ffIOServiceGetMatchingServices(*ffkIOMasterPortDefault, matchDict, &iterator) != kIOReturnSuccess)
{
dlclose(iokit);
return;
}
io_registry_entry_t registryEntry;
while((registryEntry = ffIOIteratorNext(iterator)) != 0)
{
CFMutableDictionaryRef properties;
if(ffIORegistryEntryCreateCFProperties(registryEntry, &properties, *ffkCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
{
ffIOObjectRelease(registryEntry);
continue;
}
CFStringRef key = ffCFStringCreateWithCStringNoCopy(NULL, "model", kCFStringEncodingUTF8, NULL);
CFStringRef model = ffCFDictionaryGetValue(properties, key);
if(model == NULL || ffCFGetTypeID(model) != ffCFDataGetTypeID())
{
ffCFRelease(properties);
ffIOObjectRelease(registryEntry);
continue;
}
FFGPUResult* gpu = ffListAdd(gpus);
ffStrbufInitA(&gpu->name, (uint32_t) (ffCFStringGetLength(model) + 1));
ffCFStringGetCString(model, gpu->name.chars, ffStrbufGetFree(&gpu->name), kCFStringEncodingUTF8);
ffStrbufInitA(&gpu->vendor, 0);
ffStrbufInitA(&gpu->driver, 0);
gpu->temperature = FF_GPU_TEMP_UNSET;
ffCFRelease(properties);
ffIOObjectRelease(registryEntry);
}
ffIOObjectRelease(iterator);
dlclose(iokit);
}
+208
View File
@@ -0,0 +1,208 @@
#include "gpu.h"
#include "detection/vulkan.h"
#define FF_GPU_VENDOR_NAME_AMD "AMD"
#define FF_GPU_VENDOR_NAME_INTEL "Intel"
#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA"
#ifdef FF_HAVE_LIBPCI
#include "common/library.h"
#include "common/properties.h"
#include "common/parsing.h"
#include "detection/temps.h"
#include <string.h>
#include <unistd.h>
#include <pci/pci.h>
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);
} PCIData;
static bool pciIDsContains(u16 searched, const u16* ids)
{
while(*ids != 0)
{
if(*ids == searched)
return true;
ids++;
}
return false;
}
static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
if(pciIDsContains(device->vendor_id, (const u16[]) {0x1002, 0x1022, 0}))
ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if(pciIDsContains(device->vendor_id, (const u16[]) {0x03e7, 0x8086, 0x8087, 0}))
ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if(pciIDsContains(device->vendor_id, (const u16[]) {0x0955, 0x10de, 0x12d2, 0}))
ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
if(gpu->vendor.length > 0)
return;
pci->ffpci_lookup_name(pci->access, gpu->vendor.chars, (int) ffStrbufGetFree(&gpu->vendor), PCI_LOOKUP_VENDOR, device->vendor_id);
ffStrbufRecalculateLength(&gpu->vendor);
if(ffStrbufFirstIndexS(&gpu->vendor, "AMD") < gpu->vendor.length || ffStrbufFirstIndexS(&gpu->vendor, "ATI") < gpu->vendor.length)
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if(ffStrbufFirstIndexS(&gpu->vendor, "Intel") < gpu->vendor.length)
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if(ffStrbufFirstIndexS(&gpu->vendor, "NVIDIA") < gpu->vendor.length)
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
}
static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
FFstrbuf query;
ffStrbufInit(&query);
ffStrbufAppendF(&query, "%X, %X,", device->device_id, pci->ffpci_read_byte(device, PCI_REVISION_ID));
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/libdrm/amdgpu.ids", query.chars, &gpu->name);
ffStrbufDestroy(&query);
const char* removeStrings[] = {
"AMD ", "ATI ",
" (TM)", "(TM)",
" Graphics Adapter", " Graphics", " Series", " Edition"
};
ffStrbufRemoveStringsA(&gpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
}
static void pciDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
if(ffStrbufCompS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD) == 0)
{
drmDetectDeviceName(gpu, pci, device);
if(gpu->name.length > 0)
return;
}
pci->ffpci_lookup_name(pci->access, gpu->name.chars, (int) ffStrbufGetFree(&gpu->name), PCI_LOOKUP_DEVICE, device->vendor_id, device->device_id);
ffStrbufRecalculateLength(&gpu->name);
}
static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
const char* base = pci->ffpci_get_param(pci->access, "sysfs.path");
if(!ffStrSet(base))
return;
FFstrbuf path;
ffStrbufInitA(&path, 64);
ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func);
ffStrbufEnsureFree(&gpu->driver, 1023);
ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator
if(resultLength > 0)
{
gpu->driver.length = (uint32_t) resultLength;
gpu->driver.chars[resultLength] = '\0';
ffStrbufSubstrAfterLastC(&gpu->driver, '/');
}
ffStrbufDestroy(&path);
}
static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device)
{
const FFTempsResult* tempsResult = ffDetectTemps();
for(uint32_t i = 0; i < tempsResult->values.length; i++)
{
FFTempValue* tempValue = ffListGet(&tempsResult->values, i);
uint32_t tempClass;
if(sscanf(tempValue->deviceClass.chars, "%x", &tempClass) != 1)
continue;
//The kernel exposes the device class multiplied by 256 for some reason
if(tempClass == device->device_class * 256)
{
gpu->temperature = tempValue->value;
return;
}
}
}
static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* device)
{
device->device_class = pci->ffpci_read_word(device, PCI_CLASS_DEVICE);
char class[1024];
pci->ffpci_lookup_name(pci->access, class, sizeof(class) - 1, PCI_LOOKUP_CLASS, device->device_class);
if(
strcasecmp("VGA compatible controller", class) != 0 &&
strcasecmp("3D controller", class) != 0 &&
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);
FFGPUResult* gpu = ffListAdd(results);
ffStrbufInit(&gpu->vendor);
pciDetectVendorName(gpu, pci, device);
ffStrbufInit(&gpu->name);
pciDetectDeviceName(gpu, pci, device);
ffStrbufInit(&gpu->driver);
pciDetectDriverName(gpu, pci, device);
gpu->temperature = FF_GPU_TEMP_UNSET;
pciDetectTemperatur(gpu, device);
}
static bool pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
{
PCIData pci;
FF_LIBRARY_LOAD(libpci, instance->config.libPCI, false, "libpci.so", 4)
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_alloc, false)
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_init, false)
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_scan_bus, false)
FF_LIBRARY_LOAD_SYMBOL(libpci, pci_cleanup, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_byte, pci_read_byte, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_word, pci_read_word, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_lookup_name, pci_lookup_name, false)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_get_param, pci_get_param, false)
pci.access = ffpci_alloc();
ffpci_init(pci.access);
ffpci_scan_bus(pci.access);
struct pci_dev* device = pci.access->devices;
while(device != NULL)
{
pciHandleDevice(gpus, &pci, device);
device = device->next;
}
ffpci_cleanup(pci.access);
dlclose(libpci);
return gpus->length > 0;
}
#endif
void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
{
#ifdef FF_HAVE_LIBPCI
if(pciDetectGPUs(instance, gpus))
return;
#endif
const FFVulkanResult* vulkan = ffDetectVulkan(instance);
*gpus = vulkan->gpus;
}
+24 -18
View File
@@ -1,4 +1,8 @@
#include "fastfetch.h"
#include "detection/gtk.h"
#include "common/properties.h"
#include "common/settings.h"
#include "detection/displayserver/displayserver.h"
#include <pthread.h>
@@ -10,7 +14,7 @@ static inline bool allPropertiesSet(FFGTKResult* result)
result->font.length > 0;
}
static inline void applyGTKDConfSettings(FFGTKResult* result, const char* themeName, const char* iconsName, const char* fontName, const char* cursorTheme, int cursorSize)
static inline void applyGTKSettings(FFGTKResult* result, const char* themeName, const char* iconsName, const char* fontName, const char* cursorTheme, int cursorSize)
{
if(result->theme.length == 0)
ffStrbufAppendS(&result->theme, themeName);
@@ -28,7 +32,7 @@ static inline void applyGTKDConfSettings(FFGTKResult* result, const char* themeN
ffStrbufAppendF(&result->cursorSize, "%i", cursorSize);
}
static void detectGTKFromDConf(FFinstance* instance, FFGTKResult* result)
static void detectGTKFromSettings(FFinstance* instance, FFGTKResult* result)
{
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -45,7 +49,7 @@ static void detectGTKFromDConf(FFinstance* instance, FFGTKResult* result)
if(init)
{
pthread_mutex_unlock(&mutex);
applyGTKDConfSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
return;
}
@@ -53,7 +57,15 @@ static void detectGTKFromDConf(FFinstance* instance, FFGTKResult* result)
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0)
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Xfce") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Xfce4") == 0)
{
themeName = ffSettingsGetXFConf(instance, "xsettings", "/Net/ThemeName", FF_VARIANT_TYPE_STRING).strValue;
iconsName = ffSettingsGetXFConf(instance, "xsettings", "/Net/IconThemeName", FF_VARIANT_TYPE_STRING).strValue;
fontName = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/FontName", FF_VARIANT_TYPE_STRING).strValue;
cursorTheme = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue;
cursorSize = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue;
}
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0)
{
themeName = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/gtk-theme", "org.cinnamon.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
iconsName = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/icon-theme", "org.cinnamon.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
@@ -69,7 +81,7 @@ static void detectGTKFromDConf(FFinstance* instance, FFGTKResult* result)
cursorTheme = ffSettingsGet(instance, "/org/mate/peripherals-mouse/cursor-theme", "org.mate.peripherals-mouse", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
cursorSize = ffSettingsGet(instance, "/org/mate/peripherals-mouse/cursor-size", "org.mate.peripherals-mouse", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
}
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Gnome") == 0)
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Gnome") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Unity") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Budgie") == 0)
{
themeName = ffSettingsGet(instance, "/org/gnome/desktop/interface/gtk-theme", "org.gnome.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
iconsName = ffSettingsGet(instance, "/org/gnome/desktop/interface/icon-theme", "org.gnome.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
@@ -79,7 +91,7 @@ static void detectGTKFromDConf(FFinstance* instance, FFGTKResult* result)
}
pthread_mutex_unlock(&mutex);
applyGTKDConfSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
}
static void detectGTKFromConfigFile(const char* filename, FFGTKResult* result)
@@ -95,11 +107,6 @@ static void detectGTKFromConfigFile(const char* filename, FFGTKResult* result)
static void detectGTKFromConfigDir(FFstrbuf* configDir, const char* version, FFGTKResult* result)
{
//In case of an empty env variable
ffStrbufTrim(configDir, ' ');
if(configDir->length == 0)
return;
uint32_t configDirLength = configDir->length;
// <configdir>/gtk-<version>.0/settings.ini
@@ -139,6 +146,12 @@ static void detectGTKFromConfigDir(FFstrbuf* configDir, const char* version, FFG
static void detectGTK(FFinstance* instance, const char* version, FFGTKResult* result)
{
//Mate, Cinnamon and Gnome use dconf to save theme config
//On other DEs, this will do nothing
detectGTKFromSettings(instance, result);
if(allPropertiesSet(result))
return;
//We need to do this because we use multiple threads on configDirs
FFstrbuf baseDir;
ffStrbufInitA(&baseDir, 64);
@@ -152,13 +165,6 @@ static void detectGTK(FFinstance* instance, const char* version, FFGTKResult* re
}
ffStrbufDestroy(&baseDir);
if(allPropertiesSet(result))
return;
//Mate, Cinnamon and Gnome use dconf to save theme config
//On other DEs, this will do nothing
detectGTKFromDConf(instance, result);
}
#define FF_DETECT_GTK_IMPL(version) \
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#ifndef FF_INCLUDED_detection_gtk
#define FF_INCLUDED_detection_gtk
#include "fastfetch.h"
typedef struct FFGTKResult
{
FFstrbuf theme;
FFstrbuf icons;
FFstrbuf font;
FFstrbuf cursor;
FFstrbuf cursorSize;
} FFGTKResult;
const FFGTKResult* ffDetectGTK2(FFinstance* instance);
const FFGTKResult* ffDetectGTK4(FFinstance* instance);
const FFGTKResult* ffDetectGTK3(FFinstance* instance);
#endif
+11
View File
@@ -0,0 +1,11 @@
#include "host.h"
#include "detection/internal.h"
void ffDetectHostImpl(FFHostResult* host);
const FFHostResult* ffDetectHost()
{
FF_DETECTION_INTERNAL_GUARD(FFHostResult,
ffDetectHostImpl(&result)
);
}
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#ifndef FF_INCLUDED_detection_host_host
#define FF_INCLUDED_detection_host_host
#include "fastfetch.h"
#define FF_HOST_PRODUCT_NAME_WSL "Windows Subsystem for Linux"
typedef struct FFHostResult
{
FFstrbuf productFamily;
FFstrbuf productName;
FFstrbuf productVersion;
FFstrbuf productSku;
FFstrbuf biosDate;
FFstrbuf biosRelease;
FFstrbuf biosVendor;
FFstrbuf biosVersion;
FFstrbuf boardName;
FFstrbuf boardVendor;
FFstrbuf boardVersion;
FFstrbuf chassisType;
FFstrbuf chassisVendor;
FFstrbuf chassisVersion;
FFstrbuf sysVendor;
} FFHostResult;
const FFHostResult* ffDetectHost();
#endif
+45
View File
@@ -0,0 +1,45 @@
#include "host.h"
#include "common/settings.h"
#include <ctype.h>
void ffDetectHostImpl(FFHostResult* host)
{
//Family
ffStrbufInit(&host->productFamily);
ffSettingsGetAndroidProperty("ro.product.device", &host->productFamily);
//Name
ffStrbufInit(&host->productName);
ffSettingsGetAndroidProperty("ro.product.brand", &host->productName);
if(host->productName.length > 0){
host->productName.chars[0] = (char) toupper(host->productName.chars[0]);
ffStrbufAppendC(&host->productName, ' ');
}
ffSettingsGetAndroidProperty("ro.product.model", &host->productName);
ffStrbufTrimRight(&host->productName, ' ');
//Sys vendor
ffStrbufInit(&host->sysVendor);
ffSettingsGetAndroidProperty("ro.product.manufacturer", &host->sysVendor);
//Not implemented
ffStrbufInitA(&host->productVersion, 0);
ffStrbufInitA(&host->productSku, 0);
ffStrbufInitA(&host->biosDate, 0);
ffStrbufInitA(&host->biosRelease, 0);
ffStrbufInitA(&host->biosVendor, 0);
ffStrbufInitA(&host->biosVersion, 0);
ffStrbufInitA(&host->boardName, 0);
ffStrbufInitA(&host->boardVendor, 0);
ffStrbufInitA(&host->boardVersion, 0);
ffStrbufInitA(&host->chassisType, 0);
ffStrbufInitA(&host->chassisVendor, 0);
ffStrbufInitA(&host->chassisVersion, 0);
}
+24
View File
@@ -0,0 +1,24 @@
#include "host.h"
#include "common/settings.h"
void ffDetectHostImpl(FFHostResult* host)
{
ffStrbufInit(&host->productName);
ffStrbufInitA(&host->productFamily, 0);
ffStrbufInitA(&host->sysVendor, 0);
ffStrbufInitA(&host->productVersion, 0);
ffStrbufInitA(&host->productSku, 0);
ffStrbufInitA(&host->biosDate, 0);
ffStrbufInitA(&host->biosRelease, 0);
ffStrbufInitA(&host->biosVendor, 0);
ffStrbufInitA(&host->biosVersion, 0);
ffStrbufInitA(&host->boardName, 0);
ffStrbufInitA(&host->boardVendor, 0);
ffStrbufInitA(&host->boardVersion, 0);
ffStrbufInitA(&host->chassisType, 0);
ffStrbufInitA(&host->chassisVendor, 0);
ffStrbufInitA(&host->chassisVersion, 0);
ffSettingsGetAppleProperty("hw.model", &host->productName);
}
+118
View File
@@ -0,0 +1,118 @@
#include "host.h"
#include "common/io.h"
#include <stdlib.h>
static bool hostValueSet(FFstrbuf* value)
{
return
value->length > 0 &&
ffStrbufStartsWithIgnCaseS(value, "To be filled") != true &&
ffStrbufStartsWithIgnCaseS(value, "To be set") != true &&
ffStrbufStartsWithIgnCaseS(value, "OEM") != true &&
ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true &&
ffStrbufIgnCaseCompS(value, "None") != 0 &&
ffStrbufIgnCaseCompS(value, "System Product") != 0 &&
ffStrbufIgnCaseCompS(value, "System Product Name") != 0 &&
ffStrbufIgnCaseCompS(value, "System Product Version") != 0 &&
ffStrbufIgnCaseCompS(value, "System Name") != 0 &&
ffStrbufIgnCaseCompS(value, "System Version") != 0 &&
ffStrbufIgnCaseCompS(value, "Default string") != 0 &&
ffStrbufIgnCaseCompS(value, "Undefined") != 0 &&
ffStrbufIgnCaseCompS(value, "Not Specified") != 0 &&
ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 &&
ffStrbufIgnCaseCompS(value, "INVALID") != 0 &&
ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 &&
ffStrbufIgnCaseCompS(value, "All Series") != 0
;
}
static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer)
{
ffReadFileBuffer(devicesPath, buffer);
if(hostValueSet(buffer))
return;
ffReadFileBuffer(classPath, buffer);
if(hostValueSet(buffer))
return;
ffStrbufClear(buffer);
}
static void getHostProductName(FFstrbuf* name)
{
getHostValue("/sys/devices/virtual/dmi/id/product_name", "/sys/class/dmi/id/product_name", name);
if(name->length > 0)
return;
ffReadFileBuffer("/sys/firmware/devicetree/base/model", name);
if(hostValueSet(name))
return;
//does a clear before the read
ffReadFileBuffer("/tmp/sysinfo/model", name);
if(hostValueSet(name))
return;
ffStrbufClear(name);
}
void ffDetectHostImpl(FFHostResult* host)
{
ffStrbufInit(&host->productFamily);
getHostValue("/sys/devices/virtual/dmi/id/product_family", "/sys/class/dmi/id/product_family", &host->productFamily);
ffStrbufInit(&host->productName);
getHostProductName(&host->productName);
ffStrbufInit(&host->productVersion);
getHostValue("/sys/devices/virtual/dmi/id/product_version", "/sys/class/dmi/id/product_version", &host->productVersion);
ffStrbufInit(&host->productSku);
getHostValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku);
ffStrbufInit(&host->biosDate);
getHostValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &host->biosDate);
ffStrbufInit(&host->biosRelease);
getHostValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &host->biosRelease);
ffStrbufInit(&host->biosVendor);
getHostValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &host->biosVendor);
ffStrbufInit(&host->biosVersion);
getHostValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &host->biosVersion);
ffStrbufInit(&host->boardName);
getHostValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &host->boardName);
ffStrbufInit(&host->boardVendor);
getHostValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &host->boardVendor);
ffStrbufInit(&host->boardVersion);
getHostValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &host->boardVersion);
ffStrbufInit(&host->chassisType);
getHostValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &host->chassisType);
ffStrbufInit(&host->chassisVendor);
getHostValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &host->chassisVendor);
ffStrbufInit(&host->chassisVersion);
getHostValue("/sys/devices/virtual/dmi/id/chassis_version", "/sys/class/dmi/id/chassis_version", &host->chassisVersion);
ffStrbufInit(&host->sysVendor);
getHostValue("/sys/devices/virtual/dmi/id/sys_vendor", "/sys/class/dmi/id/sys_vendor", &host->sysVendor);
//KVM/Qemu virtual machine
if(ffStrbufStartsWithS(&host->productName, "Standard PC"))
ffStrbufPrependS(&host->productName, "KVM/QEMU ");
//On WSL, the real host can't be detected. Instead use WSL as host.
if(host->productFamily.length == 0 && host->productName.length == 0 && (
getenv("WSLENV") != NULL ||
getenv("WSL_DISTRO") != NULL ||
getenv("WSL_INTEROP") != NULL
)) ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_WSL);
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#ifndef FF_INCLUDED_detection_internal
#define FF_INCLUDED_detection_internal
#include "pthread.h"
#define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
static ResultType result; \
static bool init = false; \
pthread_mutex_lock(&mutex); \
if(init) \
{ \
pthread_mutex_unlock(&mutex); \
return &result; \
} \
init = true; \
__VA_ARGS__; \
pthread_mutex_unlock(&mutex); \
return &result; \
#endif
+3 -1
View File
@@ -1,4 +1,5 @@
#include "fastfetch.h"
#include "detection/media.h"
#include <string.h>
#include <pthread.h>
@@ -7,7 +8,8 @@
#define FF_DBUS_TIMEOUT_MILLISECONDS 35
#ifdef FF_HAVE_DBUS
#include <dlfcn.h>
#include "common/library.h"
#include "common/parsing.h"
#include <dbus/dbus.h>
#define FF_DBUS_ITER_CONTINUE(iterator) \
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#ifndef FF_INCLUDED_detection_media
#define FF_INCLUDED_detection_media
#include "fastfetch.h"
typedef struct FFMediaResult
{
FFstrbuf busNameShort; //e.g. plasma-browser-integration
FFstrbuf player; // e.g. Google Chrome
FFstrbuf song;
FFstrbuf artist;
FFstrbuf album;
FFstrbuf url;
} FFMediaResult;
const FFMediaResult* ffDetectMedia(FFinstance* instance);
#endif
+16
View File
@@ -0,0 +1,16 @@
#include "memory.h"
#include "detection/internal.h"
void ffDetectMemoryImpl(FFMemoryResult* memory);
const FFMemoryResult* ffDetectMemory()
{
FF_DETECTION_INTERNAL_GUARD(FFMemoryResult,
ffDetectMemoryImpl(&result);
if(result.bytesTotal > 0)
result.percentage = (uint8_t) ((result.bytesUsed / (long double) result.bytesTotal) * 100.0);
else
result.percentage = 0;
);
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#ifndef FF_INCLUDED_detection_memory_memory
#define FF_INCLUDED_detection_memory_memory
#include "fastfetch.h"
typedef struct FFMemoryResult
{
uint64_t bytesUsed;
uint64_t bytesTotal;
uint8_t percentage;
} FFMemoryResult;
const FFMemoryResult* ffDetectMemory();
#endif
+22
View File
@@ -0,0 +1,22 @@
#include "memory.h"
#include "common/settings.h"
#include <mach/mach.h>
void ffDetectMemoryImpl(FFMemoryResult* memory)
{
memory->bytesTotal = (uint64_t) ffSettingsGetAppleInt64("hw.memsize", 0);
memory->bytesUsed = 0;
uint32_t pagesize = (uint32_t) ffSettingsGetAppleInt("hw.pagesize", 0);
if(pagesize == 0)
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)
return;
memory->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * pagesize;
}
+41
View File
@@ -0,0 +1,41 @@
#include "memory.h"
#include <stdlib.h>
void ffDetectMemoryImpl(FFMemoryResult* memory)
{
memory->bytesUsed = 0;
memory->bytesTotal = 0;
FILE* meminfo = fopen("/proc/meminfo", "r");
if(meminfo == NULL)
return;
char* line = NULL;
size_t len = 0;
uint32_t memTotal = 0,
shmem = 0,
memFree = 0,
buffers = 0,
cached = 0,
sReclaimable = 0;
while (getline(&line, &len, meminfo) != EOF)
{
sscanf(line, "MemTotal: %u", &memTotal);
sscanf(line, "Shmem: %u", &shmem);
sscanf(line, "MemFree: %u", &memFree);
sscanf(line, "Buffers: %u", &buffers);
sscanf(line, "Cached: %u", &cached);
sscanf(line, "SReclaimable: %u", &sReclaimable);
}
if(line != NULL)
free(line);
fclose(meminfo);
memory->bytesTotal = memTotal * (uint64_t) 1024;
memory->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024;
}
+11
View File
@@ -0,0 +1,11 @@
#include "os.h"
#include "detection/internal.h"
void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance);
const FFOSResult* ffDetectOS(const FFinstance* instance)
{
FF_DETECTION_INTERNAL_GUARD(FFOSResult,
ffDetectOSImpl(&result, instance)
);
}
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#ifndef FF_INCLUDED_detection_os_os
#define FF_INCLUDED_detection_os_os
#include "fastfetch.h"
typedef struct FFOSResult
{
FFstrbuf name;
FFstrbuf prettyName;
FFstrbuf id;
FFstrbuf idLike;
FFstrbuf variant;
FFstrbuf variantID;
FFstrbuf version;
FFstrbuf versionID;
FFstrbuf codename;
FFstrbuf buildID;
FFstrbuf systemName;
FFstrbuf architecture;
} FFOSResult;
const FFOSResult* ffDetectOS(const FFinstance* instance);
#endif
+38
View File
@@ -0,0 +1,38 @@
#include "os.h"
#include "common/settings.h"
void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
{
FF_UNUSED(instance);
ffStrbufInit(&os->name);
ffStrbufSetS(&os->name, "Android");
ffStrbufInit(&os->prettyName);
ffStrbufSetS(&os->prettyName, "Android");
ffStrbufInit(&os->id);
ffStrbufSetS(&os->id, "android");
ffStrbufInit(&os->version);
ffSettingsGetAndroidProperty("ro.build.version.release", &os->version);
ffStrbufInit(&os->versionID);
ffSettingsGetAndroidProperty("ro.build.version.release", &os->versionID);
ffStrbufInit(&os->codename);
ffSettingsGetAndroidProperty("ro.build.version.codename", &os->codename);
ffStrbufInit(&os->buildID);
ffSettingsGetAndroidProperty("ro.build.id", &os->buildID);
ffStrbufInit(&os->systemName);
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
ffStrbufInit(&os->architecture);
ffStrbufSetS(&os->architecture, instance->state.utsname.machine);
ffStrbufInitA(&os->idLike, 0);
ffStrbufInitA(&os->variant, 0);
ffStrbufInitA(&os->variantID, 0);
}
+93
View File
@@ -0,0 +1,93 @@
#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);
}
@@ -1,16 +1,20 @@
#include "fastfetch.h"
#include "os.h"
#include "common/properties.h"
#include "common/parsing.h"
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#if !defined(__ANDROID__)
static inline bool allRelevantValuesSet(const FFOSResult* result)
{
return result->id.length > 0
&& result->name.length > 0
&& result->prettyName.length > 0
;
}
static bool parseFile(const char* fileName, FFOSResult* result)
{
if(result->id.length > 0 && result->name.length > 0 && result->prettyName.length > 0)
return true;
return ffParsePropFileValues(fileName, 13, (FFpropquery[]) {
{"NAME =", &result->name},
{"DISTRIB_DESCRIPTION =", &result->prettyName},
@@ -89,73 +93,59 @@ static void getUbuntuFlavour(FFOSResult* result)
}
}
#endif
const FFOSResult* ffDetectOS(const FFinstance* instance)
static void detectOS(FFOSResult* os, const FFinstance* instance)
{
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFOSResult result;
static bool init = false;
pthread_mutex_lock(&mutex);
if(init)
{
pthread_mutex_unlock(&mutex);
return &result;
}
init = true;
ffStrbufInit(&result.systemName);
ffStrbufInit(&result.name);
ffStrbufInit(&result.prettyName);
ffStrbufInit(&result.id);
ffStrbufInit(&result.idLike);
ffStrbufInit(&result.variant);
ffStrbufInit(&result.variantID);
ffStrbufInit(&result.version);
ffStrbufInit(&result.versionID);
ffStrbufInit(&result.codename);
ffStrbufInit(&result.buildID);
ffStrbufInit(&result.architecture);
ffStrbufSetS(&result.systemName, instance->state.utsname.sysname);
ffStrbufSetS(&result.architecture, instance->state.utsname.machine);
#if !__ANDROID__
if(instance->config.osFile.length > 0)
{
parseFile(instance->config.osFile.chars, &result);
parseFile(instance->config.osFile.chars, os);
return;
}
else if(instance->config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock/etc/bedrock-release", &result))
if(instance->config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock/etc/bedrock-release", os))
{
if(result.id.length == 0)
ffStrbufAppendS(&result.id, "bedrock");
if(os->id.length == 0)
ffStrbufAppendS(&os->id, "bedrock");
if(result.name.length == 0)
ffStrbufAppendS(&result.name, "Bedrock");
if(os->name.length == 0)
ffStrbufAppendS(&os->name, "Bedrock");
if(result.prettyName.length == 0)
ffStrbufAppendS(&result.prettyName, "Bedrock Linux");
}
else
{
parseFile(FASTFETCH_TARGET_DIR_ROOT"/etc/os-release", &result);
parseFile(FASTFETCH_TARGET_DIR_USR"/lib/os-release", &result);
parseFile(FASTFETCH_TARGET_DIR_ROOT"/etc/lsb-release", &result);
if(os->prettyName.length == 0)
ffStrbufAppendS(&os->prettyName, "Bedrock Linux");
return;
}
if(ffStrbufIgnCaseCompS(&result.id, "ubuntu") == 0)
getUbuntuFlavour(&result);
parseFile(FASTFETCH_TARGET_DIR_ROOT"/etc/os-release", os);
if(allRelevantValuesSet(os))
return;
#else
ffStrbufSetS(&result.name, "Android");
ffStrbufSetS(&result.id, "android");
ffSettingsGetAndroidProperty("ro.build.version.release", &result.versionID);
ffSettingsGetAndroidProperty("ro.build.version.release", &result.version);
ffSettingsGetAndroidProperty("ro.build.version.codename", &result.codename);
ffSettingsGetAndroidProperty("ro.build.id", &result.buildID);
#endif
parseFile(FASTFETCH_TARGET_DIR_USR"/lib/os-release", os);
if(allRelevantValuesSet(os))
return;
pthread_mutex_unlock(&mutex);
return &result;
parseFile(FASTFETCH_TARGET_DIR_ROOT"/etc/lsb-release", os);
}
void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
{
ffStrbufInit(&os->name);
ffStrbufInit(&os->prettyName);
ffStrbufInit(&os->id);
ffStrbufInit(&os->idLike);
ffStrbufInit(&os->variant);
ffStrbufInit(&os->variantID);
ffStrbufInit(&os->version);
ffStrbufInit(&os->versionID);
ffStrbufInit(&os->codename);
ffStrbufInit(&os->buildID);
ffStrbufInit(&os->systemName);
ffStrbufInit(&os->architecture);
ffStrbufSetS(&os->systemName, instance->state.utsname.sysname);
ffStrbufSetS(&os->architecture, instance->state.utsname.machine);
detectOS(os, instance);
if(ffStrbufIgnCaseCompS(&os->id, "ubuntu") == 0)
getUbuntuFlavour(os);
}
+71 -51
View File
@@ -1,9 +1,21 @@
#include "fastfetch.h"
#include "detection/qt.h"
#include "common/properties.h"
#include "detection/displayserver/displayserver.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
static inline bool allValuesSet(const FFQtResult* result)
{
return
result->widgetStyle.length > 0 &&
result->colorScheme.length > 0 &&
result->icons.length > 0 &&
result->font.length > 0;
}
typedef enum PlasmaCategory
{
PLASMA_CATEGORY_GENERAL,
@@ -12,7 +24,7 @@ typedef enum PlasmaCategory
PLASMA_CATEGORY_OTHER
} PlasmaCategory;
static bool detectFromConfigFile(const char* filename, FFPlasmaResult* result)
static bool detectPlasmaFromFile(const char* filename, FFQtResult* result)
{
FILE* kdeglobals = fopen(filename, "r");
if(kdeglobals == NULL)
@@ -68,10 +80,62 @@ static bool detectFromConfigFile(const char* filename, FFPlasmaResult* result)
return true;
}
const FFPlasmaResult* ffDetectPlasma(FFinstance* instance)
static void detectPlasma(const FFinstance* instance, FFQtResult* result)
{
bool foundAFile = false;
//We need to do this because we use multiple threads on configDirs
FFstrbuf baseDir;
ffStrbufInitA(&baseDir, 64);
for(uint32_t i = 0; i < instance->state.configDirs.length; i++)
{
ffStrbufSet(&baseDir, ffListGet(&instance->state.configDirs, i));
ffStrbufAppendS(&baseDir, "kdeglobals");
if(detectPlasmaFromFile(baseDir.chars, result))
foundAFile = true;
if(allValuesSet(result))
{
ffStrbufDestroy(&baseDir);
return;
}
}
ffStrbufDestroy(&baseDir);
if(!foundAFile)
return;
//In Plasma the default value is never set in the config file, but the whole key-value is discarded.
///We must set these values by our self if the file exists (it always does here)
if(result->widgetStyle.length == 0)
ffStrbufAppendS(&result->widgetStyle, "Breeze");
if(result->colorScheme.length == 0)
ffStrbufAppendS(&result->colorScheme, "BreezeLight");
if(result->icons.length == 0)
ffStrbufAppendS(&result->icons, "Breeze");
if(result->font.length == 0)
ffStrbufAppendS(&result->font, "Noto Sans, 10");
}
static void detectLXQt(const FFinstance* instance, FFQtResult* result)
{
ffParsePropFileConfigValues(instance, "lxqt/lxqt.conf", 3, (FFpropquery[]) {
{"style = ", &result->widgetStyle},
{"icon_theme = ", &result->icons},
{"font = ", &result->font}
});
}
const FFQtResult* ffDetectQt(FFinstance* instance)
{
static FFQtResult result;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static FFPlasmaResult result;
static bool init = false;
pthread_mutex_lock(&mutex);
if(init)
@@ -87,55 +151,11 @@ const FFPlasmaResult* ffDetectPlasma(FFinstance* instance)
ffStrbufInit(&result.font);
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
if(ffStrbufIgnCaseCompS(&wmde->deProcessName, "plasmashell") != 0)
{
pthread_mutex_unlock(&mutex);
return &result;
}
bool foundAFile = false;
//We need to do this because we use multiple threads on configDirs
FFstrbuf baseDir;
ffStrbufInitA(&baseDir, 64);
for(uint32_t i = 0; i < instance->state.configDirs.length; i++)
{
ffStrbufSet(&baseDir, ffListGet(&instance->state.configDirs, i));
ffStrbufAppendS(&baseDir, "kdeglobals");
if(detectFromConfigFile(baseDir.chars, &result))
foundAFile = true;
if(
result.widgetStyle.length > 0 &&
result.colorScheme.length > 0 &&
result.icons.length > 0 &&
result.font.length > 0
) break;
}
ffStrbufDestroy(&baseDir);
if(!foundAFile)
{
pthread_mutex_unlock(&mutex);
return &result;
}
//In Plasma the default value is never set in the config file, but the whole key-value is discarded.
///We must set these values by our self if the file exists (it always does here)
if(result.widgetStyle.length == 0)
ffStrbufAppendS(&result.widgetStyle, "Breeze");
if(result.colorScheme.length == 0)
ffStrbufAppendS(&result.colorScheme, "BreezeLight");
if(result.icons.length == 0)
ffStrbufAppendS(&result.icons, "Breeze");
if(result.font.length == 0)
ffStrbufAppendS(&result.font, "Noto Sans, 10");
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "KDE Plasma") == 0)
detectPlasma(instance, &result);
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "LXQt") == 0)
detectLXQt(instance, &result);
pthread_mutex_unlock(&mutex);
return &result;
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#ifndef FF_INCLUDED_detection_qt
#define FF_INCLUDED_detection_qt
#include "fastfetch.h"
typedef struct FFQtResult
{
FFstrbuf widgetStyle;
FFstrbuf colorScheme;
FFstrbuf icons;
FFstrbuf font;
} FFQtResult;
const FFQtResult* ffDetectQt(FFinstance* instance);
#endif
+3 -3
View File
@@ -1,4 +1,6 @@
#include "fastfetch.h"
#include "detection/temps.h"
#include "common/io.h"
#include <string.h>
#include <pthread.h>
@@ -61,10 +63,8 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
return value->name.length > 0 || value->deviceClass.length > 0;
}
const FFTempsResult* ffDetectTemps(const FFinstance* instance)
const FFTempsResult* ffDetectTemps()
{
FF_UNUSED(instance)
static FFTempsResult result;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static bool init = false;
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#ifndef FF_INCLUDED_detection_temps
#define FF_INCLUDED_detection_temps
#include "fastfetch.h"
typedef struct FFTempValue
{
FFstrbuf name;
FFstrbuf deviceClass;
double value;
} FFTempValue;
typedef struct FFTempsResult
{
FFlist values; //List of FFTempValue
} FFTempsResult;
const FFTempsResult* ffDetectTemps();
#endif
+15 -6
View File
@@ -1,4 +1,8 @@
#include "fastfetch.h"
#include "detection/terminalshell.h"
#include "common/io.h"
#include "common/parsing.h"
#include "common/processing.h"
#include <ctype.h>
#include <string.h>
@@ -69,12 +73,13 @@ static void getTerminalShell(FFTerminalShellResult* result, const char* pid)
//Common programs that are between terminal and own process, but are not the shell
if(
strcasecmp(name, "sudo") == 0 ||
strcasecmp(name, "su") == 0 ||
strcasecmp(name, "doas") == 0 ||
strcasecmp(name, "strace") == 0 ||
strcasecmp(name, "sshd") == 0 ||
strcasecmp(name, "gdb") == 0
strcasecmp(name, "sudo") == 0 ||
strcasecmp(name, "su") == 0 ||
strcasecmp(name, "doas") == 0 ||
strcasecmp(name, "strace") == 0 ||
strcasecmp(name, "sshd") == 0 ||
strcasecmp(name, "gdb") == 0 ||
strcasecmp(name, "guake-wrapped") == 0
) {
getTerminalShell(result, ppid);
return;
@@ -132,6 +137,10 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
getenv("TMUX_TMPDIR") != NULL
)) term = "Termux";
//MacOS
if(!ffStrSet(term))
term = getenv("TERM_PROGRAM");
//Normal Terminal
if(!ffStrSet(term))
term = getenv("TERM");
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#ifndef FF_INCLUDED_detection_terminalshell
#define FF_INCLUDED_detection_terminalshell
#include "fastfetch.h"
typedef struct FFTerminalShellResult
{
FFstrbuf shellProcessName;
FFstrbuf shellExe;
const char* shellExeName; //pointer to a char in shellExe
FFstrbuf shellVersion;
FFstrbuf terminalProcessName;
FFstrbuf terminalExe;
const char* terminalExeName; //pointer to a char in terminalExe
FFstrbuf userShellExe;
const char* userShellExeName; //pointer to a char in userShellExe
FFstrbuf userShellVersion;
} FFTerminalShellResult;
const FFTerminalShellResult* ffDetectTerminalShell(FFinstance* instance);
#endif
+60
View File
@@ -0,0 +1,60 @@
#include "fastfetch.h"
#include "detection/title.h"
#include <limits.h>
#include <unistd.h>
#include <pthread.h>
#include <netdb.h>
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 64
#endif
const FFTitleResult* ffDetectTitle(const FFinstance* instance)
{
static FFTitleResult 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.userName);
ffStrbufAppendS(&result.userName, instance->state.passwd->pw_name);
ffStrbufInitA(&result.hostname, HOST_NAME_MAX);
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);
}
#endif
if(result.fqdn.length == 0)
ffStrbufAppend(&result.fqdn, &result.hostname);
pthread_mutex_unlock(&mutex);
return &result;
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#ifndef FF_INCLUDED_detection_title
#define FF_INCLUDED_detection_title
#include "fastfetch.h"
typedef struct FFTitleResult
{
FFstrbuf userName;
FFstrbuf hostname;
FFstrbuf fqdn; //Fully qualified domain name
} FFTitleResult;
const FFTitleResult* ffDetectTitle(const FFinstance* instance);
#endif

Some files were not shown because too many files have changed in this diff Show More