Compare commits

...

190 Commits

Author SHA1 Message Date
李通洲 92588e1159 Fastfetch: fix memory leaks 2023-07-05 10:05:24 +08:00
李通洲 948a480859 Release: v1.12.2 2023-07-05 09:44:44 +08:00
李通洲 ee90d886ab Packages (Linux): print pkgtool package count in custom module format mode 2023-07-05 09:43:52 +08:00
李通洲 f74c643a84 Host (macOS): fix incorrect Host on M2 Mac Studio with M2 Max CPU (#490) 2023-07-05 09:39:16 +08:00
李通洲 03efbe5f6a TerminalShell (Windows): fix #488 2023-07-05 09:39:16 +08:00
李通洲 085479a923 Shell (Windows): fallback shell version detection to file version 2023-07-05 09:39:16 +08:00
李通洲 482b15c62e Packages (Linux): try detecting pkgtool
fix #486
2023-07-05 09:18:00 +08:00
李通洲 1f5da2736e Terminal (Linux): support terminator version detection 2023-07-05 09:12:37 +08:00
李通洲 55234ff1f3 Doc: add CI badge 2023-07-05 09:12:29 +08:00
李通洲 ebbadbed4f Bios (macOS): fix compiling error on Apple Slicon 2023-07-03 15:31:33 +08:00
Linus Dierheimer e7474bda1f Adapt to new repository url 2023-07-02 17:04:46 +08:00
李通洲 fa8bfd08f9 Release: v1.12.0 2023-07-02 13:58:11 +08:00
李通洲 11827d64be TerminalShell: fix compiling on macOS 2023-07-02 13:54:31 +08:00
李通洲 47ac01c8e1 Global: fix compiling 2023-07-02 11:10:12 +08:00
李通洲 23c8937362 fix(Shell): fix shell version printing 2023-07-02 11:04:38 +08:00
李通洲 ad3b7762a3 GPU: fix #484 2023-07-02 11:04:38 +08:00
李通洲 b6c5f49650 GPU (Windows): more strict check 2023-07-02 11:04:38 +08:00
李通洲 5b6416e13c CMake (Windows): remove an unused dependency 2023-07-02 11:04:38 +08:00
李通洲 9d4ec4ca65 Bios (macOS): support bios date detection 2023-07-02 11:04:38 +08:00
李通洲 4652002e8c FFPlatform: fix ffPlatformPathAddEnv on Windows 2023-07-02 11:04:38 +08:00
李通洲 2729d72c68 GPU (macOS): remove an unused #include 2023-07-02 11:04:38 +08:00
Carter Li c18bcd316d GPU (macOS): fix typo 2023-07-02 11:04:38 +08:00
Carter Li 8fd30e814a GPU (macOS): fix vendor detection for Intel GPU 2023-07-02 11:04:38 +08:00
李通洲 b1b637fe2f OS (Windows): code refactor; fix common/library.h usage for C++ 2023-07-02 11:04:38 +08:00
李通洲 86806b64a2 CI (FreeBSD): build with libpulse support 2023-07-02 11:04:38 +08:00
Carter Li 96a8548c59 DisplayServer: dirty hack for #477 2023-07-02 11:04:38 +08:00
Carter Li c7becf82bd DisplayServer (Wayland): warn if some properties of wl_output_listener are not supported 2023-07-02 11:04:38 +08:00
李通洲 2d80085d6e Logo (Windows): make Windows logos colorable 2023-07-02 11:04:38 +08:00
Carter Li e63669bea3 Logo: more BSD logos 2023-07-02 11:04:38 +08:00
Carter Li 9568eb8dd3 TerminalFont (FreeBSD): fix gnome-terminal font detection 2023-07-02 11:04:38 +08:00
Carter Li a63925483c Terminal (Linux): print gnome-terminal-server as gnome-terminal 2023-07-02 11:04:38 +08:00
Carter Li 67689f9229 Terminal (FreeBSD): fix Gnome Terminal version detetion on FreeBSD 2023-07-02 11:04:38 +08:00
李通洲 161f86eb45 DisplayServer (Linux): add fast path of kde version detection for Fedora 2023-07-02 11:04:38 +08:00
李通洲 1994219531 DisplayServer (Linux): mark plasmashell --version as slow operation
It costs more than 1 sec some time
2023-07-02 11:04:38 +08:00
李通洲 2ec0353423 Disk (Android): actually detect something 2023-07-02 10:35:33 +08:00
Carter Li 8088905721 Host (macOS): update newest product name data 2023-07-02 10:34:33 +08:00
Carter Li ec049fd490 Fastfetch: set pipe=true automatically if stdout is not a tty 2023-07-02 10:34:12 +08:00
李通洲 033cced5a9 CMake (Windows): silence compiler warnings 2023-07-02 10:32:25 +08:00
李通洲 a059c55f05 Memory (FreeBSD): count cached memory as free memory
As what neofetch did
2023-07-02 10:30:21 +08:00
李通洲 0b00b5ffe0 FreeBSD (CPU): fix temperature detection 2023-07-02 10:29:16 +08:00
李通洲 6e7a6174ba Disk (Linux): don't detect WSL drives as subvolumes 2023-07-02 10:27:36 +08:00
李通洲 07eddf9772 GPU (Linux): always initialize variables 2023-07-02 10:26:32 +08:00
李通洲 c451a377c9 CMake: make some serious warnings as errors 2023-07-02 10:25:41 +08:00
Linus Dierheimer e5de3a90c6 Remove debug statement 2023-07-02 10:24:40 +08:00
Linus Dierheimer 7aecf385e2 Include limits.h when needed
Fixes #472
2023-07-02 10:24:22 +08:00
李通洲 1de049bdf5 Wallpaper (Linux): support Cinnamon 2023-07-02 10:23:00 +08:00
李通洲 55b8c0947b Wallpaper (Linux): support MATE 2023-07-02 10:22:50 +08:00
李通洲 51ba806e6d TerminalFont (Linux): support MATE Terminal 2023-07-02 10:21:51 +08:00
李通洲 ae2855d123 Terminal (Linux): support MATE terminal version detection 2023-07-02 10:21:39 +08:00
李通洲 9000432b52 Wallpaper (Linux): fix xfce wallpaper detection on my laptop 2023-07-02 10:21:28 +08:00
李通洲 618e5f01df Wallpaper (Linux): support lxqt 2023-07-02 10:21:19 +08:00
李通洲 0486ad8da7 TerminalFont (Linux): support QTerminal 2023-07-02 10:21:00 +08:00
李通洲 d23831465a Terminal: support qterminal version detection 2023-07-02 10:20:24 +08:00
李通洲 6ba95d7017 Wallpaper (Linux): support KDE 2023-07-02 10:20:00 +08:00
李通洲 6acfc1b715 DE: fix KDE version detection on Fedora 2023-07-02 10:18:18 +08:00
李通洲 af2e9a9a78 Logo: fix paddingLeft doesn't work when paddingTop is set 2023-07-02 10:17:12 +08:00
李通洲 af33627c4c DisplayServer: fix typos. 2023-07-02 10:13:46 +08:00
Carter Li be60eaf7c8 Merge pull request #468 from LinusDierheimer/dev
Release 1.11.3
2023-06-09 22:34:25 +08:00
李通洲 2235c3e8e4 Release 1.11.3 2023-06-09 22:32:02 +08:00
李通洲 68ae9248a6 Settings: try fixing #467 2023-06-09 22:14:29 +08:00
李通洲 b9742642fc Release 1.11.2 before merging #432 2023-06-09 11:31:36 +08:00
李通洲 356c905703 DisplayServer (macOS): add a missing variable initialization 2023-06-09 11:07:06 +08:00
李通洲 47a5473a35 Init: fix possible memleaks 2023-06-09 10:10:03 +08:00
李通洲 96bca6888a LocalIP: remove useless code 2023-06-09 09:47:45 +08:00
李通洲 bbf31c1a95 Doc: update changelog 2023-06-08 22:28:32 +08:00
李通洲 42b8c1b429 Wallpaper: add missing docs 2023-06-08 22:27:15 +08:00
李通洲 77fde11039 Disk (Linux): fix fastfetch doesn't show Windows drives (/mnt/c) 2023-06-08 22:24:57 +08:00
李通洲 e13f04e80f Disk: backport changes from config branch 2023-06-08 22:24:57 +08:00
李通洲 ad026f6105 LocalIP: backport mac address support
Also change `--*-ip-*` to `--*ip-*` to be consistant to my config branch
2023-06-08 22:22:05 +08:00
李通洲 9107d0e107 Player: try avoiding too Linux-specific names 2023-06-08 16:08:56 +08:00
李通洲 ee876c54bf Theme: split detection code 2023-06-08 16:08:56 +08:00
李通洲 4af44a40bf OS (macOS): add fast path for code name detection 2023-06-07 14:30:45 +08:00
李通洲 399cfe2fbc CI (Wallpaper): run this module 2023-06-06 21:17:03 +08:00
李通洲 71d0cdbfce Wallpaper (Linux): add support for xfce4 2023-06-06 21:02:21 +08:00
李通洲 aae740472f Wallpaper (Linux): add support for gnome 2023-06-06 21:02:21 +08:00
李通洲 8f9beb2789 Wallpaper (macOS): add support 2023-06-06 21:02:21 +08:00
李通洲 77b93a904f Wallpaper (Windows): add new module 2023-06-06 15:48:24 +08:00
李通洲 7934c16bca Doc: update changelog for Icons module 2023-06-06 15:46:57 +08:00
李通洲 941ddee2fc Icons (Windows): add support
Instead of icon theme, this module on Windows detects enabled system icons
2023-06-06 15:35:41 +08:00
李通洲 16113bf330 Icons: split detection code 2023-06-06 15:35:41 +08:00
李通洲 505182428b Global: silence some clang warnings 2023-06-04 01:30:48 +08:00
李通洲 3c2a84ff78 TerminalFont: detect /dev/pts/* 2023-06-01 11:00:40 +08:00
李通洲 8a3346b650 DisplayServer (Wayland): remove a useless line 2023-05-30 22:38:35 +08:00
李通洲 5b63fb1362 Doc: update changelog 2023-05-30 21:04:11 +08:00
李通洲 393857b067 Brightness (Linux): print more useful display name instead of intel_backlight 2023-05-30 20:57:05 +08:00
李通洲 cb8a9c0796 DisplayServer (Wayland): detect display type 2023-05-30 20:54:08 +08:00
李通洲 036752763f DisplayServer (Wayland): silence compiler warnings 2023-05-30 20:53:35 +08:00
李通洲 3a90af1f44 DisplayServer (Wayland): detect screen rotation 2023-05-30 20:16:18 +08:00
李通洲 772de0ff97 DisplayServer: better wayland feature detection 2023-05-29 13:35:45 +08:00
李通洲 53a61a8e58 Display (Linux): support name detection for wayland protocol 2023-05-29 13:30:50 +08:00
Linus Dierheimer a37328c1aa Font: Show QT before GTK
keeps consistency with other modules
2023-05-28 12:34:23 +02:00
李通洲 782325395c DE: Fix Gnome version detection on Fedora 2023-05-28 01:10:00 +08:00
李通洲 e13d554433 Merge remote-tracking branch 'upstream/master' into dev 2023-05-28 00:20:31 +08:00
李通洲 15c72c04af Release: 1.11.1
Update changelog too
2023-05-28 00:17:57 +08:00
李通洲 b797246607 DisplayServer (Apple): use FF_AUTO_FREE 2023-05-28 00:17:57 +08:00
李通洲 d54bb4fd16 Windows: use ffStrbufInitWS 2023-05-28 00:17:57 +08:00
李通洲 0a946e3976 Disk (Windows): improve performance 2023-05-28 00:17:57 +08:00
李通洲 a339f00d83 Windows: fix potential memory curruption bug in unicode.c
Also add ffStrbufInitWS
2023-05-28 00:17:57 +08:00
李通洲 de15866c9a TerminalShell (Windows): print clink version 2023-05-28 00:17:57 +08:00
李通洲 24ee87720e TerminalShell: code refactoring 2023-05-28 00:17:57 +08:00
李通洲 7310b3ed09 TerminalShel (Windows): detect Tabby version with exe file version 2023-05-28 00:17:57 +08:00
李通洲 bb6cdc7bb0 Settings (Linux): fix memleaks reported by LeakSanitizer 2023-05-28 00:17:57 +08:00
李通洲 4a2d20fb74 TerminalFont: support Tabby 2023-05-28 00:17:57 +08:00
李通洲 b136b86300 TerminalShell: support Tabby terminal version detection 2023-05-28 00:17:57 +08:00
李通洲 d4a7ae8b34 Sound (macOS): detecting volume more aggressively 2023-05-28 00:17:57 +08:00
李通洲 04da7cebdb Logo: add macOS small version 2023-05-28 00:17:57 +08:00
李通洲 ccb227e694 TerminalShell: fix iTerm being detected as iTermServer-* sometimes 2023-05-28 00:17:57 +08:00
李通洲 9c7b868227 TerminalShell: support xonsh 2023-05-28 00:17:57 +08:00
李通洲 f333937b35 Swap (Windows): fix compiler warnings 2023-05-28 00:17:57 +08:00
李通洲 e4f6f15d70 Vulkan: try fixing #456 2023-05-28 00:17:57 +08:00
李通洲 5ae8ef1cb3 Swap: split module code from memory.c 2023-05-28 00:17:57 +08:00
李通洲 d863652e1b CMake(Windows): remove USE_WIN_NTAPI option 2023-05-28 00:17:57 +08:00
李通洲 ac540d73b7 Network: drop module 2023-05-28 00:17:57 +08:00
Edward Piper 37b9da7337 Fix EndeavourOS logo again 2023-05-28 00:17:57 +08:00
李通洲 93c0dbde0d DisplayServer (Windows): code simplification 2023-05-28 00:17:57 +08:00
李通洲 aa236b4da0 OpenCL: split detection code 2023-05-28 00:17:57 +08:00
李通洲 2fd3643632 Doc: document Network module 2023-05-28 00:17:57 +08:00
李通洲 24f9247c54 LocalIP: simplify loop interface detection 2023-05-28 00:17:57 +08:00
李通洲 d312b752a1 Network (FreeBSD): add dirty support 2023-05-28 00:17:57 +08:00
李通洲 1b476757a0 Network: code refactor & bug fixes 2023-05-28 00:17:57 +08:00
李通洲 c78a8f6317 Network (Linux): add support 2023-05-28 00:17:57 +08:00
李通洲 24c3788055 Network (Windows): add support 2023-05-28 00:17:57 +08:00
李通洲 a644762a60 Network (macOS): init 2023-05-28 00:17:57 +08:00
Linus Dierheimer 3185d92fb5 --pipe: don't print white color blocks
Fixes #450
2023-05-28 00:17:57 +08:00
李通洲 2c629bc821 FFstrbuf: remove FF_STRBUF_CREATE macro 2023-05-28 00:17:57 +08:00
李通洲 1a6c38bc26 CpuUsage: code refactor 2023-05-28 00:17:57 +08:00
李通洲 589f9aa8f3 Processes: code refactor 2023-05-28 00:17:57 +08:00
tdtooke 70e5d0b235 Update builtin.c 2023-05-28 00:17:57 +08:00
tdtooke aa81d80578 Update builtin.c 2023-05-28 00:17:57 +08:00
KingKrouch 7bc6676680 Update Windows 11 ASCII
Reason being that the original ASCII art as shown in Windows Terminal has random portions using "*" and "(" as opposed to "/".
2023-05-28 00:17:57 +08:00
Linus Dierheimer ab9b10824f Fix flatpak package count
Fix user package count
Show runtime packages too
Fixes #441
2023-05-28 00:17:57 +08:00
Linus Dierheimer f5931e80e7 Fix a new compile warning 2023-05-28 00:17:57 +08:00
Linus Dierheimer bf4f86b4f6 Remove leftover comment 2023-05-28 00:17:57 +08:00
李通洲 7f59f22cf4 Font: code refactor 2023-05-28 00:17:57 +08:00
李通洲 14f4817381 Doc: update changelog 2023-05-28 00:17:57 +08:00
李通洲 e821468bb0 Gamepad: fix copy-and-paste errors 2023-05-28 00:17:57 +08:00
李通洲 d9315d2332 Doc: update changelog 2023-05-28 00:17:57 +08:00
李通洲 a2b4be388e Logo: add SteamOS (#439) 2023-05-28 00:17:57 +08:00
李通洲 35e06642f9 Gamepad (Windows): change the name of Pro Controller 2023-05-28 00:17:57 +08:00
李通洲 92de3e4f30 Windows: fix compiling with imagemagick enabled 2023-05-28 00:17:57 +08:00
李通洲 5b65e182e9 Release: 1.11.1
Update changelog too
2023-05-27 23:53:41 +08:00
李通洲 a7896c39f0 DisplayServer (Apple): use FF_AUTO_FREE 2023-05-27 23:34:04 +08:00
李通洲 4f19bf9a18 Windows: use ffStrbufInitWS 2023-05-27 23:34:03 +08:00
李通洲 c379c65960 Disk (Windows): improve performance 2023-05-27 23:34:03 +08:00
李通洲 1ae0a83880 Windows: fix potential memory curruption bug in unicode.c
Also add ffStrbufInitWS
2023-05-27 23:34:03 +08:00
李通洲 77f7c813f4 TerminalShell (Windows): print clink version 2023-05-27 21:47:36 +08:00
李通洲 bfec8b5634 TerminalShell: code refactoring 2023-05-27 21:47:18 +08:00
李通洲 15a43a6b11 TerminalShel (Windows): detect Tabby version with exe file version 2023-05-27 21:26:00 +08:00
李通洲 c9e3c34ce1 Settings (Linux): fix memleaks reported by LeakSanitizer 2023-05-27 18:25:54 +08:00
李通洲 b99b3ad982 TerminalFont: support Tabby 2023-05-26 15:47:19 +08:00
李通洲 f4ce5c4143 TerminalShell: support Tabby terminal version detection 2023-05-26 15:44:54 +08:00
李通洲 bb4bf63621 Sound (macOS): detecting volume more aggressively 2023-05-26 15:18:59 +08:00
李通洲 60c1a552bb Logo: add macOS small version 2023-05-26 09:16:29 +08:00
李通洲 0a979ddd1e TerminalShell: fix iTerm being detected as iTermServer-* sometimes 2023-05-24 14:50:39 +08:00
李通洲 e45c4b49fd TerminalShell: support xonsh 2023-05-24 14:50:37 +08:00
李通洲 b89ace7aae Swap (Windows): fix compiler warnings 2023-05-16 20:54:45 +08:00
李通洲 424ca923fc Vulkan: try fixing #456 2023-05-16 20:53:45 +08:00
李通洲 e837e1e1d1 Swap: split module code from memory.c 2023-05-11 22:03:18 +08:00
李通洲 aea0986928 CMake(Windows): remove USE_WIN_NTAPI option 2023-05-11 19:55:31 +08:00
李通洲 dc2a3492f0 Network: drop module 2023-05-03 21:50:05 +08:00
Edward Piper 8cf033002c Fix EndeavourOS logo again 2023-05-03 21:49:50 +08:00
李通洲 4d7cb25aa6 DisplayServer (Windows): code simplification 2023-04-26 00:14:39 +08:00
李通洲 60cf3ec861 OpenCL: split detection code 2023-04-25 19:08:27 +08:00
李通洲 4fd82b16e8 Doc: document Network module 2023-04-18 20:59:26 +08:00
李通洲 26feccc0e4 LocalIP: simplify loop interface detection 2023-04-18 20:38:02 +08:00
李通洲 9a1bc66dfc Network (FreeBSD): add dirty support 2023-04-18 20:37:22 +08:00
李通洲 24a3783d7c Network: code refactor & bug fixes 2023-04-18 20:36:41 +08:00
李通洲 7e072c395f Network (Linux): add support 2023-04-18 18:27:25 +08:00
李通洲 94e1ed1d7e Network (Windows): add support 2023-04-18 18:02:31 +08:00
李通洲 94e6f4040d Network (macOS): init 2023-04-18 17:29:48 +08:00
Linus Dierheimer d570e59818 --pipe: don't print white color blocks
Fixes #450
2023-04-17 17:04:28 +02:00
李通洲 0e9d48fff0 FFstrbuf: remove FF_STRBUF_CREATE macro 2023-04-15 12:27:51 +08:00
李通洲 e690d73434 CpuUsage: code refactor 2023-04-15 12:27:51 +08:00
李通洲 8f2b3c6b69 Processes: code refactor 2023-04-15 12:27:51 +08:00
Linus Dierheimer 3c0b2fc910 Merge pull request #448 from LinusDierheimer/master
Merge pull request #437 from LinusDierheimer/dev
2023-04-13 09:17:37 +02:00
Linus Dierheimer 7d0a1c8987 Merge pull request #446 from tdtooke/dev
Adds another font color index to arch icon
2023-04-12 08:09:54 +02:00
tdtooke 757d947446 Update builtin.c 2023-04-11 13:44:07 -07:00
tdtooke 4ced4f9631 Update builtin.c 2023-04-11 13:35:24 -07:00
Linus Dierheimer c6859d7edd Merge pull request #445 from KingKrouch/winlogo-patch
Update Windows 11 ASCII logo to look more visually consistent.
2023-04-10 18:04:17 +02:00
KingKrouch 94cf9a89cc Update Windows 11 ASCII
Reason being that the original ASCII art as shown in Windows Terminal has random portions using "*" and "(" as opposed to "/".
2023-04-10 15:28:42 +00:00
Linus Dierheimer bd8d78427b Fix flatpak package count
Fix user package count
Show runtime packages too
Fixes #441
2023-04-06 11:11:31 +02:00
Linus Dierheimer e40d4b9b68 Fix a new compile warning 2023-04-05 13:41:10 +02:00
Linus Dierheimer 4a07485a19 Remove leftover comment 2023-04-05 13:21:46 +02:00
李通洲 71614e0b0c Font: code refactor 2023-04-04 12:06:21 +08:00
李通洲 d5b6c14bdf Doc: update changelog 2023-04-04 11:05:27 +08:00
李通洲 9509718b0e Gamepad: fix copy-and-paste errors 2023-04-04 11:02:59 +08:00
李通洲 c0ca022ac2 Doc: update changelog 2023-04-02 20:56:12 +08:00
李通洲 708b4a8981 Logo: add SteamOS (#439) 2023-04-02 20:54:16 +08:00
李通洲 8006b0ca4f Gamepad (Windows): change the name of Pro Controller 2023-04-02 20:41:18 +08:00
李通洲 cc2286f056 Windows: fix compiling with imagemagick enabled 2023-04-02 20:41:16 +08:00
129 changed files with 2123 additions and 1299 deletions
@@ -1,4 +1,4 @@
name: manage pushes
name: CI
on:
- push
@@ -150,7 +150,7 @@ jobs:
uses: vmactions/freebsd-vm@v0
with:
prepare: |
pkg install -y cmake git pkgconf pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd
pkg install -y cmake git pkgconf pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package
@@ -285,7 +285,7 @@ jobs:
path: ./fastfetch-*-Win32.zip
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch'
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
name: Release
runs-on: ubuntu-latest
needs:
+98
View File
@@ -1,3 +1,101 @@
# 1.12.2
Features:
* Support terminator terminal version detection (Linux, Terminal)
* Support `pkgtool` package manager detection (Linux, Packages)
* Support `Far` shell version detection (Windows, Shell)
Bugfixes:
* Fix ConEmu terminal detection in some special cases (Windows, Terminal, #488)
* Fix incorrect Host on M2 Mac Studio with M2 Max CPU (macOS, Host, #490)
# 1.12.1
Bugfixes:
* Fix compiling error on Apple Slicon (Bios, macOS)
# 1.12.0
This release backports some changes from dev branch, and fixes 2 crashing issues
Features:
* Support KDE / LXQT / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
* Support QTerminal version & terminal font detection
* Support MATE Terminal version & terminal font detection
* Set `--pipe true` automatically if stdout is not a tty
* Detect new macs released on WWDC 2023 (macOS, Host)
* Count cached memory as free memory (FreeBSD, Memory)
* Support sound detection (FreeBSD, Sound)
Bugfixes:
* Fix DE detection on Windows 8.1 (Windows, DE)
* Fix `--logo-padding-left` doesn't work when `--logo-padding-top` is set (Logo)
* Fix KDE version detection on Fedora (DE)
* Include limits.h when needed (Linux, #472)
* Fix Windows drives detection in WSL (Linux, Disk)
* Fix CPU temp detection (FreeBSD, CPU)
* Fix disk detection (Android, Disk)
* Fix Gnome Terminal version and font detection (FreeBSD, TerminalFont)
* Fix crash on newer wayland desktops (Linux, Display, #477)
* Fix vendor detection for Intel GPU (macOS, GPU)
* Fix possible crashes on Windows Server (Windows, GPU, #484)
Logo:
* Add bsd, freebsd_small, ghostbsd
* Make Windows 11 logo colorable
# 1.11.3
Bugfixes:
* Fix a segfault bug, regression of `1.11.1` (Linux, wmtheme, #467)
# 1.11.2
This release should be the last version of fastfetch 1.x (if no serious bugs found, hopefully)
Features:
* Support display name, type, rotation detection on Wayland (Linux, Display)
* Print more useful display name instead of intel_backlight (Linux, Brightness)
* Icons module supports Windows (Windows, Icons)
* Add Wallpaper module which shows the current wallpaper image path
* Add mac address detection `--localip-show-mac` (LocalIP, #451)
Bugfixes:
* Fix Gnome version detection on Fedora (DE)
* Fix Windows drives detection in WSL (Disk)
Changes:
* In order to make Icons module consistant between different platforms, `--icons-format` no longer supports individual GTK / QT icon params.
* `--theme-format` no longer supports individual GTK / plasma theme params.
* `--local-ip-*` and `--public-ip-*` have been changed to `--localip-*` and `--publicip-*`
* `--localip-compact-type` is no longer supported. Fastfetch now display IPs as `--localip-compat-type multiline` by default, with `--local-compact true` can be set as an alias of `--localip-compact-type oneline`
* `--localip-v6first` is no longer supported.
# 1.11.1
Features:
* Support xonsh detection (TerminalShell)
* Support Tabby version / terminal font detection (TerminalFont)
Bugfixes:
* Fix name of Pro Controller (Gamepad, Windows)
* Fix compile error with imagemagick enabled (Windows)
* Fix copy-and-paste errors (Gamepad)
* Flatpak: Fix user package count
* Flatpak: Count runtime packages too (#441)
* Fix flatpak package count (#441)
* Don't print white color blocks with `--pipe` (#450)
* Fix iTerm being detected as iTermServer-* sometimes
* Fix sound device volume being incorrectly detected as muted sometimes (Sound)
* Fix memleaks reported by LeakSanitizer (Linux)
* Fix potential memory curruption bug in unicode.c (Windows)
Logo:
* Update Windows 11 ASCII logo to look more visually consistent (#445)
* Add another font color index to arch icon (#446)
* Add SteamOS
* Add macOS small / small2
# 1.11.0
Features:
+29 -13
View File
@@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 1.11.0
VERSION 1.12.2
LANGUAGES C
DESCRIPTION "Fast system information tool"
HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
)
set(PROJECT_LICENSE "MIT license")
@@ -57,7 +57,7 @@ cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD OR APPLE" OFF)
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD OR APPLE OR WIN32" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD OR APPLE" OFF)
@@ -73,7 +73,6 @@ cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN32" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_BUFFER "Enable stdout buffer" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
cmake_dependent_option(USE_WIN_NTAPI "Allow using internal NTAPI" ON "WIN32" 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
@@ -97,12 +96,14 @@ else()
message(STATUS "Threads type: disabled")
endif()
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration")
if(WIN32)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -fno-exceptions -fno-rtti")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id -Wl,--subsystem,console:6.1,--major-os-version,6,--minor-os-version,1")
endif()
@@ -248,6 +249,7 @@ set(LIBFASTFETCH_SRC
src/detection/host/host.c
src/detection/locale/locale.c
src/detection/media/media.c
src/detection/opencl/opencl.c
src/detection/os/os.c
src/detection/packages/packages.c
src/detection/terminalfont/terminalfont.c
@@ -296,6 +298,7 @@ set(LIBFASTFETCH_SRC
src/modules/separator.c
src/modules/shell.c
src/modules/sound.c
src/modules/swap.c
src/modules/media.c
src/modules/terminal.c
src/modules/terminalfont.c
@@ -305,6 +308,7 @@ set(LIBFASTFETCH_SRC
src/modules/uptime.c
src/modules/users.c
src/modules/vulkan.c
src/modules/wallpaper.c
src/modules/weather.c
src/modules/wifi.c
src/modules/wm.c
@@ -341,6 +345,7 @@ if(LINUX)
src/detection/gpu/gpu_linux.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/icons/icons_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_linux.c
src/detection/media/media_linux.c
@@ -356,8 +361,10 @@ if(LINUX)
src/detection/temps/temps_linux.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/theme/theme_linux.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/util/platform/FFPlatform_unix.c
@@ -381,6 +388,7 @@ elseif(ANDROID)
src/detection/font/font_nosupport.c
src/detection/gpu/gpu_nosupport.c
src/detection/host/host_android.c
src/detection/icons/icons_nosupport.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_nosupport.c
@@ -395,8 +403,10 @@ elseif(ANDROID)
src/detection/temps/temps_linux.c
src/detection/terminalfont/terminalfont_android.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/theme/theme_nosupport.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_nosupport.c
src/detection/wifi/wifi_android.c
src/detection/wmtheme/wmtheme_nosupport.c
src/util/platform/FFPlatform_unix.c
@@ -427,6 +437,7 @@ elseif(BSD)
src/detection/gpu/gpu_linux.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_bsd.c
src/detection/icons/icons_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_linux.c
@@ -442,8 +453,10 @@ elseif(BSD)
src/detection/temps/temps_linux.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/theme/theme_linux.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wmtheme/wmtheme_linux.c
src/util/platform/FFPlatform_unix.c
@@ -469,6 +482,7 @@ elseif(APPLE)
src/detection/font/font_apple.m
src/detection/gpu/gpu_apple.c
src/detection/host/host_apple.c
src/detection/icons/icons_nosupport.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_apple.c
src/detection/media/media_apple.m
@@ -483,8 +497,10 @@ elseif(APPLE)
src/detection/temps/temps_apple.c
src/detection/terminalfont/terminalfont_apple.m
src/detection/terminalshell/terminalshell_linux.c
src/detection/theme/theme_nosupport.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_apple.c
src/detection/wifi/wifi_apple.m
src/detection/wmtheme/wmtheme_apple.m
src/util/apple/cf_helpers.c
@@ -510,6 +526,7 @@ elseif(WIN32)
src/detection/font/font_windows.c
src/detection/gpu/gpu_windows.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/localip/localip_windows.c
src/detection/gamepad/gamepad_windows.c
src/detection/media/media_nosupport.c
@@ -518,14 +535,16 @@ elseif(WIN32)
src/detection/os/os_windows.cpp
src/detection/packages/packages_windows.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_windows.cpp
src/detection/processes/processes_windows.c
src/detection/sound/sound_windows.cpp
src/detection/swap/swap_windows.cpp
src/detection/swap/swap_windows.c
src/detection/terminalfont/terminalfont_windows.c
src/detection/terminalshell/terminalshell_windows.cpp
src/detection/terminalshell/terminalshell_windows.c
src/detection/temps/temps_windows.cpp
src/detection/theme/theme_nosupport.c
src/detection/uptime/uptime_windows.c
src/detection/users/users_windows.c
src/detection/wallpaper/wallpaper_windows.c
src/detection/wifi/wifi_windows.c
src/detection/wmtheme/wmtheme_windows.c
src/util/windows/getline.c
@@ -710,6 +729,7 @@ if(APPLE)
PRIVATE "-framework IOKit"
PRIVATE "-framework OpenGL"
PRIVATE "-framework OpenCL"
PRIVATE "-framework SystemConfiguration"
PRIVATE "-weak_framework CoreDisplay"
PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks"
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
@@ -730,11 +750,7 @@ elseif(WIN32)
PRIVATE "setupapi"
PRIVATE "hid"
PRIVATE "wtsapi32"
PRIVATE "powrprof"
)
if(USE_WIN_NTAPI)
target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI)
endif()
endif()
target_include_directories(libfastfetch
+8 -5
View File
@@ -1,5 +1,7 @@
# Fastfetch
[![CI](https://github.com/fastfetch-cli/fastfetch/actions/workflows/ci.yml/badge.svg)](https://github.com/fastfetch-cli/fastfetch/actions/workflows/ci.yml)
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
<img src="screenshots/example1.png" width="49%" align="left" />
@@ -10,7 +12,7 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
<img src="screenshots/example3.png" width="48%" align="top" />
<img src="screenshots/example5.png" height="15%" align="top" />
There are [screenshots on different platforms](https://github.com/LinusDierheimer/fastfetch/wiki)
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
## Customization
@@ -64,6 +66,7 @@ The following libraries are used if present at runtime:
* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb)
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb)
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb)
* [`libsqlite3`](https://www.sqlite.org/index.html): Used for fast wallpaper detection ( fallback to AppleScript )
For the image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported.
@@ -89,17 +92,17 @@ All categories not listed here should work without needing a specific implementa
##### Available Modules
```
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, Display, Font, Gamepad, GPU, Host, Icons, Kernel, Locale, LocalIP, Media, Memory, OpenCL, OpenGL, Packages, Player, Power Adapter, Processes, PublicIP, Separator, OS, Shell, Sound, Swap, Terminal, Terminal Font, Theme, Time, Title, Uptime, Vulkan, Wifi, WM, WMTheme
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, Display, Font, Gamepad, GPU, Host, Icons, Kernel, Locale, LocalIP, Media, Memory, OpenCL, OpenGL, Packages, Player, Power Adapter, Processes, PublicIP, Separator, OS, Shell, Sound, Swap, Terminal, Terminal Font, Theme, Time, Title, Uptime, Vulkan, Wallpaper, Wifi, WM, WMTheme
```
##### Builtin logos
```
AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Deepin, Devuan, Endeavour, Enso, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE LEAP, OpenSUSE Tumbleweed, Parabola, Pop!_OS, Raspbian, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Solus, Ubuntu, Vanilla, Void, Windows, Windows 11, Windows 8, Zorin
AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Deepin, Devuan, Endeavour, Enso, Fedora, FreeBSD, Garuda, Gentoo, GhostBSD, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE LEAP, OpenSUSE Tumbleweed, Parabola, Pop!_OS, Raspbian, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Solus, SteamOS, Ubuntu, Vanilla, Void, Windows, Windows 11, Windows 8, Zorin
```
##### Package managers
```
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, Pacman, pkg, rpm, scoop, Snap, xbps
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, Pacman, pkg, pkgtool, rpm, scoop, Snap, xbps
```
##### WM themes
@@ -114,7 +117,7 @@ Budgie, Cinnamon, Gnome, KDE Plasma, LXQt, Mate, XFCE4
##### Terminal fonts
```
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, mintty, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal
```
## Building
+10 -10
View File
@@ -32,8 +32,8 @@ __fastfetch_complete_help()
"battery-format"
"poweradapter-format"
"locale-format"
"local-ip-format"
"public-ip-format"
"localip-format"
"publicip-format"
"player-format"
"media-format"
"datetime-format"
@@ -235,8 +235,8 @@ __fastfetch_completion()
"--set-keyless"
"--player-name"
"--percent-type"
"--public-ip-url"
"--public-ip-timeout"
"--publicip-url"
"--publicip-timeout"
"--weather-output-format"
"--weather-timeout"
"--os-key"
@@ -317,12 +317,12 @@ __fastfetch_completion()
"--locale-key"
"--locale-format"
"--locale-error"
"--local-ip-key"
"--local-ip-format"
"--local-ip-error"
"--public-ip-key"
"--public-ip-format"
"--public-ip-error"
"--localip-key"
"--localip-format"
"--localip-error"
"--publicip-key"
"--publicip-format"
"--publicip-error"
"--wifi-key"
"--wifi-format"
"--wifi-error"
+1 -1
View File
@@ -1 +1 @@
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:Break:Colors
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:Break:Colors
+1 -1
View File
@@ -3,7 +3,7 @@
--kernel-format Sysname: {}; Release: {}; Version: {}
--uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {}
--processes-format Count: {}
--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; eopkg: {}; xbps: {}; apk: {}; flatpak-system: {}; flatpak-user: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {}
--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; eopkg: {}; xbps: {}; apk: {}; flatpak-system: {}; flatpak-user: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {}; pkgtool: {}
--shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {}
--display-format Width: {}; Height: {}; Refresh rate: {}; ScaledWith: {}; ScaledHeight: {}
--de-format Process name: {}; Pretty name: {}; Version: {}
+8 -12
View File
@@ -60,12 +60,12 @@ static void defaultConfig(FFinstance* instance)
instance->config.showErrors = false;
instance->config.recache = false;
instance->config.allowSlowOperations = false;
instance->config.disableLinewrap = true;
instance->config.hideCursor = true;
instance->config.pipe = !isatty(STDOUT_FILENO);
instance->config.disableLinewrap = !instance->config.pipe;
instance->config.hideCursor = !instance->config.pipe;
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;
instance->config.stat = false;
@@ -109,6 +109,7 @@ static void defaultConfig(FFinstance* instance)
initModuleArg(&instance->config.date);
initModuleArg(&instance->config.time);
initModuleArg(&instance->config.vulkan);
initModuleArg(&instance->config.wallpaper);
initModuleArg(&instance->config.openGL);
initModuleArg(&instance->config.openCL);
initModuleArg(&instance->config.users);
@@ -156,10 +157,7 @@ static void defaultConfig(FFinstance* instance)
instance->config.titleFQDN = false;
ffStrbufInitA(&instance->config.diskFolders, 0);
instance->config.diskShowRemovable = true;
instance->config.diskShowHidden = false;
instance->config.diskShowUnknown = false;
instance->config.diskShowSubvolumes = false;
instance->config.diskShowTypes = FF_DISK_TYPE_REGULAR_BIT | FF_DISK_TYPE_EXTERNAL_BIT;
instance->config.displayCompactType = FF_DISPLAY_COMPACT_TYPE_NONE;
instance->config.displayDetectName = false;
@@ -173,12 +171,8 @@ static void defaultConfig(FFinstance* instance)
ffStrbufInitA(&instance->config.separatorString, 0);
instance->config.localIpShowIpV4 = true;
instance->config.localIpShowIpV6 = false;
instance->config.localIpShowLoop = false;
instance->config.localIpV6First = false;
instance->config.localIpShowType = FF_LOCALIP_TYPE_IPV4_BIT;
ffStrbufInit(&instance->config.localIpNamePrefix);
instance->config.localIpCompactType = FF_LOCALIP_COMPACT_TYPE_NONE;
instance->config.publicIpTimeout = 0;
ffStrbufInit(&instance->config.publicIpUrl);
@@ -343,6 +337,7 @@ static void destroyConfig(FFinstance* instance)
destroyModuleArg(&instance->config.host);
destroyModuleArg(&instance->config.bios);
destroyModuleArg(&instance->config.board);
destroyModuleArg(&instance->config.chassis);
destroyModuleArg(&instance->config.kernel);
destroyModuleArg(&instance->config.uptime);
destroyModuleArg(&instance->config.processes);
@@ -369,6 +364,7 @@ static void destroyConfig(FFinstance* instance)
destroyModuleArg(&instance->config.locale);
destroyModuleArg(&instance->config.localIP);
destroyModuleArg(&instance->config.publicIP);
destroyModuleArg(&instance->config.wallpaper);
destroyModuleArg(&instance->config.weather);
destroyModuleArg(&instance->config.wifi);
destroyModuleArg(&instance->config.player);
+4 -4
View File
@@ -10,7 +10,7 @@
#include <libloaderapi.h>
#define FF_DLOPEN_FLAGS 0
FF_C_NODISCARD static inline void* dlopen(const char* path, int mode) { FF_UNUSED(mode); return LoadLibraryA(path); }
FF_C_NODISCARD static inline void* dlsym(void* handle, const char* symbol) { return GetProcAddress((HMODULE)handle, symbol); }
FF_C_NODISCARD static inline void* dlsym(void* handle, const char* symbol) { return (void*) GetProcAddress((HMODULE)handle, symbol); }
static inline int dlclose(void* handle) { return !FreeLibrary((HMODULE)handle); }
#else
#include <dlfcn.h>
@@ -40,20 +40,20 @@ static inline void ffLibraryUnload(void** handle)
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
symbolMapping = dlsym(library, #symbolName); \
symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
if(symbolMapping == NULL) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \
symbolMapping = dlsym(library, #symbolName); \
if(symbolMapping == NULL && !(symbolMapping = dlsym(library, #alternateName))) \
if(symbolMapping == NULL && !(symbolMapping = (__typeof__(&symbolName)) dlsym(library, #alternateName))) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
__typeof__(&symbolName) ff ## symbolName = dlsym(library, #symbolName);
__typeof__(&symbolName) ff ## symbolName = (__typeof__(&symbolName)) dlsym(library, #symbolName);
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
+2
View File
@@ -3,6 +3,8 @@
#ifndef FF_INCLUDED_parsing_h
#define FF_INCLUDED_parsing_h
#include "fastfetch.h"
#include <stdint.h>
typedef struct FFVersion
+2 -2
View File
@@ -166,10 +166,10 @@ bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uin
FFstrbuf baseDir;
ffStrbufInitA(&baseDir, 64);
for(uint32_t i = 0; i < list->length; i++)
FF_LIST_FOR_EACH(FFstrbuf, dirPrefix, *list)
{
//We need to copy the dir each time, because it used by multiple threads, so we can't directly write to it.
ffStrbufSet(&baseDir, ffListGet(list, i));
ffStrbufSet(&baseDir, dirPrefix);
ffStrbufAppendS(&baseDir, relativeFile);
if(ffParsePropFileValues(baseDir.chars, numQueries, queries))
+60 -8
View File
@@ -57,23 +57,31 @@ typedef enum FFInitState
typedef struct GVariantGetters
{
FF_LIBRARY_SYMBOL(g_variant_get_string)
FF_LIBRARY_SYMBOL(g_variant_dup_string)
FF_LIBRARY_SYMBOL(g_variant_get_boolean)
FF_LIBRARY_SYMBOL(g_variant_get_int32)
FF_LIBRARY_SYMBOL(g_variant_unref)
} GVariantGetters;
static FFvariant getGVariantValue(GVariant* variant, FFvarianttype type, const GVariantGetters* variantGetters)
{
FFvariant result;
if(variant == NULL)
return FF_VARIANT_NULL;
result = FF_VARIANT_NULL;
else if(type == FF_VARIANT_TYPE_STRING)
return (FFvariant) {.strValue = variantGetters->ffg_variant_get_string(variant, NULL)};
result = (FFvariant) {.strValue = variantGetters->ffg_variant_dup_string(variant, NULL)}; // Dup string, so that variant itself can be freed
else if(type == FF_VARIANT_TYPE_BOOL)
return (FFvariant) {.boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true};
result = (FFvariant) {.boolValue = (bool) variantGetters->ffg_variant_get_boolean(variant), .boolValueSet = true};
else if(type == FF_VARIANT_TYPE_INT)
return (FFvariant) {.intValue = variantGetters->ffg_variant_get_int32(variant)};
result = (FFvariant) {.intValue = variantGetters->ffg_variant_get_int32(variant)};
else
return FF_VARIANT_NULL;
result = FF_VARIANT_NULL;
if(variant)
variantGetters->ffg_variant_unref(variant);
return result;
}
typedef struct GSettingsData
@@ -102,9 +110,10 @@ static const GSettingsData* getGSettingsData(const FFinstance* instance)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_get_default)
#define data data.variantGetters
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_string)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref);
#undef data
data.schemaSource = data.ffg_settings_schema_source_get_default();
@@ -169,9 +178,10 @@ static const DConfData* getDConfData(const FFinstance* instance)
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
#define data data.variantGetters
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_string)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_dup_string)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_boolean)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_get_int32)
FF_LIBRARY_DATA_LOAD_SYMBOL(g_variant_unref)
#undef data
data.client = data.ffdconf_client_new();
@@ -288,6 +298,7 @@ typedef struct SQLiteData
FF_LIBRARY_SYMBOL(sqlite3_step)
FF_LIBRARY_SYMBOL(sqlite3_data_count)
FF_LIBRARY_SYMBOL(sqlite3_column_int)
FF_LIBRARY_SYMBOL(sqlite3_column_text)
FF_LIBRARY_SYMBOL(sqlite3_finalize)
FF_LIBRARY_SYMBOL(sqlite3_close)
} SQLiteData;
@@ -301,6 +312,7 @@ static const SQLiteData* getSQLiteData(const FFinstance* instance)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_step)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_data_count)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_int)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_text)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_finalize)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_close)
@@ -341,12 +353,52 @@ int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, cons
return result;
}
bool ffSettingsGetSQLite3String(const FFinstance* instance, const char* dbPath, const char* query, FFstrbuf* result)
{
if(!ffPathExists(dbPath, FF_PATHTYPE_FILE))
return false;
const SQLiteData* data = getSQLiteData(instance);
if(data == NULL)
return false;
sqlite3* db;
if(data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK)
return false;
sqlite3_stmt* stmt;
if(data->ffsqlite3_prepare_v2(db, query, (int) strlen(query), &stmt, NULL) != SQLITE_OK)
{
data->ffsqlite3_close(db);
return false;
}
if(data->ffsqlite3_step(stmt) != SQLITE_ROW || data->ffsqlite3_data_count(stmt) < 1)
{
data->ffsqlite3_finalize(stmt);
data->ffsqlite3_close(db);
return false;
}
ffStrbufSetS(result, (const char *) data->ffsqlite3_column_text(stmt, 0));
data->ffsqlite3_finalize(stmt);
data->ffsqlite3_close(db);
return true;
}
#else //FF_HAVE_SQLITE3
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query)
{
FF_UNUSED(instance, dbPath, query)
return 0;
}
bool ffSettingsGetSQLite3String(const FFinstance* instance, const char* dbPath, const char* query, FFstrbuf* result)
{
FF_UNUSED(instance, dbPath, query, result)
return false;
}
#endif //FF_HAVE_SQLITE3
#ifdef __ANDROID__
+1
View File
@@ -31,6 +31,7 @@ FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type);
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query);
bool ffSettingsGetSQLite3String(const FFinstance* instance, const char* dbPath, const char* query, FFstrbuf* result);
#ifdef __ANDROID__
void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
+11 -8
View File
@@ -168,13 +168,13 @@
# Sets the URL of public IP detection server to be used.
# Only HTTP protocol is supported, and the value should not contain "http://" prefix.
# Default is "ipinfo.io/ip".
#--public-ip-url "ipinfo.io/ip"
#--publicip-url "ipinfo.io/ip"
# Public IP timeout option:
# Sets the time to wait for the public ip server to respond.
# Must be a positive integer.
# Default is 0 (disabled).
#--public-ip-timeout 0
#--publicip-timeout 0
# Weather output format option:
# Sets the weather format to be used. It must be URI encoded.
@@ -321,8 +321,8 @@
#--battery-key Battery {1}
#--poweradapter-key Power Adapter {1}
#--locale-key Locale
#--local-ip-key Local IP ({1})
#--public-ip-key Public IP
#--localip-key Local IP ({1})
#--publicip-key Public IP
#--wifi-key Wifi
#--weather-key Weather
#--player-key Media Player
@@ -335,6 +335,7 @@
#--bluetooth-key Bluetooth
#--sound-key Sound
#--gamepad-key Gamepad
#--wallpaper-key Wallpaper
# Format options:
# Sets the format string for module values.
@@ -369,8 +370,8 @@
#--battery-format
#--poweradapter-format
#--locale-format
#--local-ip-format
#--public-ip-format
#--localip-format
#--publicip-format
#--weather-format
#--player-format
#--media-format
@@ -382,6 +383,7 @@
#--bluetooth-format
#--sound-format
#--gamepad-format
#--wallpaper-format
# Error options:
# Sets the format string to use if an error occured
@@ -416,8 +418,8 @@
#--battery-error
#--poweradapter-error
#--locale-error
#--local-ip-error
#--public-ip-error
#--localip-error
#--publicip-error
#--weather-error
#--player-error
#--media-error
@@ -429,6 +431,7 @@
#--bluetooth-error
#--sound-error
#--gamepad-error
#--wallpaper-error
# Library options:
# Sets an user specific path to a library to load.
+5 -4
View File
@@ -108,6 +108,7 @@ Module specific options:
--shell-version <?value>: Set if shell version should be detected and printed
--terminal-version <?value>: Set if terminal version should be detected and printed
--disk-folders <folders>: A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows)
--disk-show-regular <?value>: Set if regular volume should be printed. Default is true
--disk-show-removable <?value>: Set if removable volume should be printed. Default is true
--disk-show-hidden <?value>: Set if hidden volumes should be printed. Default is false
--disk-show-subvolumes <?value>: Set if subvolumes should be printed. Default is false
@@ -126,12 +127,12 @@ Module specific options:
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
--localip-show-ipv4 <?value>: Show IPv4 addresses in local ip module. Default is true
--localip-show-ipv6 <?value>: Show IPv6 addresses in local ip module. Default is false
--localip-show-mac <?value>: Show mac addresses in local ip module. Default is false
--localip-show-loop <?value>: Show loop back addresses (127.0.0.1) in local ip module. Default is false
--localip-name-prefix <str>: Show IPs with given name prefix only. Default is empty
--localip-compact-type <str>: Show IPs in one line. Should be either none, oneline, multiline. Default is none
--localip-v6first <?value>: Set if ipv6 should be printed first. Default is false
--public-ip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
--public-ip-url: The URL of public IP detection server to be used.
--localip-compact <?value>: Show all IPs in one line. Default is false
--publicip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
--publicip-url: The URL of public IP detection server to be used.
--weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0)
--weather-output-format: The output weather format to be used. It must be URI encoded.
--player-name: The name of the player to use
+10 -13
View File
@@ -9,18 +9,15 @@
#include <devguid.h>
#include <winternl.h>
#ifdef FF_USE_WIN_NTAPI
NTSYSCALLAPI
NTSTATUS
NTAPI
NtPowerInformation(
IN POWER_INFORMATION_LEVEL InformationLevel,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength);
#define CallNtPowerInformation NtPowerInformation
#endif
NTSYSCALLAPI
NTSTATUS
NTAPI
NtPowerInformation(
IN POWER_INFORMATION_LEVEL InformationLevel,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength);
static inline void wrapCloseHandle(HANDLE* handle)
{
@@ -147,7 +144,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
else
{
SYSTEM_BATTERY_STATE info;
if (NT_SUCCESS(CallNtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent)
if (NT_SUCCESS(NtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent)
{
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
ffStrbufInit(&battery->modelName);
+1
View File
@@ -48,6 +48,7 @@ void ffDetectBios(FFBiosResult* bios)
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) == kIOReturnSuccess)
{
ffCfDictGetString(properties, CFSTR("manufacturer"), &bios->biosVendor);
ffCfDictGetString(properties, CFSTR("time-stamp"), &bios->biosDate);
CFRelease(properties);
}
IOObjectRelease(registryEntry);
+17 -7
View File
@@ -2,6 +2,8 @@
#include "common/io/io.h"
#include <dirent.h>
#include <ctype.h>
#include <limits.h>
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result)
{
@@ -12,13 +14,13 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result)
if(dirp == NULL)
return "Failed to open `/sys/class/backlight/`";
FFstrbuf backlightDir;
FF_STRBUF_AUTO_DESTROY backlightDir;
ffStrbufInitA(&backlightDir, 64);
ffStrbufAppendS(&backlightDir, backlightDirPath);
uint32_t backlightDirLength = backlightDir.length;
FFstrbuf buffer;
FF_STRBUF_AUTO_DESTROY buffer;
ffStrbufInit(&buffer);
struct dirent* entry;
@@ -38,18 +40,26 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result)
if(ffReadFileBuffer(backlightDir.chars, &buffer))
{
FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result);
ffStrbufInitS(&display->name, entry->d_name);
ffStrbufSubstrBeforeLastC(&backlightDir, '/');
ffStrbufAppendS(&backlightDir, "/device");
ffStrbufInitA(&display->name, PATH_MAX + 1);
if(realpath(backlightDir.chars, display->name.chars))
{
ffStrbufRecalculateLength(&display->name);
ffStrbufSubstrAfterLastC(&display->name, '/');
if(ffStrbufStartsWithS(&display->name, "card") && isdigit(display->name.chars[4]))
ffStrbufSubstrAfterFirstC(&display->name, '-');
}
else
ffStrbufInitS(&display->name, entry->d_name);
double maxBrightness = ffStrbufToDouble(&buffer);
display->value = (float) (actualBrightness * 100 / maxBrightness);
}
break;
}
ffStrbufSubstrBefore(&backlightDir, backlightDirLength);
}
closedir(dirp);
ffStrbufDestroy(&backlightDir);
ffStrbufDestroy(&buffer);
return NULL;
}
+2 -3
View File
@@ -7,9 +7,8 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu)
if (instance->config.cpuTemp)
{
FFstrbuf cpuTemp;
ffStrbufInit(&cpuTemp);
if(ffSysctlGetString("temperature", &cpuTemp))
FF_STRBUF_AUTO_DESTROY cpuTemp = ffStrbufCreate();
if(ffSysctlGetString("hw.acpi.thermal.tz0.temperature", &cpuTemp))
cpu->temperature = FF_CPU_TEMP_UNSET;
else
cpu->temperature = ffStrbufToDouble(&cpuTemp);
-25
View File
@@ -1,8 +1,6 @@
#include "fastfetch.h"
#include "cpuUsage.h"
#ifdef FF_USE_WIN_NTAPI
#include "util/mallocHelper.h"
#include <ntstatus.h>
@@ -37,26 +35,3 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
return NULL;
}
#else
#include <processthreadsapi.h>
static inline uint64_t fileTimeToUint64(const FILETIME* ft) {
return (((uint64_t)ft->dwHighDateTime) << 32) | ((uint64_t)ft->dwLowDateTime);
}
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
{
FILETIME idleTime, kernelTime, userTime;
if(!GetSystemTimes(&idleTime, &kernelTime, &userTime))
return "GetSystemTimes() failed";
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getsystemtimes
// `kernelTime` also includes the amount of time the system has been idle.
*totalAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime);
*inUseAll = *totalAll - fileTimeToUint64(&idleTime);
return NULL;
}
#endif
+13 -6
View File
@@ -18,11 +18,18 @@ const FFDiskResult* ffDetectDisks()
if(result.disks.length == 0 && result.error.length == 0)
ffStrbufAppendS(&result.error, "No disks found");
//We need to sort the disks, so that we can detect, which disk a path resides on
// For example for /boot/efi/bootmgr we need to check /boot/efi before /boot
//Note that we sort alphabetically here for a better ordering when printing the list,
// so the check must be done in reverse order
ffListSort(&result.disks, compareDisks);
else
{
//We need to sort the disks, so that we can detect, which disk a path resides on
// For example for /boot/efi/bootmgr we need to check /boot/efi before /boot
//Note that we sort alphabetically here for a better ordering when printing the list,
// so the check must be done in reverse order
ffListSort(&result.disks, compareDisks);
FF_LIST_FOR_EACH(FFDisk, disk, result.disks)
{
if(disk->bytesTotal == 0)
disk->type |= FF_DISK_TYPE_UNKNOWN_BIT;
}
}
);
}
-8
View File
@@ -5,14 +5,6 @@
#include "fastfetch.h"
typedef enum FFDiskType
{
FF_DISK_TYPE_REGULAR,
FF_DISK_TYPE_HIDDEN,
FF_DISK_TYPE_EXTERNAL,
FF_DISK_TYPE_SUBVOLUME
} FFDiskType;
typedef struct FFDisk
{
FFstrbuf mountpoint;
+3 -3
View File
@@ -7,11 +7,11 @@ void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
// FreeBSD doesn't support these flags
if(fs->f_flags & MNT_DONTBROWSE)
disk->type = FF_DISK_TYPE_HIDDEN;
disk->type = FF_DISK_TYPE_HIDDEN_BIT;
else if(fs->f_flags & MNT_REMOVABLE)
disk->type = FF_DISK_TYPE_EXTERNAL;
disk->type = FF_DISK_TYPE_EXTERNAL_BIT;
else
disk->type = FF_DISK_TYPE_REGULAR;
disk->type = FF_DISK_TYPE_REGULAR_BIT;
ffStrbufInitS(&disk->name, [NSFileManager.defaultManager displayNameAtPath:@(fs->f_mntonname)].UTF8String);
}
+3 -3
View File
@@ -13,11 +13,11 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk)
ffStrbufStartsWithS(&disk->mountpoint, "/proc") ||
ffStrbufStartsWithS(&disk->mountpoint, "/zroot")
)
disk->type = FF_DISK_TYPE_HIDDEN;
disk->type = FF_DISK_TYPE_HIDDEN_BIT;
else if((fs->f_flags & MNT_NOSUID) || !(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_TYPE_EXTERNAL;
disk->type = FF_DISK_TYPE_EXTERNAL_BIT;
else
disk->type = FF_DISK_TYPE_REGULAR;
disk->type = FF_DISK_TYPE_REGULAR_BIT;
ffStrbufInit(&disk->name);
}
+26 -25
View File
@@ -17,16 +17,7 @@
static bool isPhysicalDevice(FFstrbuf* device)
{
struct stat deviceStat;
if(stat(device->chars, &deviceStat) != 0)
return false;
//Ignore all devices that are not block devices
if(!S_ISBLK(deviceStat.st_mode))
return false;
//Ignore all devices that are not physical devices
#ifndef __ANDROID__ //On Android, `/dev` is not accessable, so that the following checks always fail
//DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem.
if(ffStrbufEqualS(device, "drvfs"))
@@ -36,10 +27,20 @@ static bool isPhysicalDevice(FFstrbuf* device)
if(ffStrbufStartsWithS(device, "rpool/"))
return true;
struct stat deviceStat;
if(stat(device->chars, &deviceStat) != 0)
return false;
//Ignore all devices that are not block devices
if(!S_ISBLK(deviceStat.st_mode))
return false;
//Pseudo filesystems don't have a device in /dev
if(!ffStrbufStartsWithS(device, "/dev/"))
return false;
#endif // __ANDROID__
if(
ffStrbufStartsWithS(device, "/dev/loop") || //Ignore loop devices
ffStrbufStartsWithS(device, "/dev/ram") || //Ignore ram devices
@@ -115,7 +116,7 @@ static void detectName(FFDisk* disk, const FFstrbuf* device)
if(stat(device->chars, &deviceStat) != 0)
return;
FFstrbuf basePath;
FF_STRBUF_AUTO_DESTROY basePath;
ffStrbufInit(&basePath);
//Try partlabel first
@@ -132,8 +133,6 @@ static void detectName(FFDisk* disk, const FFstrbuf* device)
//Use the mountpoint as a last resort
if(disk->name.length == 0)
ffStrbufAppend(&disk->name, &disk->mountpoint);
ffStrbufDestroy(&basePath);
}
#ifdef __ANDROID__
@@ -141,31 +140,34 @@ static void detectName(FFDisk* disk, const FFstrbuf* device)
static void detectType(FF_MAYBE_UNUSED const FFlist* devices, FFDisk* currentDisk, FF_MAYBE_UNUSED const char* options)
{
if(ffStrbufEqualS(&currentDisk->mountpoint, "/") || ffStrbufEqualS(&currentDisk->mountpoint, "/storage/emulated"))
currentDisk->type = FF_DISK_TYPE_REGULAR;
currentDisk->type = FF_DISK_TYPE_REGULAR_BIT;
else if(ffStrbufStartsWithS(&currentDisk->mountpoint, "/mnt/media_rw/"))
currentDisk->type = FF_DISK_TYPE_EXTERNAL;
currentDisk->type = FF_DISK_TYPE_EXTERNAL_BIT;
else
currentDisk->type = FF_DISK_TYPE_HIDDEN;
currentDisk->type = FF_DISK_TYPE_HIDDEN_BIT;
}
#else
static bool isSubvolume(const FFlist* devices)
{
const FFstrbuf* currentDevie = ffListGet(devices, devices->length - 1);
const FFstrbuf* current = ffListGet(devices, devices->length - 1);
if(ffStrbufEqualS(current, "drvfs")) // WSL Windows drives
return false;
//Filter all disks which device was already found. This catches BTRFS subvolumes.
for(uint32_t i = 0; i < devices->length - 1; i++)
{
const FFstrbuf* otherDevice = ffListGet(devices, i);
if(ffStrbufEqual(currentDevie, otherDevice))
if(ffStrbufEqual(current, otherDevice))
return true;
}
//ZFS subvolumes: rpool/<POOL_NAME>/<VOLUME_NAME>/<SUBVOLUME_NAME>.
//Test if the third slash is present.
if(strncmp(currentDevie->chars, "rpool/", 6) == 0 && ffStrHasNChars(currentDevie->chars, '/', 3))
if(ffStrbufStartsWithS(current, "rpool/") && ffStrHasNChars(current->chars, '/', 3))
return true;
return false;
@@ -174,13 +176,13 @@ static bool isSubvolume(const FFlist* devices)
static void detectType(const FFlist* devices, FFDisk* currentDisk, const char* options)
{
if(isSubvolume(devices))
currentDisk->type = FF_DISK_TYPE_SUBVOLUME;
currentDisk->type = FF_DISK_TYPE_SUBVOLUME_BIT;
else if(strstr(options, "nosuid") != NULL || strstr(options, "nodev") != NULL)
currentDisk->type = FF_DISK_TYPE_EXTERNAL;
currentDisk->type = FF_DISK_TYPE_EXTERNAL_BIT;
else if(ffStrbufStartsWithS(&currentDisk->mountpoint, "/boot") || ffStrbufStartsWithS(&currentDisk->mountpoint, "/efi"))
currentDisk->type = FF_DISK_TYPE_HIDDEN;
currentDisk->type = FF_DISK_TYPE_HIDDEN_BIT;
else
currentDisk->type = FF_DISK_TYPE_REGULAR;
currentDisk->type = FF_DISK_TYPE_REGULAR_BIT;
}
#endif
@@ -207,7 +209,7 @@ void ffDetectDisksImpl(FFDiskResult* disks)
return;
}
FFlist devices;
FF_LIST_AUTO_DESTROY devices;
ffListInit(&devices, sizeof(FFstrbuf));
char* line = NULL;
@@ -257,7 +259,6 @@ void ffDetectDisksImpl(FFDiskResult* disks)
FF_LIST_FOR_EACH(FFstrbuf, device, devices)
ffStrbufDestroy(device);
ffListDestroy(&devices);
fclose(mountsFile);
}
+27 -26
View File
@@ -1,35 +1,31 @@
#include "disk.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <assert.h>
void ffDetectDisksImpl(FFDiskResult* disks)
{
uint32_t length = GetLogicalDriveStringsA(0, NULL);
if(length == 0)
{
ffStrbufAppendS(&disks->error, "GetLogicalDriveStringsA failed");
return;
}
char* buf = malloc(length + 1);
GetLogicalDriveStringsA(length, buf);
wchar_t buf[MAX_PATH + 1];
uint32_t length = GetLogicalDriveStringsW(sizeof(buf) / sizeof(*buf), buf);
assert(length < sizeof(buf) / sizeof(*buf));
for(uint32_t i = 0; i < length; i++)
{
const char* mountpoint = buf + i;
const wchar_t* mountpoint = buf + i;
UINT driveType = GetDriveTypeA(mountpoint);
UINT driveType = GetDriveTypeW(mountpoint);
if(driveType == DRIVE_NO_ROOT_DIR)
{
i += (uint32_t)strlen(mountpoint);
i += (uint32_t)wcslen(mountpoint);
continue;
}
FFDisk* disk = ffListAdd(&disks->disks);
ffStrbufInitS(&disk->mountpoint, mountpoint);
ffStrbufInitWS(&disk->mountpoint, mountpoint);
uint64_t bytesFree;
if(!GetDiskFreeSpaceExA(mountpoint, NULL, (PULARGE_INTEGER)&disk->bytesTotal, (PULARGE_INTEGER)&bytesFree))
if(!GetDiskFreeSpaceExW(mountpoint, NULL, (PULARGE_INTEGER)&disk->bytesTotal, (PULARGE_INTEGER)&bytesFree))
{
disk->bytesTotal = 0;
bytesFree = 0;
@@ -37,26 +33,33 @@ void ffDetectDisksImpl(FFDiskResult* disks)
disk->bytesUsed = disk->bytesTotal - bytesFree;
if(driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM)
disk->type = FF_DISK_TYPE_EXTERNAL;
disk->type = FF_DISK_TYPE_EXTERNAL_BIT;
else if(driveType == DRIVE_FIXED)
disk->type = FF_DISK_TYPE_REGULAR;
disk->type = FF_DISK_TYPE_REGULAR_BIT;
else
disk->type = FF_DISK_TYPE_HIDDEN;
disk->type = FF_DISK_TYPE_HIDDEN_BIT;
ffStrbufInit(&disk->filesystem);
ffStrbufInit(&disk->name);
wchar_t diskName[MAX_PATH + 1], diskFileSystem[MAX_PATH + 1];
ffStrbufInitA(&disk->filesystem, MAX_PATH + 1);
ffStrbufInitA(&disk->name, MAX_PATH + 1);
//https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa#remarks
UINT errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
GetVolumeInformationA(mountpoint,
disk->name.chars, disk->name.allocated, //Volume name
BOOL result = GetVolumeInformationW(mountpoint,
diskName, sizeof(diskName) / sizeof(*diskName), //Volume name
NULL, //Serial number
NULL, //Max component length
NULL, //File system flags
disk->filesystem.chars, disk->filesystem.allocated
diskFileSystem, sizeof(diskFileSystem) / sizeof(*diskFileSystem)
);
SetErrorMode(errorMode);
ffStrbufRecalculateLength(&disk->name);
ffStrbufRecalculateLength(&disk->filesystem);
if(result)
{
ffStrbufSetWS(&disk->filesystem, diskFileSystem);
ffStrbufSetWS(&disk->name, diskName);
}
//TODO: implement
disk->filesUsed = 0;
@@ -64,6 +67,4 @@ void ffDetectDisksImpl(FFDiskResult* disks)
i += disk->mountpoint.length;
}
free(buf);
}
@@ -1,6 +1,7 @@
#include "displayserver.h"
#include "common/sysctl.h"
#include "util/apple/cf_helpers.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <ctype.h>
@@ -73,7 +74,7 @@ static void detectWMPlugin(FFstrbuf* name)
u_int requestLength = sizeof(request) / sizeof(*request);
size_t length = 0;
struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length);
FF_AUTO_FREE struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length);
if(processes == NULL)
return;
@@ -94,8 +95,6 @@ static void detectWMPlugin(FFstrbuf* name)
name->chars[0] = (char) toupper(name->chars[0]);
break;
}
free(processes);
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
@@ -109,6 +108,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins
if(instance->config.allowSlowOperations)
{
FF_STRBUF_AUTO_DESTROY name;
ffStrbufInit(&name);
detectWMPlugin(&name);
if(name.length)
ffStrbufAppendF(&ds->wmPrettyName, " (with %s)", name.chars);
@@ -117,7 +117,6 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins
ffStrbufInit(&ds->deProcessName);
ffStrbufInit(&ds->dePrettyName);
ffStrbufInit(&ds->deVersion);
ffStrbufInit(&ds->deProcessName);
ffStrbufAppendS(&ds->dePrettyName, "Aqua");
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
@@ -5,27 +5,6 @@
#include <dwmapi.h>
#include <WinUser.h>
typedef struct
{
WCHAR* deviceName;
uint32_t width;
uint32_t height;
} DataBundle;
static CALLBACK WINBOOL enumMonitorProc(HMONITOR hMonitor, FF_MAYBE_UNUSED HDC hDC, FF_MAYBE_UNUSED LPRECT rc, LPARAM lparam)
{
DataBundle* data = (DataBundle*) lparam;
MONITORINFOEXW mi = { .cbSize = sizeof(mi) };
if(GetMonitorInfoW(hMonitor, (MONITORINFO *)&mi) && wcscmp(mi.szDevice, data->deviceName) == 0)
{
data->width = (uint32_t) (mi.rcMonitor.right - mi.rcMonitor.left);
data->height = (uint32_t) (mi.rcMonitor.bottom - mi.rcMonitor.top);
return FALSE;
}
return TRUE;
}
static void detectDisplays(FFDisplayServerResult* ds, bool detectName)
{
DISPLAYCONFIG_PATH_INFO paths[128];
@@ -45,8 +24,6 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName)
{
DISPLAYCONFIG_PATH_INFO* path = &paths[i];
DataBundle data = {};
DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName = {
.header = {
.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME,
@@ -55,10 +32,14 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName)
.id = path->sourceInfo.id,
},
};
uint32_t scaledWidth = 0, scaledHeight = 0;
if (DisplayConfigGetDeviceInfo(&sourceName.header) == ERROR_SUCCESS)
{
data.deviceName = sourceName.viewGdiDeviceName;
EnumDisplayMonitors(NULL, NULL, enumMonitorProc, (LPARAM) &data);
HDC hdc = CreateICW(sourceName.viewGdiDeviceName, NULL, NULL, NULL);
scaledWidth = (uint32_t) GetDeviceCaps(hdc, HORZRES);
scaledHeight = (uint32_t) GetDeviceCaps(hdc, VERTRES);
DeleteDC(hdc);
}
FF_STRBUF_AUTO_DESTROY name;
@@ -101,8 +82,8 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName)
width,
height,
path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator,
data.width,
data.height,
scaledWidth,
scaledHeight,
&name,
path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL ||
path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED ||
@@ -145,7 +126,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins
) ffStrbufSetS(&ds->dePrettyName, "Fluent");
else if(
ffStrbufEqualS(&os->version, "8") ||
ffStrbufEqualS(&os->version, "81.") ||
ffStrbufEqualS(&os->version, "8.1") ||
ffStrbufEqualS(&os->version, "2012 R2") ||
ffStrbufEqualS(&os->version, "2012")
) ffStrbufSetS(&ds->dePrettyName, "Metro");
+79 -25
View File
@@ -9,6 +9,7 @@
#include "common/thread.h"
#include <wayland-client.h>
#include <sys/socket.h>
#include <assert.h>
typedef struct WaylandData
{
@@ -19,6 +20,7 @@ typedef struct WaylandData
FF_LIBRARY_SYMBOL(wl_display_roundtrip)
struct wl_display* display;
const struct wl_interface* ffwl_output_interface;
bool detectName;
} WaylandData;
typedef struct WaylandDisplay
@@ -27,6 +29,10 @@ typedef struct WaylandDisplay
int32_t height;
int32_t refreshRate;
int32_t scale;
enum wl_output_transform transform;
FFDisplayType type;
FFstrbuf name;
bool detectName;
} WaylandDisplay;
#ifndef __FreeBSD__
@@ -57,10 +63,8 @@ static void stubListener(void* data, ...)
(void) data;
}
static void waylandOutputModeListener(void* data, struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate)
static void waylandOutputModeListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate)
{
FF_UNUSED(output);
if(!(flags & WL_OUTPUT_MODE_CURRENT))
return;
@@ -70,15 +74,46 @@ static void waylandOutputModeListener(void* data, struct wl_output* output, uint
display->refreshRate = refreshRate;
}
#if WAYLAND_VERSION_MINOR >= 2
static void waylandOutputScaleListener(void* data, struct wl_output* output, int32_t scale)
static void waylandOutputScaleListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, int32_t scale)
{
FF_UNUSED(output);
WaylandDisplay* display = data;
display->scale = scale;
}
#endif
static void waylandOutputGeometryListener(void *data,
FF_MAYBE_UNUSED struct wl_output *output,
FF_MAYBE_UNUSED int32_t x,
FF_MAYBE_UNUSED int32_t y,
FF_MAYBE_UNUSED int32_t physical_width,
FF_MAYBE_UNUSED int32_t physical_height,
FF_MAYBE_UNUSED int32_t subpixel,
const char *make,
const char *model,
int32_t transform)
{
WaylandDisplay* display = data;
display->transform = (enum wl_output_transform) transform;
if(display->detectName)
{
if(make && strcmp(make, "unknown") != 0)
ffStrbufAppendS(&display->name, make);
if(model && strcmp(model, "unknown") != 0)
{
if(display->name.length > 0)
ffStrbufAppendC(&display->name, '-');
ffStrbufAppendS(&display->name, model);
}
}
}
static void waylandOutputNameListener(void *data, FF_MAYBE_UNUSED struct wl_output *output, const char *name)
{
WaylandDisplay* display = data;
if(strncmp(name, "eDP-", strlen("eDP-")) == 0)
display->type = FF_DISPLAY_TYPE_BUILTIN;
else if(strncmp(name, "HDMI-", strlen("HDMI-")) == 0 || strncmp(name, "DP-", strlen("DP-")) == 0)
display->type = FF_DISPLAY_TYPE_EXTERNAL;
}
static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
{
@@ -87,28 +122,30 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist
return;
WaylandDisplay display = {
.detectName = wldata->detectName,
.width = 0,
.height = 0,
.refreshRate = 0,
.scale = 1,
.transform = WL_OUTPUT_TRANSFORM_NORMAL,
.type = FF_DISPLAY_TYPE_UNKNOWN,
};
ffStrbufInit(&display.name);
struct wl_output_listener outputListener = {
.mode = waylandOutputModeListener,
.geometry = (void*) stubListener,
//https://lists.freedesktop.org/archives/wayland-devel/2013-July/010278.html
#if WAYLAND_VERSION_MINOR >= 2
.done = (void*) stubListener,
.scale = waylandOutputScaleListener,
#endif
//https://lists.freedesktop.org/archives/wayland-devel/2021-December/042064.html
#if WAYLAND_VERSION_MINOR >= 20
.name = (void*) stubListener,
.description = (void*) stubListener,
#endif
// Dirty hack for #477
// The order of these callbacks MUST follow `struct wl_output_listener`
void* outputListener[] = {
waylandOutputGeometryListener, // geometry
waylandOutputModeListener, // mode
stubListener, // done
waylandOutputScaleListener, // scale
waylandOutputNameListener, // name
stubListener, // description
};
static_assert(
sizeof(outputListener) >= sizeof(struct wl_output_listener),
"sizeof(outputListener) is too small. Please report it to fastfetch github issue"
);
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display);
wldata->ffwl_display_roundtrip(wldata->display);
@@ -120,14 +157,29 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
ffThreadMutexLock(&mutex);
switch(display.transform)
{
case WL_OUTPUT_TRANSFORM_90:
case WL_OUTPUT_TRANSFORM_270:
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_270: {
int32_t temp = display.width;
display.width = display.height;
display.height = temp;
break;
}
default:
break;
}
ffdsAppendDisplay(wldata->result,
(uint32_t) display.width,
(uint32_t) display.height,
display.refreshRate / 1000.0,
(uint32_t) (display.width / display.scale),
(uint32_t) (display.height / display.scale),
NULL,
FF_DISPLAY_TYPE_UNKNOWN
&display.name,
display.type
);
ffThreadMutexUnlock(&mutex);
@@ -164,6 +216,8 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
if(data.display == NULL)
return false;
data.detectName = instance->config.displayDetectName;
waylandDetectWM(ffwl_display_get_fd(data.display), result);
struct wl_proxy* registry = ffwl_proxy_marshal_constructor((struct wl_proxy*) data.display, WL_DISPLAY_GET_REGISTRY, ffwl_registry_interface, NULL);
+32 -1
View File
@@ -125,14 +125,35 @@ static void getKDE(const FFinstance* instance, FFDisplayServerResult* result)
ffStrbufSetS(&result->deProcessName, "plasmashell");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
ffParsePropFileData(instance, "xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
ffParsePropFileValues("/usr/share/xsessions/plasmax11.desktop", 1, (FFpropquery[]) {
{"X-KDE-PluginInfo-Version =", &result->deVersion}
});
if(result->deVersion.length == 0)
ffParsePropFileData(instance, "xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0)
ffParsePropFileData(instance, "xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0)
{
ffParsePropFileValues("/usr/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) {
{"X-KDE-PluginInfo-Version =", &result->deVersion}
});
}
if(result->deVersion.length == 0)
ffParsePropFileData(instance, "wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0)
ffParsePropFileData(instance, "wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
if(result->deVersion.length == 0 && instance->config.allowSlowOperations)
{
if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){
"plasmashell",
"--version",
NULL
}) == NULL) // plasmashell 5.27.5
ffStrbufSubstrAfterLastC(&result->deVersion, ' ');
}
applyBetterWM(result, getenv("KDEWM"));
}
@@ -141,6 +162,16 @@ static void getGnome(const FFinstance* instance, FFDisplayServerResult* result)
ffStrbufSetS(&result->deProcessName, "gnome-shell");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME);
ffParsePropFileData(instance, "gnome-shell/org.gnome.Extensions", "version :", &result->deVersion);
if (result->deVersion.length == 0)
{
if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){
"gnome-shell",
"--version",
NULL
}) == NULL) // GNOME Shell 44.1
ffStrbufSubstrAfterLastC(&result->deVersion, ' ');
}
}
static void getCinnamon(const FFinstance* instance, FFDisplayServerResult* result)
+1 -1
View File
@@ -175,7 +175,7 @@ typedef struct XcbRandrData
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo)
{
double refreshRate = modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal);
double refreshRate = (double) modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal);
return ffdsAppendDisplay(
data->result,
+1 -1
View File
@@ -134,7 +134,7 @@ typedef struct XrandrData
static bool xrandrHandleModeInfo(XrandrData* data, XRRModeInfo* modeInfo)
{
double refreshRate = modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
double refreshRate = (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
return ffdsAppendDisplay(
data->result,
+1
View File
@@ -9,6 +9,7 @@ static void detectFont(const FFinstance* instance, FFFontResult* font)
for(uint32_t i = 0; i < FF_DETECT_FONT_NUM_FONTS; ++i)
ffStrbufInit(&font->fonts[i]);
ffStrbufInit(&font->display);
ffDetectFontImpl(instance, font);
+1
View File
@@ -18,6 +18,7 @@ typedef struct FFFontResult
* Other: Unset, Unset, Unset, Unset
*/
FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS];
FFstrbuf display;
} FFFontResult;
const FFFontResult* ffDetectFont(const FFinstance* instance);
+18
View File
@@ -4,6 +4,23 @@
#import <AppKit/NSFont.h>
static void generateString(FFFontResult* font)
{
if(font->fonts[0].length > 0)
{
ffStrbufAppend(&font->display, &font->fonts[0]);
ffStrbufAppendS(&font->display, " [System]");
if(font->fonts[1].length > 0)
ffStrbufAppendS(&font->display, ", ");
}
if(font->fonts[1].length > 0)
{
ffStrbufAppend(&font->display, &font->fonts[1]);
ffStrbufAppendS(&font->display, " [User]");
}
}
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
{
FF_UNUSED(instance);
@@ -11,4 +28,5 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
ffStrbufAppendS(&result->fonts[1], [NSFont userFontOfSize:12].familyName.UTF8String);
ffStrbufAppendS(&result->fonts[2], [NSFont monospacedSystemFontOfSize:12 weight:400].familyName.UTF8String);
ffStrbufAppendS(&result->fonts[3], [NSFont userFixedPitchFontOfSize:12].familyName.UTF8String);
generateString(result);
}
+23
View File
@@ -1,8 +1,29 @@
#include "common/font.h"
#include "common/parsing.h"
#include "detection/displayserver/displayserver.h"
#include "detection/gtk_qt/gtk_qt.h"
#include "font.h"
static void generateString(FFFontResult* font)
{
if(font->fonts[0].length > 0)
{
ffStrbufAppend(&font->display, &font->fonts[0]);
ffStrbufAppendS(&font->display, " [QT]");
for(uint8_t i = 1; i < sizeof(font->fonts) / sizeof(font->fonts[0]); i++)
{
if(font->fonts[i].length > 0)
{
ffStrbufAppendS(&font->display, ", ");
break;
}
}
}
ffParseGTK(&font->display, &font->fonts[1], &font->fonts[2], &font->fonts[3]);
}
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
{
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
@@ -32,4 +53,6 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
ffFontInitPango(&gtk4, ffDetectGTK4(instance)->font.chars);
ffStrbufAppend(&result->fonts[3], &gtk4.pretty);
ffFontDestroy(&gtk4);
generateString(result);
}
+22
View File
@@ -3,6 +3,26 @@
#include <windows.h>
static void generateString(FFFontResult* font)
{
const char* types[] = { "Caption", "Menu", "Message", "Status" };
for(uint32_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i)
{
if(i == 0 || !ffStrbufEqual(&font->fonts[i - 1], &font->fonts[i]))
{
if(i > 0)
ffStrbufAppendS(&font->display, "], ");
ffStrbufAppendF(&font->display, "%s [%s", font->fonts[i].chars, types[i]);
}
else
{
ffStrbufAppendS(&font->display, " / ");
ffStrbufAppendS(&font->display, types[i]);
}
}
ffStrbufAppendC(&font->display, ']');
}
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
{
FF_UNUSED(instance);
@@ -19,4 +39,6 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
if(fonts[i]->lfHeight < 0)
ffStrbufAppendF(&result->fonts[i], " (%dpt)", (int)-fonts[i]->lfHeight);
}
generateString(result);
}
+2 -3
View File
@@ -17,7 +17,7 @@ static const char* detectKnownGamepad(uint32_t vendorId, uint32_t productId)
{
case 0x2006: return "Nintendo Switch Joycon L";
case 0x2007: return "Nintendo Switch Joycon R";
case 0x2009: return "Nintendo Switch Pro";
case 0x2009: return "Nintendo Switch Pro Controller";
case 0x200E: return "Nintendo Switch Charging Grip";
case 0x2017: return "Nintendo Switch SNES Controller";
@@ -117,8 +117,7 @@ const char* ffDetectGamepad(FF_MAYBE_UNUSED const FFinstance* instance, FFlist*
continue;
FFGamepadDevice* device = (FFGamepadDevice*) ffListAdd(devices);
ffStrbufInit(&device->identifier);
ffStrbufSetWS(&device->identifier, devName);
ffStrbufInitWS(&device->identifier, devName);
ffStrbufInit(&device->name);
const char* knownGamepad = detectKnownGamepad(rdi.hid.dwVendorId, rdi.hid.dwProductId);
+1
View File
@@ -37,6 +37,7 @@ typedef struct FFGPUResult
int coreCount;
FFGPUMemory dedicated;
FFGPUMemory shared;
uint32_t vulkanDeviceId; // Only used for vulkan
} FFGPUResult;
const FFlist* ffDetectGPU(const FFinstance* instance);
+20 -17
View File
@@ -5,7 +5,6 @@
#include "util/apple/cf_helpers.h"
#include <IOKit/graphics/IOGraphicsLib.h>
#include <wchar.h>
static double detectGpuTemp(const FFstrbuf* gpuName)
{
@@ -63,23 +62,18 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
ffStrbufInit(&gpu->vendor);
int vendorId;
if(!ffCfDictGetInt(properties, CFSTR("vendor-id"), &vendorId))
{
const char* vendorStr = ffGetGPUVendorString((unsigned) vendorId);
ffStrbufAppendS(&gpu->vendor, vendorStr);
if (vendorStr == FF_GPU_VENDOR_NAME_APPLE || vendorStr == FF_GPU_VENDOR_NAME_INTEL)
gpu->type = FF_GPU_TYPE_INTEGRATED;
else if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA || vendorStr == FF_GPU_VENDOR_NAME_AMD)
gpu->type = FF_GPU_TYPE_DISCRETE;
}
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->driver); // Ok for both Apple and Intel
ffCfDictGetString(properties, CFSTR("CFBundleIdentifier"), &gpu->driver);
int vram; // Supported on Intel
if(!ffCfDictGetInt(properties, CFSTR("VRAM,totalMB"), &vram))
gpu->dedicated.total = (uint64_t) vram * 1024 * 1024;
if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount)) // For Apple
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
ffStrbufInit(&gpu->name);
//IOAccelerator returns model property for Apple Silicon, but not for Intel Iris GPUs.
//IOAccelerator returns model / vendor-id properties for Apple Silicon, but not for Intel Iris GPUs.
//Still needs testing for AMD's
if(ffCfDictGetString(properties, CFSTR("model"), &gpu->name))
{
@@ -96,8 +90,17 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
ffCfDictGetString(properties, CFSTR("model"), &gpu->name);
}
if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount))
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
ffStrbufInit(&gpu->vendor);
int vendorId;
if(!ffCfDictGetInt(properties, CFSTR("vendor-id"), &vendorId))
{
const char* vendorStr = ffGetGPUVendorString((unsigned) vendorId);
ffStrbufAppendS(&gpu->vendor, vendorStr);
if (vendorStr == FF_GPU_VENDOR_NAME_APPLE || vendorStr == FF_GPU_VENDOR_NAME_INTEL)
gpu->type = FF_GPU_TYPE_INTEGRATED;
else if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA || vendorStr == FF_GPU_VENDOR_NAME_AMD)
gpu->type = FF_GPU_TYPE_DISCRETE;
}
if(instance->config.gpuTemp)
gpu->temperature = detectGpuTemp(&gpu->name);
+1 -1
View File
@@ -46,7 +46,7 @@ static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
static void drmDetectDeviceName(const FFinstance* instance, FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
{
u8 revId;
u8 revId = 0;
bool revIdSet = false;
#if PCI_LIB_VERSION >= 0x030800
+19 -7
View File
@@ -4,31 +4,43 @@
#include <inttypes.h>
static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
{
return ffStrbufEqual(&gpu->name, name);
}
const char* ffDetectGPUImpl(FFlist* gpus, FF_MAYBE_UNUSED const FFinstance* instance)
{
DISPLAY_DEVICEW displayDevice = {.cb = sizeof(displayDevice) };
DISPLAY_DEVICEW displayDevice = { .cb = sizeof(displayDevice) };
wchar_t regKey[MAX_PATH] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\{";
const uint32_t regKeyPrefixLength = strlen("SYSTEM\\CurrentControlSet\\Control\\Video\\{");
const uint32_t deviceKeyPrefixLength = strlen("\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{");
const uint32_t regKeyPrefixLength = (uint32_t) wcslen(regKey);
const uint32_t deviceKeyPrefixLength = strlen("\\Registry\\Machine\\") + regKeyPrefixLength;
for (DWORD i = 0; EnumDisplayDevicesW(NULL, i, &displayDevice, 0); ++i)
{
if (displayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) continue;
const uint32_t deviceKeyLength = (uint32_t) wcslen(displayDevice.DeviceKey);
if (wmemcmp(&displayDevice.DeviceKey[deviceKeyLength - 4], L"0000", 4) != 0) continue;
if (__builtin_expect(deviceKeyLength == 100, true))
{
if (wmemcmp(&displayDevice.DeviceKey[deviceKeyLength - 4], L"0000", 4) != 0) continue;
}
else
{
// DeviceKey can be empty. See #484
FF_STRBUF_AUTO_DESTROY gpuName = ffStrbufCreateWS(displayDevice.DeviceString);
if (ffListFirstIndexComp(gpus, &gpuName, (void*) isGpuNameEqual) != gpus->length) continue;
}
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->name);
ffStrbufInitWS(&gpu->name, displayDevice.DeviceString);
ffStrbufInit(&gpu->driver);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
ffStrbufSetWS(&gpu->name, displayDevice.DeviceString);
if (deviceKeyLength == 100 && displayDevice.DeviceKey[deviceKeyPrefixLength - 1] == '{')
{
wmemcpy(regKey + regKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, 100 - regKeyPrefixLength + 1);
+14 -3
View File
@@ -13,7 +13,7 @@ static inline bool allPropertiesSet(FFGTKResult* result)
result->font.length > 0;
}
static inline void applyGTKSettings(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, const char* wallpaper)
{
if(result->theme.length == 0)
ffStrbufAppendS(&result->theme, themeName);
@@ -29,6 +29,9 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
if(result->cursorSize.length == 0 && cursorSize > 0)
ffStrbufAppendF(&result->cursorSize, "%i", cursorSize);
if(result->wallpaper.length == 0)
ffStrbufAppendS(&result->wallpaper, wallpaper);
}
static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* result)
@@ -40,6 +43,7 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
static const char* fontName = NULL;
static const char* cursorTheme = NULL;
static int cursorSize = 0;
static const char* wallpaper = NULL;
static bool init = false;
@@ -48,7 +52,7 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
if(init)
{
ffThreadMutexUnlock(&mutex);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
return;
}
@@ -63,6 +67,9 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
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;
wallpaper = ffSettingsGetXFConf(instance, "xfce4-desktop", "/backdrop/screen0/monitor0/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue;
if (!wallpaper) // FIXME: find a way to enumerate possible properties
wallpaper = ffSettingsGetXFConf(instance, "xfce4-desktop", "/backdrop/screen0/monitoreDP-1/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue;
}
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_CINNAMON) == 0)
{
@@ -71,6 +78,7 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
fontName = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/font-name", "org.cinnamon.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
cursorTheme = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/cursor-theme", "org.cinnamon.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
cursorSize = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/cursor-size", "org.cinnamon.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
wallpaper = ffSettingsGet(instance, "/org/cinnamon/desktop/background/picture-uri", "org.cinnamon.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
}
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_MATE) == 0)
{
@@ -79,6 +87,7 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
fontName = ffSettingsGet(instance, "/org/mate/interface/font-name", "org.mate.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
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;
wallpaper = ffSettingsGet(instance, "/org/mate/desktop/background", "org.mate.background", NULL, "picture-filename", FF_VARIANT_TYPE_STRING).strValue;
}
else if(
ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_GNOME) == 0 ||
@@ -90,10 +99,11 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
fontName = ffSettingsGet(instance, "/org/gnome/desktop/interface/font-name", "org.gnome.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
cursorTheme = ffSettingsGet(instance, "/org/gnome/desktop/interface/cursor-theme", "org.gnome.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
cursorSize = ffSettingsGet(instance, "/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
wallpaper = ffSettingsGet(instance, "/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
}
ffThreadMutexUnlock(&mutex);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
}
static void detectGTKFromConfigFile(const char* filename, FFGTKResult* result)
@@ -184,6 +194,7 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu
ffStrbufInit(&result.font); \
ffStrbufInit(&result.cursor); \
ffStrbufInit(&result.cursorSize); \
ffStrbufInit(&result.wallpaper); \
detectGTK(instance, #version, &result); \
ffThreadMutexUnlock(&mutex); \
return &result;
+2
View File
@@ -12,6 +12,7 @@ typedef struct FFGTKResult
FFstrbuf font;
FFstrbuf cursor;
FFstrbuf cursorSize;
FFstrbuf wallpaper;
} FFGTKResult;
typedef struct FFQtResult
@@ -20,6 +21,7 @@ typedef struct FFQtResult
FFstrbuf colorScheme;
FFstrbuf icons;
FFstrbuf font;
FFstrbuf wallpaper;
} FFQtResult;
const FFGTKResult* ffDetectGTK2(const FFinstance* instance);
+10 -1
View File
@@ -13,7 +13,8 @@ static inline bool allValuesSet(const FFQtResult* result)
result->widgetStyle.length > 0 &&
result->colorScheme.length > 0 &&
result->icons.length > 0 &&
result->font.length > 0;
result->font.length > 0 &&
result->wallpaper.length > 0;
}
typedef enum PlasmaCategory
@@ -96,6 +97,11 @@ static void detectPlasma(const FFinstance* instance, FFQtResult* result)
if(detectPlasmaFromFile(baseDir.chars, result))
foundAFile = true;
ffStrbufSet(&baseDir, configDir);
ffStrbufAppendS(&baseDir, "plasma-org.kde.plasma.desktop-appletsrc");
ffParsePropFile(baseDir.chars, "Image=", &result->wallpaper);
if(allValuesSet(result))
{
ffStrbufDestroy(&baseDir);
@@ -129,6 +135,8 @@ static void detectLXQt(const FFinstance* instance, FFQtResult* result)
{"icon_theme = ", &result->icons},
{"font = ", &result->font}
});
ffParsePropFileConfig(instance, "pcmanfm-qt/lxqt/settings.conf", "Wallpaper=", &result->wallpaper);
}
const FFQtResult* ffDetectQt(const FFinstance* instance)
@@ -149,6 +157,7 @@ const FFQtResult* ffDetectQt(const FFinstance* instance)
ffStrbufInit(&result.colorScheme);
ffStrbufInit(&result.icons);
ffStrbufInit(&result.font);
ffStrbufInit(&result.wallpaper);
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
+4
View File
@@ -112,6 +112,10 @@ static const char* getProductName(const FFstrbuf* hwModel)
else if(ffStrbufStartsWithS(hwModel, "Mac"))
{
const char* version = hwModel->chars + strlen("Mac");
if(strEqual(version, "14,15")) return "MacBook Air (15-inch, M2, 2023)";
if(strEqual(version, "14,14")) return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)";
if(strEqual(version, "14,13")) return "Mac Studio (M2 Max, 2023, Two USB-C front ports)";
if(strEqual(version, "14,8")) return "Mac Pro (2023)";
if(strEqual(version, "14,6") ||
strEqual(version, "14,10")) return "MacBook Pro (16-inch, 2023)";
if(strEqual(version, "14,5") ||
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#ifndef FF_INCLUDED_detection_icons
#define FF_INCLUDED_detection_icons
#include "fastfetch.h"
const char* ffDetectIcons(const FFinstance* instance, FFstrbuf* result);
#endif
+36
View File
@@ -0,0 +1,36 @@
#include "icons.h"
#include "common/parsing.h"
#include "detection/gtk_qt/gtk_qt.h"
#include "detection/displayserver/displayserver.h"
const char* ffDetectIcons(const FFinstance* instance, FFstrbuf* result)
{
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0)
return "Icons aren't supported in TTY";
const FFstrbuf* plasma = &ffDetectQt(instance)->icons;
const FFstrbuf* gtk2 = &ffDetectGTK2(instance)->icons;
const FFstrbuf* gtk3 = &ffDetectGTK3(instance)->icons;
const FFstrbuf* gtk4 = &ffDetectGTK4(instance)->icons;
if(plasma->length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0)
return "No icons could be found";
FF_STRBUF_AUTO_DESTROY gtkPretty;
ffStrbufInit(&gtkPretty);
ffParseGTK(&gtkPretty, gtk2, gtk3, gtk4);
if(plasma->length > 0)
{
ffStrbufAppend(result, plasma);
ffStrbufAppendS(result, " [QT]");
if(gtkPretty.length > 0)
ffStrbufAppendS(result, ", ");
}
ffStrbufAppend(result, &gtkPretty);
return NULL;
}
+6
View File
@@ -0,0 +1,6 @@
#include "icons.h"
const char* ffDetectIcons(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFstrbuf* result)
{
return "Not supported on this platform";
}
+33
View File
@@ -0,0 +1,33 @@
#include "icons.h"
#include "util/windows/registry.h"
const char* ffDetectIcons(FF_MAYBE_UNUSED const FFinstance* instance, FFstrbuf* result)
{
FF_HKEY_AUTO_DESTROY hKey = NULL;
if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu", &hKey, NULL))
return "ffRegOpenKeyForRead(Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu) failed";
// Whether these icons are hidden
uint32_t ThisPC = 0, UsersFiles = 0, RemoteNetwork = 0, RecycleBin = 0, ControlPanel = 0;
ffRegReadUint(hKey, L"{20D04FE0-3AEA-1069-A2D8-08002B30309D}", &ThisPC, NULL);
ffRegReadUint(hKey, L"{59031a47-3f72-44a7-89c5-5595fe6b30ee}", &UsersFiles, NULL);
ffRegReadUint(hKey, L"{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}", &RemoteNetwork, NULL);
ffRegReadUint(hKey, L"{645FF040-5081-101B-9F08-00AA002F954E}", &RecycleBin, NULL);
ffRegReadUint(hKey, L"{5399E694-6CE5-4D6C-8FCE-1D8870FDCBA0}", &ControlPanel, NULL);
if (!ThisPC)
ffStrbufAppendS(result, "This PC, ");
if (!UsersFiles)
ffStrbufAppendS(result, "User's Files, ");
if (!RemoteNetwork)
ffStrbufAppendS(result, "Remote Network, ");
if (!RecycleBin)
ffStrbufAppendS(result, "Recycle Bin, ");
if (!ControlPanel)
ffStrbufAppendS(result, "Control Panel");
ffStrbufTrimRight(result, ' ');
ffStrbufTrimRight(result, ',');
return NULL;
}
+3 -2
View File
@@ -8,8 +8,9 @@
typedef struct FFLocalIpResult
{
FFstrbuf name;
FFstrbuf addr;
bool ipv6;
FFstrbuf ipv4;
FFstrbuf ipv6;
FFstrbuf mac;
} FFLocalIpResult;
const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results);
+65 -16
View File
@@ -2,21 +2,48 @@
#include <string.h>
#include <ctype.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#ifdef __FreeBSD__
#include <sys/socket.h> // FreeBSD needs this for AF_INET
#if defined(__FreeBSD__) || defined(__APPLE__)
#include <net/if_dl.h>
#else
#include <linux/if_packet.h>
#endif
static void addNewIp(FFlist* list, const char* name, const char* addr, bool ipv6)
static void addNewIp(FFlist* list, const char* name, const char* addr, int type)
{
FFLocalIpResult* ip = (FFLocalIpResult*) ffListAdd(list);
ffStrbufInitS(&ip->name, name);
ffStrbufInitS(&ip->addr, addr);
ip->ipv6 = ipv6;
FFLocalIpResult* ip = NULL;
FF_LIST_FOR_EACH(FFLocalIpResult, temp, *list)
{
if (!ffStrbufEqualS(&temp->name, name)) continue;
ip = temp;
break;
}
if (!ip)
{
ip = (FFLocalIpResult*) ffListAdd(list);
ffStrbufInitS(&ip->name, name);
ffStrbufInit(&ip->ipv4);
ffStrbufInit(&ip->ipv6);
ffStrbufInit(&ip->mac);
}
switch (type)
{
case AF_INET:
ffStrbufSetS(&ip->ipv4, addr);
break;
case AF_INET6:
ffStrbufSetS(&ip->ipv6, addr);
break;
case -1:
ffStrbufSetS(&ip->mac, addr);
break;
}
}
const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results)
@@ -30,8 +57,7 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results)
if (!ifa->ifa_addr || !(ifa->ifa_flags & IFF_RUNNING))
continue;
// loop back
if (strncmp(ifa->ifa_name, "lo", 2) == 0 && (ifa->ifa_name[2] == '\0' || isdigit(ifa->ifa_name[2])) && !instance->config.localIpShowLoop)
if ((ifa->ifa_flags & IFF_LOOPBACK) && !(instance->config.localIpShowType & FF_LOCALIP_TYPE_LOOP_BIT))
continue;
if (instance->config.localIpNamePrefix.length && strncmp(ifa->ifa_name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0)
@@ -39,26 +65,49 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results)
if (ifa->ifa_addr->sa_family == AF_INET)
{
// IPv4
if (!instance->config.localIpShowIpV4)
if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV4_BIT))
continue;
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
addNewIp(results, ifa->ifa_name, addressBuffer, false);
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET);
}
else if (ifa->ifa_addr->sa_family == AF_INET6)
{
// IPv6
if (!instance->config.localIpShowIpV6)
if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV6_BIT))
continue;
struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr;
char addressBuffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
addNewIp(results, ifa->ifa_name, addressBuffer, true);
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6);
}
#if defined(__FreeBSD__) || defined(__APPLE__)
else if (ifa->ifa_addr->sa_family == AF_LINK)
{
if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT))
continue;
char addressBuffer[32];
uint8_t* ptr = (uint8_t*) LLADDR((struct sockaddr_dl *)ifa->ifa_addr);
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1);
}
#else
else if (ifa->ifa_addr->sa_family == AF_PACKET)
{
if (!(instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT))
continue;
char addressBuffer[32];
uint8_t* ptr = ((struct sockaddr_ll *)ifa->ifa_addr)->sll_addr;
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1);
}
#endif
}
if (ifAddrStruct) freeifaddrs(ifAddrStruct);
+53 -24
View File
@@ -1,21 +1,45 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <wchar.h>
#include "util/mallocHelper.h"
#include "util/windows/unicode.h"
#include "localip.h"
static void addNewIp(FFlist* list, const char* name, const char* addr, bool ipv6)
static void addNewIp(FFlist* list, const char* name, const char* value, int type, bool newIp)
{
FFLocalIpResult* ip = (FFLocalIpResult*) ffListAdd(list);
ffStrbufInitS(&ip->name, name);
ffStrbufInitS(&ip->addr, addr);
ip->ipv6 = ipv6;
FFLocalIpResult* ip = NULL;
if (newIp)
{
ip = (FFLocalIpResult*) ffListAdd(list);
ffStrbufInitS(&ip->name, name);
ffStrbufInit(&ip->ipv4);
ffStrbufInit(&ip->ipv6);
ffStrbufInit(&ip->mac);
}
else
{
ip = ffListGet(list, list->length - 1);
}
switch (type)
{
case AF_INET:
ffStrbufSetS(&ip->ipv4, value);
break;
case AF_INET6:
ffStrbufSetS(&ip->ipv6, value);
break;
case -1:
ffStrbufSetS(&ip->mac, value);
break;
}
}
const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results)
{
IP_ADAPTER_ADDRESSES* adapter_addresses = NULL;
IP_ADAPTER_ADDRESSES* FF_AUTO_FREE adapter_addresses = NULL;
// Start with a 16 KB buffer and resize if needed -
// multiple attempts in case interfaces change while
@@ -27,11 +51,10 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results)
assert(adapter_addresses);
DWORD error = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER |
GAA_FLAG_SKIP_FRIENDLY_NAME,
instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV4_BIT
? instance->config.localIpShowType & FF_LOCALIP_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET
: AF_INET6,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
NULL,
adapter_addresses,
&adapter_addresses_buffer_size);
@@ -47,41 +70,47 @@ const char* ffDetectLocalIps(const FFinstance* instance, FFlist* results)
// Iterate through all of the adapters
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
{
if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK && !instance->config.localIpShowLoop)
bool isLoop = adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK;
if (isLoop && !(instance->config.localIpShowType & FF_LOCALIP_TYPE_LOOP_BIT))
continue;
bool newIp = true;
char name[128];
WideCharToMultiByte(CP_UTF8, 0, adapter->FriendlyName, -1, name, sizeof(name), NULL, NULL);
if (instance->config.localIpNamePrefix.length && strncmp(name, instance->config.localIpNamePrefix.chars, instance->config.localIpNamePrefix.length) != 0)
continue;
if (instance->config.localIpShowType & FF_LOCALIP_TYPE_MAC_BIT && adapter->PhysicalAddressLength == 6)
{
char addressBuffer[32];
uint8_t* ptr = adapter->PhysicalAddress;
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, name, addressBuffer, -1, newIp);
newIp = false;
}
for (IP_ADAPTER_UNICAST_ADDRESS* ifa = adapter->FirstUnicastAddress; ifa; ifa = ifa->Next)
{
if (ifa->Address.lpSockaddr->sa_family == AF_INET)
{
// IPv4
if (!instance->config.localIpShowIpV4)
continue;
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
addNewIp(results, name, addressBuffer, false);
addNewIp(results, name, addressBuffer, AF_INET, newIp);
newIp = false;
}
else if (ifa->Address.lpSockaddr->sa_family == AF_INET6)
{
// IPv6
if (!instance->config.localIpShowIpV6)
continue;
SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr;
char addressBuffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
addNewIp(results, name, addressBuffer, true);
addNewIp(results, name, addressBuffer, AF_INET6, newIp);
newIp = false;
}
}
}
free(adapter_addresses);
return NULL;
}
+1 -1
View File
@@ -7,7 +7,7 @@ const FFMediaResult* ffDetectMedia(const FFinstance* instance)
{
FF_DETECTION_INTERNAL_GUARD(FFMediaResult,
ffStrbufInitA(&result.error, 0);
ffStrbufInit(&result.busNameShort);
ffStrbufInit(&result.playerId);
ffStrbufInit(&result.player);
ffStrbufInit(&result.song);
ffStrbufInit(&result.artist);
+1 -1
View File
@@ -8,7 +8,7 @@
typedef struct FFMediaResult
{
FFstrbuf error;
FFstrbuf busNameShort; //e.g. plasma-browser-integration
FFstrbuf playerId; // Bus name on Linux, app bundle name on macOS. e.g. plasma-browser-integration
FFstrbuf player; // e.g. Google Chrome
FFstrbuf song;
FFstrbuf artist;
+3 -3
View File
@@ -57,17 +57,17 @@ static const char* getMedia(FFMediaResult* result)
if (identifier == nil)
identifier = MRNowPlayingClientGetParentAppBundleIdentifier(clientObj);
if (identifier != nil)
ffCfStrGetString(identifier, &result->busNameShort);
ffCfStrGetString(identifier, &result->playerId);
}
dispatch_group_leave(group);
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
if(result->busNameShort.length > 0)
if(result->playerId.length > 0)
{
char buf[128];
snprintf(buf, sizeof(buf), "name of app id \"%s\"", result->busNameShort.chars);
snprintf(buf, sizeof(buf), "name of app id \"%s\"", result->playerId.chars);
ffOsascript(buf, &result->player);
}
+2 -2
View File
@@ -87,14 +87,14 @@ static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResul
}
//Set short bus name
ffStrbufAppendS(&result->busNameShort, busName + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
ffStrbufAppendS(&result->playerId, busName + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
//We found a song, get the player name
ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "Identity", &result->player);
if(result->player.length == 0)
ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "DesktopEntry", &result->player);
if(result->player.length == 0)
ffStrbufAppend(&result->player, &result->busNameShort);
ffStrbufAppend(&result->player, &result->playerId);
return true;
}
+8 -2
View File
@@ -3,8 +3,14 @@
#ifndef FF_INCLUDED_detection_memory_memory
#define FF_INCLUDED_detection_memory_memory
#include "detection/storage.h"
#include "fastfetch.h"
void ffDetectMemory(FFMemoryStorage* result);
typedef struct FFMemoryResult
{
uint64_t bytesUsed;
uint64_t bytesTotal;
} FFMemoryResult;
const char* ffDetectMemory(FFMemoryResult* result);
#endif
+7 -13
View File
@@ -3,31 +3,25 @@
#include <string.h>
#include <mach/mach.h>
#include <sys/sysctl.h>
#include <unistd.h>
void ffDetectMemory(FFMemoryStorage* ram)
const char* ffDetectMemory(FFMemoryResult* ram)
{
size_t length = sizeof(ram->bytesTotal);
if (sysctl((int[]){ CTL_HW, HW_MEMSIZE }, 2, &ram->bytesTotal, &length, NULL, 0))
{
ffStrbufAppendS(&ram->error, "Failed to read hw.memsize");
return;
}
return "Failed to read hw.memsize";
uint32_t pagesize;
length = sizeof(pagesize);
if (sysctl((int[]){ CTL_HW, HW_PAGESIZE }, 2, &pagesize, &length, NULL, 0))
{
ffStrbufAppendS(&ram->error, "Failed to read hw.pagesize");
return;
}
return "Failed to read hw.pagesize";
mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
vm_statistics64_data_t vmstat;
if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS)
{
ffStrbufAppendS(&ram->error, "Failed to read host_statistics64");
return;
}
return "Failed to read host_statistics64";
ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * pagesize;
return NULL;
}
+16 -17
View File
@@ -1,24 +1,23 @@
#include "memory.h"
#include "common/sysctl.h"
void ffDetectMemory(FFMemoryStorage* ram)
const char* ffDetectMemory(FFMemoryResult* ram)
{
uint32_t pageSize = (uint32_t) ffSysctlGetInt("hw.pagesize", 0);
if(pageSize == 0)
{
ffStrbufAppendS(&ram->error, "Failed to read hw.pagesize");
return;
}
uint64_t length = sizeof(ram->bytesTotal);
if (sysctl((int[]){ CTL_HW, HW_PHYSMEM }, 2, &ram->bytesTotal, &length, NULL, 0))
return "Failed to read hw.physmem";
ram->bytesTotal = (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_page_count", 0) * pageSize;
if(ram->bytesTotal == 0)
{
ffStrbufAppendS(&ram->error, "Failed to read vm.stats.vm.v_page_count");
return;
}
uint32_t pageSize;
length = sizeof(pageSize);
if (sysctl((int[]){ CTL_HW, HW_PAGESIZE }, 2, &pageSize, &length, NULL, 0))
return "Failed to read hw.pagesize";
ram->bytesUsed = ram->bytesTotal
- (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_free_count", 0) * pageSize
- (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_inactive_count", 0) * pageSize
;
// vm.stats.vm.* are int values
int32_t pagesFree = ffSysctlGetInt("vm.stats.vm.v_free_count", 0)
+ ffSysctlGetInt("vm.stats.vm.v_inactive_count", 0)
+ ffSysctlGetInt("vm.stats.vm.v_cache_count", 0);
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * pageSize;
return NULL;
}
+7 -10
View File
@@ -1,18 +1,16 @@
#include "memory.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <string.h>
void ffDetectMemory(FFMemoryStorage* ram)
const char* ffDetectMemory(FFMemoryResult* ram)
{
FILE* meminfo = fopen("/proc/meminfo", "r");
if(meminfo == NULL)
{
ffStrbufAppendS(&ram->error, "Failed to open /proc/meminfo");
return;
}
return "Failed to open /proc/meminfo";
char* line = NULL;
char* FF_AUTO_FREE line = NULL;
size_t len = 0;
uint32_t memTotal = 0,
@@ -32,14 +30,13 @@ void ffDetectMemory(FFMemoryStorage* ram)
sscanf(line, "SReclaimable: %u", &sReclaimable);
}
if(line != NULL)
free(line);
fclose(meminfo);
ram->bytesTotal = memTotal * (uint64_t) 1024;
if(ram->bytesTotal == 0)
ffStrbufAppendS(&ram->error, "Failed to read MemTotal");
return "Failed to read MemTotal";
else
ram->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024;
return NULL;
}
+4 -5
View File
@@ -2,16 +2,15 @@
#include <windows.h>
void ffDetectMemory(FFMemoryStorage* ram)
const char* ffDetectMemory(FFMemoryResult* ram)
{
MEMORYSTATUSEX statex = {
.dwLength = sizeof(statex),
};
if (!GlobalMemoryStatusEx(&statex))
{
ffStrbufAppendS(&ram->error, "GlobalMemoryStatusEx() failed");
return;
}
return "GlobalMemoryStatusEx() failed";
ram->bytesTotal = statex.ullTotalPhys;
ram->bytesUsed = statex.ullTotalPhys - statex.ullAvailPhys;
return NULL;
}
+102
View File
@@ -0,0 +1,102 @@
#include "detection/opencl/opencl.h"
#if defined(FF_HAVE_OPENCL) || defined(__APPLE__)
#include "common/library.h"
#include "common/parsing.h"
#include "util/stringUtils.h"
#include <string.h>
#define CL_TARGET_OPENCL_VERSION 100
#ifdef FF_HAVE_OPENCL
#include <CL/cl.h>
#else
#include <OpenCL/cl.h>
#endif
typedef struct OpenCLData
{
FF_LIBRARY_SYMBOL(clGetPlatformIDs)
FF_LIBRARY_SYMBOL(clGetDeviceIDs)
FF_LIBRARY_SYMBOL(clGetDeviceInfo)
} OpenCLData;
static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
{
cl_platform_id platformID;
cl_uint numPlatforms;
data->ffclGetPlatformIDs(1, &platformID, &numPlatforms);
if(numPlatforms == 0)
return "clGetPlatformIDs returned 0 platforms";
cl_device_id deviceID;
cl_uint numDevices;
data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_GPU, 1, &deviceID, &numDevices);
if(numDevices == 0)
data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_ALL, 1, &deviceID, &numDevices);
if(numDevices == 0)
return "clGetDeviceIDs returned 0 devices";
char version[64];
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(version), version, NULL);
if(!ffStrSet(version))
return "clGetDeviceInfo returned NULL or empty string";
const char* versionPretty = version;
const char* prefix = "OpenCL ";
if(strncasecmp(version, prefix, sizeof(prefix) - 1) == 0)
versionPretty = version + sizeof(prefix) - 1;
ffStrbufSetS(&result->version, versionPretty);
ffStrbufEnsureFree(&result->device, 128);
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_NAME, result->device.allocated, result->device.chars, NULL);
ffStrbufRecalculateLength(&result->device);
ffStrbufEnsureFree(&result->vendor, 32);
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR, result->vendor.allocated, result->vendor.chars, NULL);
ffStrbufRecalculateLength(&result->vendor);
return NULL;
}
#endif // defined(FF_HAVE_OPENCL) || defined(__APPLE__)
const char* ffDetectOpenCL(FFinstance* instance, FFOpenCLResult* result)
{
#ifdef FF_HAVE_OPENCL
OpenCLData data;
FF_LIBRARY_LOAD(opencl, &instance->config.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed",
#ifdef _WIN32
"OpenCL"FF_LIBRARY_EXTENSION, -1,
#endif
"libOpenCL"FF_LIBRARY_EXTENSION, 1
);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetPlatformIDs);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceIDs);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceInfo);
return openCLHandleData(&data, result);
#elif defined(__APPLE__) // FF_HAVE_OPENCL
FF_UNUSED(instance);
OpenCLData data;
data.ffclGetPlatformIDs = clGetPlatformIDs;
data.ffclGetDeviceIDs = clGetDeviceIDs;
data.ffclGetDeviceInfo = clGetDeviceInfo;
return openCLHandleData(&data, result);
#else
FF_UNUSED(instance, result);
return "Fastfetch was build without OpenCL support";
#endif // FF_HAVE_OPENCL
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#ifndef FF_INCLUDED_detection_opencl_opencl
#define FF_INCLUDED_detection_opencl_opencl
#include "fastfetch.h"
typedef struct FFOpenCLResult
{
FFstrbuf version;
FFstrbuf device;
FFstrbuf vendor;
} FFOpenCLResult;
const char* ffDetectOpenCL(FFinstance* instance, FFOpenCLResult* result);
#endif
+48 -2
View File
@@ -24,7 +24,52 @@ static void parseSystemVersion(FFOSResult* os)
ffStrbufInitS(&os->buildID, value.UTF8String);
}
void parseOSXSoftwareLicense(FFOSResult* os)
static bool detectOSCodeName(FFOSResult* os)
{
// https://en.wikipedia.org/wiki/MacOS_version_history
char* str_end;
const char* version = os->version.chars;
unsigned long num = strtoul(version, &str_end, 10);
if (str_end == version) return false;
switch (num)
{
case 14: ffStrbufAppendS(&os->codename, "Sonoma"); return true;
case 13: ffStrbufAppendS(&os->codename, "Ventura"); return true;
case 12: ffStrbufAppendS(&os->codename, "Monterey"); return true;
case 11: ffStrbufAppendS(&os->codename, "Big Sur"); return true;
case 10: {
version = str_end + 1;
num = strtoul(version, &str_end, 10);
if (str_end == version) return false;
switch (num)
{
case 16: ffStrbufAppendS(&os->codename, "Big Sur"); return true;
case 15: ffStrbufAppendS(&os->codename, "Catalina"); return true;
case 14: ffStrbufAppendS(&os->codename, "Mojave"); return true;
case 13: ffStrbufAppendS(&os->codename, "High Sierra"); return true;
case 12: ffStrbufAppendS(&os->codename, "Sierra"); return true;
case 11: ffStrbufAppendS(&os->codename, "El Capitan"); return true;
case 10: ffStrbufAppendS(&os->codename, "Yosemite"); return true;
case 9: ffStrbufAppendS(&os->codename, "Mavericks"); return true;
case 8: ffStrbufAppendS(&os->codename, "Mountain Lion"); return true;
case 7: ffStrbufAppendS(&os->codename, "Lion"); return true;
case 6: ffStrbufAppendS(&os->codename, "Snow Leopard"); return true;
case 5: ffStrbufAppendS(&os->codename, "Leopard"); return true;
case 4: ffStrbufAppendS(&os->codename, "Tiger"); return true;
case 3: ffStrbufAppendS(&os->codename, "Panther"); return true;
case 2: ffStrbufAppendS(&os->codename, "Jaguar"); return true;
case 1: ffStrbufAppendS(&os->codename, "Puma"); return true;
case 0: ffStrbufAppendS(&os->codename, "Cheetah"); return true;
}
}
}
return false;
}
static void parseOSXSoftwareLicense(FFOSResult* os)
{
FILE* rtf = fopen("/System/Library/CoreServices/Setup Assistant.app/Contents/Resources/en.lproj/OSXSoftwareLicense.rtf", "r");
if(rtf == NULL)
@@ -81,5 +126,6 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance)
ffStrbufAppend(&os->prettyName, &os->name);
ffStrbufAppend(&os->versionID, &os->version);
parseOSXSoftwareLicense(os);
if(!detectOSCodeName(os))
parseOSXSoftwareLicense(os);
}
+5 -13
View File
@@ -1,5 +1,6 @@
extern "C" {
#include "os.h"
#include "common/library.h"
#include "util/windows/unicode.h"
}
#include "util/windows/wmi.hpp"
@@ -20,27 +21,18 @@ static const char* getOsNameByWmi(FFstrbuf* osName)
return "No WMI result returned";
}
static inline void wrapFreeLibrary(HMODULE* module)
{
if(*module)
FreeLibrary(*module);
}
PWSTR WINAPI BrandingFormatString(PCWSTR format);
static const char* getOsNameByWinbrand(FFstrbuf* osName)
{
//https://dennisbabkin.com/blog/?t=how-to-tell-the-real-version-of-windows-your-app-is-running-on#ver_string
if(HMODULE __attribute__((__cleanup__(wrapFreeLibrary))) hWinbrand = LoadLibraryW(L"winbrand.dll"))
{
auto BrandingFormatString = (PWSTR(WINAPI*)(PCWSTR))(void*)GetProcAddress(hWinbrand, "BrandingFormatString");
if(!BrandingFormatString)
return "GetProcAddress(BrandingFormatString) failed";
FF_LIBRARY_LOAD(winbrand, nullptr, "dlopen winbrand" FF_LIBRARY_EXTENSION " failed", "winbrand" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(winbrand, BrandingFormatString);
const wchar_t* rawName = BrandingFormatString(L"%WINDOWS_LONG%");
const wchar_t* rawName = ffBrandingFormatString(L"%WINDOWS_LONG%");
ffStrbufSetWS(osName, rawName);
GlobalFree((HGLOBAL)rawName);
return NULL;
}
return "LoadLibraryW(winbrand.dll) failed";
}
extern "C"
+1
View File
@@ -21,6 +21,7 @@ typedef struct FFPackagesResult
uint32_t nixUser;
uint32_t pacman;
uint32_t pkg;
uint32_t pkgtool;
uint32_t port;
uint32_t rpm;
uint32_t scoop;
+18 -4
View File
@@ -135,7 +135,7 @@ static uint32_t getNixPackagesImpl(char* path)
FFstrbuf output;
ffStrbufInitA(&output, 128);
//https://github.com/LinusDierheimer/fastfetch/issues/195#issuecomment-1191748222
//https://github.com/fastfetch-cli/fastfetch/issues/195#issuecomment-1191748222
FFstrbuf command;
ffStrbufInitA(&command, 255);
ffStrbufAppendS(&command, "for x in $(nix-store --query --requisites ");
@@ -207,6 +207,19 @@ static uint32_t getSnap(FFstrbuf* baseDir)
return result > 0 ? result - 1 : 0;
}
static uint32_t getFlatpak(FFstrbuf* baseDir, const char* dirname)
{
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, dirname);
uint32_t result =
getNumElements(baseDir, "/app", DT_DIR) +
getNumElements(baseDir, "/runtime", DT_DIR);
ffStrbufSubstrBefore(baseDir, baseDirLength);
return result;
}
#ifdef FF_HAVE_RPM
#include "common/library.h"
#include <rpm/rpmlib.h>
@@ -258,11 +271,12 @@ static void getPackageCounts(const FFinstance* instance, FFstrbuf* baseDir, FFPa
packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: ");
packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE");
packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR);
packageCounts->flatpakSystem += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR);
packageCounts->flatpakSystem += getFlatpak(baseDir, "/var/lib/flatpak");
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system");
packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
packageCounts->pkg += getSQLite3Int(instance, baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages");
packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
packageCounts->rpm += getSQLite3Int(instance, baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages");
packageCounts->snap += getSnap(baseDir);
packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
@@ -320,7 +334,7 @@ void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result)
ffStrbufInitA(&baseDir, 512);
ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT);
if(ffStrbufIgnCaseCompS(&(ffDetectOS(instance)->id), "bedrock") == 0)
if(ffStrbufIgnCaseEqualS(&ffDetectOS(instance)->id, "bedrock"))
getPackageCountsBedrock(instance, &baseDir, result);
else
getPackageCountsRegular(instance, &baseDir, result);
@@ -335,5 +349,5 @@ void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result)
ffStrbufSet(&baseDir, &instance->state.platform.homeDir);
result->nixUser = getNixPackages(&baseDir, "/.nix-profile");
result->flatpakUser += getNumElements(&baseDir, "/.var/app", DT_DIR);
result->flatpakUser = getFlatpak(&baseDir, "/.local/share/flatpak");
}
+1 -1
View File
@@ -5,6 +5,6 @@
#include "fastfetch.h"
uint32_t ffDetectProcesses(FFstrbuf* error);
const char* ffDetectProcesses(uint32_t* result);
#endif
+5 -6
View File
@@ -6,15 +6,14 @@
#include <sys/user.h>
#endif
uint32_t ffDetectProcesses(FFstrbuf* error)
const char* ffDetectProcesses(uint32_t* result)
{
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
size_t length;
if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0)
{
ffStrbufAppendS(error, "sysctl() failed");
return 0;
}
return (uint32_t)(length / sizeof(struct kinfo_proc));
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_ALL}) failed";
*result = (uint32_t)(length / sizeof(struct kinfo_proc));
return NULL;
}
+5 -3
View File
@@ -2,10 +2,12 @@
#include <sys/sysinfo.h>
uint32_t ffDetectProcesses(FFstrbuf* error)
const char* ffDetectProcesses(uint32_t* result)
{
struct sysinfo info;
if(sysinfo(&info) != 0)
ffStrbufAppendS(error, "sysinfo() failed");
return (uint32_t) info.procs;
return "sysinfo() failed";
*result = (uint32_t) info.procs;
return NULL;
}
@@ -0,0 +1,27 @@
#include "processes.h"
#include "util/mallocHelper.h"
#include <ntstatus.h>
#include <winternl.h>
const char* ffDetectProcesses(uint32_t* result)
{
ULONG size = 0;
if(NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
return "NtQuerySystemInformation(SystemProcessInformation, NULL) failed";
size += sizeof(SystemProcessInformation) * 5; //What if new processes are created during two syscalls?
SYSTEM_PROCESS_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PROCESS_INFORMATION*)malloc(size);
if(!pstart)
return "malloc(size) failed";
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessInformation, pstart, size, NULL)))
return "NtQuerySystemInformation(SystemProcessInformation, pstart) failed";
*result = 1; //Init with 1 because we test for ptr->NextEntryOffset
for (SYSTEM_PROCESS_INFORMATION* ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset))
++*result;
return NULL;
}
@@ -1,64 +0,0 @@
extern "C" {
#include "processes.h"
#include "util/mallocHelper.h"
}
#ifdef FF_USE_WIN_NTAPI
#include <ntstatus.h>
#include <winternl.h>
uint32_t ffDetectProcesses(FFstrbuf* error)
{
ULONG size = 0;
if(NtQuerySystemInformation(SystemProcessInformation, nullptr, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
{
ffStrbufAppendS(error, "NtQuerySystemInformation(SystemProcessInformation, NULL) failed");
return 0;
}
size += sizeof(SystemProcessInformation) * 5; //What if new processes are created during two syscalls?
SYSTEM_PROCESS_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PROCESS_INFORMATION*)malloc(size);
if(!pstart)
{
ffStrbufAppendF(error, "malloc(%u) failed", (unsigned)size);
return 0;
}
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessInformation, pstart, size, nullptr)))
{
ffStrbufAppendS(error, "NtQuerySystemInformation(SystemProcessInformation, pstart) failed");
return 0;
}
uint32_t result = 1; //Init with 1 because we test for ptr->NextEntryOffset
for (auto ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset))
++result;
return result;
}
#else
#include "util/windows/wmi.hpp"
uint32_t ffDetectProcesses(FFstrbuf* error)
{
FFWmiQuery query(L"SELECT NumberOfProcesses FROM Win32_OperatingSystem", error);
if(!query)
return 0;
if(FFWmiRecord record = query.next())
{
uint64_t result = 0;
record.getUnsigned(L"NumberOfProcesses", &result);
return (uint32_t)result;
}
else
{
ffStrbufAppendS(error, "No Wmi result returned");
return 0;
}
}
#endif
+2
View File
@@ -5,6 +5,8 @@
#include "fastfetch.h"
#define FF_SOUND_VOLUME_UNKNOWN 255
typedef struct FFSoundDevice
{
FFstrbuf identifier;
+29 -1
View File
@@ -44,7 +44,7 @@ const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* de
FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices);
device->main = deviceId == mainDeviceId;
device->active = false;
device->volume = 0;
device->volume = FF_SOUND_VOLUME_UNKNOWN;
ffStrbufInitF(&device->identifier, "%u", (unsigned) deviceId);
ffStrbufInit(&device->name);
@@ -67,6 +67,34 @@ const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* de
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize, &volume) == kAudioHardwareNoError)
device->volume = (uint8_t) (volume * 100 + 0.5);
else
{
// Try detecting volume from channels
uint32_t channels[2];
dataSize = sizeof(channels);
if (AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyPreferredChannelsForStereo,
kAudioObjectPropertyScopeOutput,
kAudioObjectPropertyElementMain
}, 0, NULL, &dataSize, channels) == kAudioHardwareNoError)
{
dataSize = sizeof(volume);
if (AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyVolumeScalar,
kAudioObjectPropertyScopeOutput,
channels[0]
}, 0, NULL, &dataSize, &volume) == kAudioHardwareNoError)
{
float temp;
if (AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
kAudioDevicePropertyVolumeScalar,
kAudioObjectPropertyScopeOutput,
channels[1]
}, 0, NULL, &dataSize, &temp) == kAudioHardwareNoError)
device->volume = (uint8_t) ((volume + temp) / 2 * 100 + 0.5);
}
}
}
}
CFStringRef name;
+1 -1
View File
@@ -77,7 +77,7 @@ static const char* detectSound(const FFinstance* instance, FFlist* devices)
return "Failed to connect to pulseaudio context";
}
int state;
pa_context_state_t state;
while((state = ffpa_context_get_state(context)) != PA_CONTEXT_READY)
{
if(!PA_CONTEXT_IS_GOOD(state))
+2 -4
View File
@@ -62,12 +62,10 @@ const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_U
FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices);
device->main = wcscmp(mainDeviceId, immDeviceId) == 0;
device->active = !!(immState & DEVICE_STATE_ACTIVE);
device->volume = 0;
ffStrbufInit(&device->identifier);
device->volume = FF_SOUND_VOLUME_UNKNOWN;
ffStrbufInitWS(&device->identifier, immDeviceId);
ffStrbufInit(&device->name);
ffStrbufSetWS(&device->identifier, immDeviceId);
{
PROPVARIANT __attribute__((__cleanup__(PropVariantClear))) friendlyName;
PropVariantInit(&friendlyName);
-15
View File
@@ -1,15 +0,0 @@
#pragma once
#ifndef FF_INCLUDED_detection_storage
#define FF_INCLUDED_detection_storage
#include "fastfetch.h"
typedef struct FFMemoryStorage
{
FFstrbuf error;
uint64_t bytesUsed;
uint64_t bytesTotal;
} FFMemoryStorage;
#endif
+8 -2
View File
@@ -3,8 +3,14 @@
#ifndef FF_INCLUDED_detection_swap_swap
#define FF_INCLUDED_detection_swap_swap
#include "detection/storage.h"
#include "fastfetch.h"
void ffDetectSwap(FFMemoryStorage* result);
typedef struct FFSwapResult
{
uint64_t bytesUsed;
uint64_t bytesTotal;
} FFSwapResult;
const char* ffDetectSwap(FFSwapResult* result);
#endif
+3 -5
View File
@@ -3,16 +3,14 @@
#include <mach/mach.h>
#include <sys/sysctl.h>
void ffDetectSwap(FFMemoryStorage* swap)
const char* ffDetectSwap(FFSwapResult* swap)
{
struct xsw_usage xsw;
size_t size = sizeof(xsw);
if(sysctl((int[]){ CTL_VM, VM_SWAPUSAGE }, 2, &xsw, &size, NULL, 0) != 0)
{
ffStrbufAppendS(&swap->error, "Failed to read vm.swapusage");
return;
}
return "Failed to read vm.swapusage";
swap->bytesTotal = xsw.xsu_total;
swap->bytesUsed = xsw.xsu_used;
return NULL;
}
+2 -1
View File
@@ -1,8 +1,9 @@
#include "swap.h"
#include "common/sysctl.h"
void ffDetectSwap(FFMemoryStorage* swap)
const char* ffDetectSwap(FFSwapResult* swap)
{
swap->bytesTotal = (uint64_t)ffSysctlGetInt64("vm.swap_total", 0);
swap->bytesUsed = (uint64_t)ffSysctlGetInt64("vm.swap_reserved", 0);
return NULL;
}
+4 -2
View File
@@ -2,12 +2,14 @@
#include <sys/sysinfo.h>
void ffDetectSwap(FFMemoryStorage* swap)
const char* ffDetectSwap(FFSwapResult* swap)
{
struct sysinfo info;
if(sysinfo(&info) != 0)
ffStrbufAppendS(&swap->error, "sysinfo() failed");
return "sysinfo() failed";
swap->bytesTotal = info.totalswap * (uint64_t) info.mem_unit;
swap->bytesUsed = (info.totalswap - info.freeswap) * (uint64_t) info.mem_unit;
return NULL;
}
+31
View File
@@ -0,0 +1,31 @@
#include "swap.h"
#include "util/mallocHelper.h"
#include <winternl.h>
#include <ntstatus.h>
#include <windows.h>
const char* ffDetectSwap(FFSwapResult* swap)
{
SYSTEM_INFO sysInfo;
GetNativeSystemInfo(&sysInfo);
ULONG size = sizeof(SYSTEM_PAGEFILE_INFORMATION);
SYSTEM_PAGEFILE_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PAGEFILE_INFORMATION*)malloc(size);
while(true)
{
NTSTATUS status = NtQuerySystemInformation(SystemPagefileInformation, pstart, size, &size);
if(status == STATUS_INFO_LENGTH_MISMATCH)
{
if(!(pstart = (SYSTEM_PAGEFILE_INFORMATION*)realloc(pstart, size)))
return "realloc(pstart, size) failed";
}
else if(!NT_SUCCESS(status))
return "NtQuerySystemInformation(SystemPagefileInformation, size) failed";
break;
}
swap->bytesUsed = (uint64_t)pstart->TotalUsed * sysInfo.dwPageSize;
swap->bytesTotal = (uint64_t)pstart->CurrentSize * sysInfo.dwPageSize;
return NULL;
}
-65
View File
@@ -1,65 +0,0 @@
extern "C" {
#include "swap.h"
#include "util/mallocHelper.h"
}
#ifdef FF_USE_WIN_NTAPI
#include <winternl.h>
#include <ntstatus.h>
#include <windows.h>
extern "C"
void ffDetectSwap(FFMemoryStorage* swap)
{
SYSTEM_INFO sysInfo;
GetNativeSystemInfo(&sysInfo);
ULONG size = sizeof(SYSTEM_PAGEFILE_INFORMATION);
SYSTEM_PAGEFILE_INFORMATION* FF_AUTO_FREE pstart = (SYSTEM_PAGEFILE_INFORMATION*)malloc(size);
while(true)
{
NTSTATUS status = NtQuerySystemInformation(SystemPagefileInformation, pstart, size, &size);
if(status == STATUS_INFO_LENGTH_MISMATCH)
{
if(!(pstart = (SYSTEM_PAGEFILE_INFORMATION*)realloc(pstart, size)))
{
ffStrbufAppendF(&swap->error, "realloc(pstart, %lu) failed", size);
return;
}
}
else if(!NT_SUCCESS(status))
{
ffStrbufAppendF(&swap->error, "NtQuerySystemInformation(SystemPagefileInformation, %lu) failed", size);
return;
}
break;
}
swap->bytesUsed = (uint64_t)pstart->TotalUsed * sysInfo.dwPageSize;
swap->bytesTotal = (uint64_t)pstart->CurrentSize * sysInfo.dwPageSize;
}
#else
#include "util/windows/wmi.hpp"
extern "C"
void ffDetectSwapImpl(FFMemoryStorage* swap)
{
FFWmiQuery query(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error);
if(!query)
return;
if(FFWmiRecord record = query.next())
{
//MB
record.getUnsigned(L"AllocatedBaseSize", &swap->bytesTotal);
record.getUnsigned(L"CurrentUsage", &swap->bytesUsed);
swap->bytesTotal *= 1024 * 1024;
swap->bytesUsed *= 1024 * 1024;
}
else
ffStrbufInitS(&swap->error, "No Wmi result returned");
}
#endif
+32 -5
View File
@@ -287,10 +287,10 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu
FF_MAYBE_UNUSED static bool detectKitty(const FFinstance* instance, FFTerminalFontResult* result)
{
FFstrbuf fontName;
FF_STRBUF_AUTO_DESTROY fontName;
ffStrbufInit(&fontName);
FFstrbuf fontSize;
FF_STRBUF_AUTO_DESTROY fontSize;
ffStrbufInit(&fontSize);
FFpropquery fontQuery[] = {
@@ -308,9 +308,6 @@ FF_MAYBE_UNUSED static bool detectKitty(const FFinstance* instance, FFTerminalFo
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
ffStrbufDestroy(&fontName);
ffStrbufDestroy(&fontSize);
return true;
}
@@ -373,6 +370,32 @@ static bool detectWezterm(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminal
return true;
}
static bool detectTabby(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminalFontResult* result)
{
FF_STRBUF_AUTO_DESTROY fontName;
ffStrbufInit(&fontName);
FF_STRBUF_AUTO_DESTROY fontSize;
ffStrbufInit(&fontSize);
FFpropquery fontQuery[] = {
{"font: ", &fontName},
{"fontSize: ", &fontSize},
};
if(!ffParsePropFileConfigValues(instance, "tabby/config.yaml", 2, fontQuery))
return false;
if(fontName.length == 0)
ffStrbufSetS(&fontName, "monospace");
if(fontSize.length == 0)
ffStrbufSetS(&fontSize, "14");
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
return true;
}
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont);
static bool detectTerminalFontCommon(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
@@ -383,8 +406,12 @@ static bool detectTerminalFontCommon(const FFinstance* instance, const FFTermina
detectTerminator(instance, terminalFont);
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "wezterm-gui"))
detectWezterm(instance, terminalFont);
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "tabby"))
detectTabby(instance, terminalFont);
#ifndef _WIN32
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/pts/"))
ffStrbufAppendS(&terminalFont->error, "Terminal font detection is not supported on PTS");
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "kitty"))
detectKitty(instance, terminalFont);
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty"))
@@ -86,7 +86,8 @@ static void detectWarpTerminal(const FFinstance* instance, FFTerminalFontResult*
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
{
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "iterm.app") == 0)
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "iterm.app") == 0 ||
ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "iTermServer-"))
detectIterm2(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Apple_Terminal") == 0)
detectAppleTerminal(terminalFont);
+34 -13
View File
@@ -10,13 +10,13 @@ static const char* getSystemMonospaceFont(const FFinstance* instance)
{
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0)
if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, "Cinnamon"))
{
const char* systemMonospaceFont = ffSettingsGet(instance, "/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
if(ffStrSet(systemMonospaceFont))
return systemMonospaceFont;
}
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0)
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, "Mate"))
{
const char* systemMonospaceFont = ffSettingsGet(instance, "/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
if(ffStrSet(systemMonospaceFont))
@@ -26,9 +26,9 @@ static const char* getSystemMonospaceFont(const FFinstance* instance)
return ffSettingsGet(instance, "/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
}
static void detectFromGSettings(const FFinstance* instance, char* profilePath, char* profileList, char* profile, FFTerminalFontResult* terminalFont)
static void detectFromGSettings(const FFinstance* instance, const char* profilePath, const char* profileList, const char* profile, const char* defaultProfileKey, FFTerminalFontResult* terminalFont)
{
const char* defaultProfile = ffSettingsGetGSettings(instance, profileList, NULL, "default", FF_VARIANT_TYPE_STRING).strValue;
const char* defaultProfile = ffSettingsGetGSettings(instance, profileList, NULL, defaultProfileKey, FF_VARIANT_TYPE_STRING).strValue;
if(!ffStrSet(defaultProfile))
{
ffStrbufAppendF(&terminalFont->error, "Could not get default profile from gsettings: %s", profileList);
@@ -221,20 +221,41 @@ static void detectFootTerminal(const FFinstance* instance, FFTerminalFontResult*
ffFontInitValues(&terminalFont->font, font.chars, &font.chars[equal + strlen("size=")]);
}
static void detectQTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont)
{
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate();
ffParsePropFileConfigValues(instance, "qterminal.org/qterminal.ini", 2, (FFpropquery[]) {
{"fontFamily=", &fontName},
{"fontSize=", &fontSize},
});
if (fontName.length == 0)
ffStrbufAppendS(&fontName, "monospace");
if (fontSize.length == 0)
ffStrbufAppendS(&fontSize, "12");
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
}
void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
{
if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "konsole") == 0)
if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "konsole"))
detectKonsole(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "xfce4-terminal") == 0)
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xfce4-terminal"))
detectXFCETerminal(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "lxterminal") == 0)
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "lxterminal"))
detectFromConfigFile(instance, "lxterminal/lxterminal.conf", "fontname =", terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "tilix") == 0)
detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "gnome-terminal-") == 0)
detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "deepin-terminal") == 0)
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "tilix"))
detectFromGSettings(instance, "/com/gexperts/Tilix/profiles/", "com.gexperts.Tilix.ProfilesList", "com.gexperts.Tilix.Profile", "default", terminalFont);
else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "gnome-terminal-"))
detectFromGSettings(instance, "/org/gnome/terminal/legacy/profiles:/:", "org.gnome.Terminal.ProfilesList", "org.gnome.Terminal.Legacy.Profile", "default", terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "mate-terminal"))
detectFromGSettings(instance, "/org/mate/terminal/profiles/", "org.mate.terminal.global", "org.mate.terminal.profile", "default-profile", terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "deepin-terminal"))
detectDeepinTerminal(instance, terminalFont);
else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "foot") == 0)
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "foot"))
detectFootTerminal(instance, terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "qterminal"))
detectQTerminal(instance, terminalFont);
}
+43 -19
View File
@@ -5,6 +5,8 @@
#ifdef _WIN32
#include "util/mallocHelper.h"
#include <winver.h>
static bool getFileVersion(const char* exePath, FFstrbuf* version)
@@ -13,7 +15,7 @@ static bool getFileVersion(const char* exePath, FFstrbuf* version)
DWORD size = GetFileVersionInfoSizeA(exePath, &handle);
if(size > 0)
{
void* versionData = malloc(size);
FF_AUTO_FREE void* versionData = malloc(size);
if(GetFileVersionInfoA(exePath, handle, size, versionData))
{
VS_FIXEDFILEINFO* verInfo;
@@ -26,11 +28,9 @@ static bool getFileVersion(const char* exePath, FFstrbuf* version)
(unsigned)(( verInfo->dwFileVersionLS >> 16 ) & 0xffff),
(unsigned)(( verInfo->dwFileVersionLS >> 0 ) & 0xffff)
);
free(versionData);
return true;
}
}
free(versionData);
}
return false;
@@ -40,11 +40,17 @@ static bool getFileVersion(const char* exePath, FFstrbuf* version)
static bool getExeVersionRaw(FFstrbuf* exe, FFstrbuf* version)
{
return ffProcessAppendStdOut(version, (char* const[]) {
bool ok = ffProcessAppendStdOut(version, (char* const[]) {
exe->chars,
"--version",
NULL
}) == NULL;
if (ok)
{
ffStrbufTrim(version, '\n');
ffStrbufTrim(version, ' ');
}
return ok;
}
static bool getExeVersionGeneral(FFstrbuf* exe, FFstrbuf* version)
@@ -115,11 +121,6 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
ffStrbufSubstrAfterLastC(version, ' ');
return true;
}
static bool getShellVersionCmd(FFstrbuf* exe, FFstrbuf* version)
{
return getFileVersion(exe->chars, version);
}
#endif
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
@@ -136,15 +137,20 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
return getExeVersionGeneral(exe, version); //tcsh 6.24.07 (Astron) 2022-12-21 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec
if(strcasecmp(exeName, "nu") == 0)
return getExeVersionRaw(exe, version); //0.73.0
if(strcasecmp(exeName, "python") == 0 && getenv("XONSH_VERSION"))
{
ffStrbufSetS(version, getenv("XONSH_VERSION"));
return true;
}
#ifdef _WIN32
if(strcasecmp(exeName, "powershell") == 0 || strcasecmp(exeName, "powershell_ise") == 0)
return getShellVersionWinPowerShell(exe, version);
if(strcasecmp(exeName, "cmd") == 0)
return getShellVersionCmd(exe, version);
#endif
return getFileVersion(exe->chars, version);
#else
return false;
#endif
}
FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version)
@@ -190,11 +196,7 @@ FF_MAYBE_UNUSED static bool getTerminalVersionKonsole(FFstrbuf* exe, FFstrbuf* v
FF_MAYBE_UNUSED static bool getTerminalVersionFoot(FFstrbuf* exe, FFstrbuf* version)
{
if(ffProcessAppendStdOut(version, (char* const[]){
exe->chars,
"--version",
NULL
})) return false;
if(!getExeVersionRaw(exe, version)) return false;
//foot version: 1.13.1 -pgo +ime -graphemes -assertions
ffStrbufSubstrAfterFirstS(version, "version: ");
@@ -202,6 +204,15 @@ FF_MAYBE_UNUSED static bool getTerminalVersionFoot(FFstrbuf* exe, FFstrbuf* vers
return true;
}
FF_MAYBE_UNUSED static bool getTerminalVersionMateTerminal(FFstrbuf* exe, FFstrbuf* version)
{
if(!getExeVersionRaw(exe, version)) return false;
//MATE Terminal 1.26.1
ffStrbufSubstrAfterLastC(version, ' ');
return version->length > 0;
}
#ifdef _WIN32
static bool getTerminalVersionWindowsTerminal(FFstrbuf* exe, FFstrbuf* version)
@@ -242,7 +253,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
#if defined(__linux__) || defined(__FreeBSD__)
if(ffStrbufIgnCaseEqualS(processName, "gnome-terminal-"))
if(ffStrbufStartsWithIgnCaseS(processName, "gnome-terminal-"))
return getTerminalVersionGnome(version);
if(ffStrbufIgnCaseEqualS(processName, "konsole"))
@@ -251,12 +262,21 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal"))
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
if(ffStrbufIgnCaseEqualS(processName, "terminator"))
return getExeVersionGeneral(exe, version);//terminator 2.1.3
if(ffStrbufIgnCaseEqualS(processName, "deepin-terminal"))
return getExeVersionGeneral(exe, version);//deepin-terminal 5.4.36
if(ffStrbufIgnCaseEqualS(processName, "foot"))
return getTerminalVersionFoot(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "qterminal"))
return getExeVersionRaw(exe, version); //1.2.0
if(ffStrbufIgnCaseEqualS(processName, "mate-terminal"))
return getTerminalVersionMateTerminal(exe, version);
#endif
#ifdef _WIN32
@@ -274,6 +294,9 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
if(ffStrbufIgnCaseEqualS(processName, "kitty"))
return getExeVersionGeneral(exe, version); //kitty 0.21.2 created by Kovid Goyal
if (ffStrbufIgnCaseEqualS(processName, "Tabby") && getExeVersionRaw(exe, version))
return true;
#endif
if(ffStrbufStartsWithIgnCaseS(processName, "alacritty"))
@@ -286,7 +309,8 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
if(termProgram)
{
if(ffStrbufStartsWithIgnCaseS(processName, termProgram) || // processName ends with `.exe` on Windows
(strcmp(termProgram, "vscode") == 0 && ffStrbufStartsWithIgnCaseS(processName, "code"))
(strcmp(termProgram, "vscode") == 0 && ffStrbufStartsWithIgnCaseS(processName, "code")) ||
(strcmp(termProgram, "iTerm.app") == 0 && ffStrbufStartsWithIgnCaseS(processName, "iTermServer-"))
) {
ffStrbufSetS(version, termProgramVersion);
return true;
@@ -148,7 +148,7 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
}
//Known shells
if(
if (
strcasecmp(name, "bash") == 0 ||
strcasecmp(name, "zsh") == 0 ||
strcasecmp(name, "ksh") == 0 ||
@@ -158,7 +158,8 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
strcasecmp(name, "dash") == 0 ||
strcasecmp(name, "pwsh") == 0 ||
strcasecmp(name, "nu") == 0 ||
strcasecmp(name, "git-shell") == 0
strcasecmp(name, "git-shell") == 0 ||
(strcasecmp(name, "python") == 0 && getenv("XONSH_VERSION"))
) {
if (result->shellProcessName.length == 0)
{
@@ -369,20 +370,33 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
ffStrbufInitS(&result.shellPrettyName, "PowerShell");
else if(ffStrbufEqualS(&result.shellProcessName, "nu"))
ffStrbufInitS(&result.shellPrettyName, "nushell");
else if(ffStrbufIgnCaseEqualS(&result.shellProcessName, "python") && getenv("XONSH_VERSION"))
ffStrbufInitS(&result.shellPrettyName, "xonsh");
else
{
// https://github.com/LinusDierheimer/fastfetch/discussions/280#discussioncomment-3831734
// https://github.com/fastfetch-cli/fastfetch/discussions/280#discussioncomment-3831734
ffStrbufInitS(&result.shellPrettyName, result.shellExeName);
}
if(ffStrbufEqualS(&result.terminalProcessName, "iTerm.app"))
if(ffStrbufEqualS(&result.terminalProcessName, "wezterm-gui"))
ffStrbufInitS(&result.terminalPrettyName, "WezTerm");
#if defined(__linux__) || defined(__FreeBSD__)
else if(ffStrbufStartsWithS(&result.terminalProcessName, "gnome-terminal-"))
ffStrbufInitS(&result.terminalPrettyName, "gnome-terminal");
#elif defined(__APPLE__)
else if(ffStrbufEqualS(&result.terminalProcessName, "iTerm.app") || ffStrbufStartsWithS(&result.terminalProcessName, "iTermServer-"))
ffStrbufInitS(&result.terminalPrettyName, "iTerm");
else if(ffStrbufEqualS(&result.terminalProcessName, "Apple_Terminal"))
ffStrbufInitS(&result.terminalPrettyName, "Apple Terminal");
else if(ffStrbufEqualS(&result.terminalProcessName, "WarpTerminal"))
ffStrbufInitS(&result.terminalPrettyName, "Warp");
else if(ffStrbufEqualS(&result.terminalProcessName, "wezterm-gui"))
ffStrbufInitS(&result.terminalPrettyName, "WezTerm");
#endif
else if(strncmp(result.terminalExeName, result.terminalProcessName.chars, result.terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName
ffStrbufInitS(&result.terminalPrettyName, result.terminalExeName);
else
@@ -1,19 +1,41 @@
extern "C" {
#include "terminalshell.h"
#include "common/processing.h"
#include "common/thread.h"
#include "util/mallocHelper.h"
}
#include <windows.h>
#include <wchar.h>
#include <tlhelp32.h>
#ifdef FF_USE_WIN_NTAPI
#include <ntstatus.h>
#include <winternl.h>
static bool getProductVersion(const wchar_t* filePath, FFstrbuf* version)
{
DWORD handle;
DWORD size = GetFileVersionInfoSizeW(filePath, &handle);
if(size > 0)
{
FF_AUTO_FREE void* versionData = malloc(size);
if(GetFileVersionInfoW(filePath, handle, size, versionData))
{
VS_FIXEDFILEINFO* verInfo;
UINT len;
if(VerQueryValueW(versionData, L"\\", (void**)&verInfo, &len) && len && verInfo->dwSignature == 0xFEEF04BD)
{
ffStrbufAppendF(version, "%u.%u.%u.%u",
(unsigned)(( verInfo->dwProductVersionMS >> 16 ) & 0xffff),
(unsigned)(( verInfo->dwProductVersionMS >> 0 ) & 0xffff),
(unsigned)(( verInfo->dwProductVersionLS >> 16 ) & 0xffff),
(unsigned)(( verInfo->dwProductVersionLS >> 0 ) & 0xffff)
);
return true;
}
}
}
return false;
}
static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName)
{
HANDLE hProcess = pid == 0
@@ -59,7 +81,7 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb
static bool getTerminalInfoByEnumeratingChildProcesses(FFTerminalShellResult* result, uint32_t ppid)
{
ULONG size = 0;
if(NtQuerySystemInformation(SystemProcessInformation, nullptr, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
if(NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
return false;
size += sizeof(SystemProcessInformation) * 5; //What if new processes are created during two syscalls?
@@ -68,12 +90,12 @@ static bool getTerminalInfoByEnumeratingChildProcesses(FFTerminalShellResult* re
if(!pstart)
return false;
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessInformation, pstart, size, nullptr)))
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessInformation, pstart, size, NULL)))
return false;
uint32_t currentProcessId = (uint32_t) GetCurrentProcessId();
for (auto ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset))
for (SYSTEM_PROCESS_INFORMATION* ptr = pstart; ptr->NextEntryOffset; ptr = (SYSTEM_PROCESS_INFORMATION*)((uint8_t*)ptr + ptr->NextEntryOffset))
{
if ((uint32_t)(uintptr_t) ptr->InheritedFromUniqueProcessId != ppid)
continue;
@@ -82,7 +104,7 @@ static bool getTerminalInfoByEnumeratingChildProcesses(FFTerminalShellResult* re
if (pid == currentProcessId)
continue;
if(!getProcessInfo(pid, nullptr, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName))
if(!getProcessInfo(pid, NULL, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName))
return false;
result->terminalPid = pid;
@@ -95,77 +117,7 @@ static bool getTerminalInfoByEnumeratingChildProcesses(FFTerminalShellResult* re
return false;
}
#else
#include "util/windows/wmi.hpp"
#include <inttypes.h>
static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrbuf* exe, const char** exeName)
{
if(pid == 0)
pid = GetCurrentProcessId();
wchar_t sql[256] = {};
swprintf(sql, 256, L"SELECT %ls %ls ParentProcessId FROM Win32_Process WHERE ProcessId = %" PRIu32,
pname ? L"Name," : L"",
pname ? L"ExecutablePath," : L"",
pid);
FFWmiQuery query(sql);
if(!query)
return false;
if(FFWmiRecord record = query.next())
{
if(ppid)
{
uint64_t value;
record.getUnsigned(L"ParentProcessId", &value);
*ppid = (uint32_t) value;
}
if(pname)
record.getString(L"Name", pname);
if(exe)
record.getString(L"ExecutablePath", exe);
if(exeName)
*exeName = exe->chars + ffStrbufLastIndexC(exe, '\\') + 1;
}
return true;
}
static bool getTerminalInfoByEnumeratingChildProcesses(FFTerminalShellResult* result, uint32_t ppid)
{
wchar_t sql[256] = {};
swprintf(sql, 256, L"SELECT Name, ExecutablePath, ProcessId FROM Win32_Process WHERE ProcessId <> %" PRIu32 " AND ParentProcessId = %" PRIu32,
(uint32_t) GetCurrentProcessId(),
ppid);
FFWmiQuery query(sql);
if(!query)
return false;
if(FFWmiRecord record = query.next())
{
record.getString(L"Name", &result->terminalProcessName);
record.getString(L"ExecutablePath", &result->terminalExe);
result->terminalExeName = result->terminalExe.chars + ffStrbufLastIndexC(&result->terminalExe, '\\') + 1;
uint64_t pid;
record.getUnsigned(L"ProcessId", &pid);
result->terminalPid = (uint32_t) pid;
ffStrbufSet(&result->terminalPrettyName, &result->terminalProcessName);
if(ffStrbufEndsWithIgnCaseS(&result->terminalPrettyName, ".exe"))
ffStrbufSubstrBefore(&result->terminalPrettyName, result->terminalPrettyName.length - 4);
return true;
}
return false;
}
#endif
extern "C" bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult* result, uint32_t pid)
{
@@ -190,12 +142,13 @@ static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult*
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "guake-wrapped") ||
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "fastfetch") || //scoop warps the real binaries with a "shim" exe
ffStrbufIgnCaseEqualS(&result->shellPrettyName, "flashfetch") ||
ffStrbufContainIgnCaseS(&result->shellPrettyName, "debug")
ffStrbufContainIgnCaseS(&result->shellPrettyName, "debug") ||
ffStrbufStartsWithIgnCaseS(&result->shellPrettyName, "ConEmuC") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
) {
ffStrbufClear(&result->shellProcessName);
ffStrbufClear(&result->shellPrettyName);
ffStrbufClear(&result->shellExe);
result->shellExeName = nullptr;
result->shellExeName = NULL;
return getShellInfo(instance, result, ppid);
}
@@ -225,7 +178,9 @@ static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult*
{
if(wcsncmp(module.szModule, L"clink_dll_", strlen("clink_dll_")) == 0)
{
ffStrbufAppendS(&result->shellPrettyName, "CMD (with Clink)");
ffStrbufAppendS(&result->shellPrettyName, "CMD (with Clink ");
getProductVersion(module.szExePath, &result->shellPrettyName);
ffStrbufAppendC(&result->shellPrettyName, ')');
break;
}
}
@@ -316,23 +271,23 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
ffStrbufIgnCaseCompS(&result->terminalProcessName, "explorer") != 0
) return;
const char* term = nullptr;
const char* term = NULL;
//SSH
if(getenv("SSH_CONNECTION") != nullptr)
if(getenv("SSH_CONNECTION") != NULL)
term = getenv("SSH_TTY");
//Windows Terminal
if(!term && (
getenv("WT_SESSION") != nullptr ||
getenv("WT_PROFILE_ID") != nullptr
getenv("WT_SESSION") != NULL ||
getenv("WT_PROFILE_ID") != NULL
)) term = "Windows Terminal";
//Alacritty
if(!term && (
getenv("ALACRITTY_SOCKET") != nullptr ||
getenv("ALACRITTY_LOG") != nullptr ||
getenv("ALACRITTY_WINDOW_ID") != nullptr
getenv("ALACRITTY_SOCKET") != NULL ||
getenv("ALACRITTY_LOG") != NULL ||
getenv("ALACRITTY_WINDOW_ID") != NULL
)) term = "Alacritty";
if(!term)
@@ -351,7 +306,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
}
}
extern "C" bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
{
@@ -386,7 +341,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
ffStrbufInit(&result.userShellVersion);
uint32_t ppid;
if(!getProcessInfo(0, &ppid, nullptr, nullptr, nullptr))
if(!getProcessInfo(0, &ppid, NULL, NULL, NULL))
goto exit;
ppid = getShellInfo(instance, &result, ppid);
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#ifndef FF_INCLUDED_detection_theme
#define FF_INCLUDED_detection_theme
#include "fastfetch.h"
const char* ffDetectTheme(const FFinstance* instance, FFstrbuf* result);
#endif
+69
View File
@@ -0,0 +1,69 @@
#include "theme.h"
#include "common/parsing.h"
#include "detection/gtk_qt/gtk_qt.h"
#include "detection/displayserver/displayserver.h"
const char* ffDetectTheme(const FFinstance* instance, FFstrbuf* result)
{
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0)
return "Theme isn't supported in TTY";
const FFQtResult* plasma = ffDetectQt(instance);
const FFstrbuf* gtk2 = &ffDetectGTK2(instance)->theme;
const FFstrbuf* gtk3 = &ffDetectGTK3(instance)->theme;
const FFstrbuf* gtk4 = &ffDetectGTK4(instance)->theme;
if(plasma->widgetStyle.length == 0 && plasma->colorScheme.length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0)
return "No themes found";
FF_STRBUF_AUTO_DESTROY plasmaColorPretty;
ffStrbufInit(&plasmaColorPretty);
if(ffStrbufStartsWithIgnCase(&plasma->colorScheme, &plasma->widgetStyle))
ffStrbufAppendNS(&plasmaColorPretty, plasma->colorScheme.length - plasma->widgetStyle.length, &plasma->colorScheme.chars[plasma->widgetStyle.length]);
else
ffStrbufAppend(&plasmaColorPretty, &plasma->colorScheme);
ffStrbufTrim(&plasmaColorPretty, ' ');
FF_STRBUF_AUTO_DESTROY gtkPretty;
ffStrbufInit(&gtkPretty);
ffParseGTK(&gtkPretty, gtk2, gtk3, gtk4);
if(plasma->widgetStyle.length > 0)
{
ffStrbufAppend(result, &plasma->widgetStyle);
if(plasma->colorScheme.length > 0)
{
ffStrbufAppendS(result, " (");
if(plasmaColorPretty.length > 0)
ffStrbufAppend(result, &plasmaColorPretty);
else
ffStrbufAppend(result, &plasma->colorScheme);
ffStrbufAppendC(result, ')');
}
}
else if(plasma->colorScheme.length > 0)
{
if(plasmaColorPretty.length > 0)
ffStrbufAppend(result, &plasmaColorPretty);
else
ffStrbufAppend(result, &plasma->colorScheme);
}
if(plasma->widgetStyle.length > 0 || plasma->colorScheme.length > 0)
{
ffStrbufAppendS(result, " [QT]");
if(gtkPretty.length > 0)
ffStrbufAppendS(result, ", ");
}
ffStrbufAppend(result, &gtkPretty);
return NULL;
}
+6
View File
@@ -0,0 +1,6 @@
#include "theme.h"
const char* ffDetectTheme(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFstrbuf* result)
{
return "Not supported on this platform";
}
+2 -2
View File
@@ -22,9 +22,9 @@ next:
if(n->ut_type != USER_PROCESS)
continue;
for(uint32_t i = 0; i < users->length; ++i)
FF_LIST_FOR_EACH(FFstrbuf, user, *users)
{
if(ffStrbufCompS((FFstrbuf*)ffListGet(users, i), n->ut_user) == 0)
if(ffStrbufCompS(user, n->ut_user) == 0)
goto next;
}
+12
View File
@@ -176,8 +176,17 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu
if(physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)
continue;
// #456
FF_LIST_FOR_EACH(FFGPUResult, gpu, result->gpus)
{
if (gpu->vulkanDeviceId == physicalDeviceProperties.properties.deviceID)
goto next;
}
FFGPUResult* gpu = ffListAdd(&result->gpus);
gpu->vulkanDeviceId = physicalDeviceProperties.properties.deviceID;
ffStrbufInit(&gpu->name);
ffStrbufAppendS(&gpu->name, physicalDeviceProperties.properties.deviceName);
@@ -215,6 +224,9 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu
//No way to detect those using vulkan
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
next:
continue;
}
//If the highest device version is lower than the instance version, use it as our vulkan version
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#ifndef FF_INCLUDED_detection_wallpaper
#define FF_INCLUDED_detection_wallpaper
#include "fastfetch.h"
const char* ffDetectWallpaper(const FFinstance* instance, FFstrbuf* result);
#endif
+31
View File
@@ -0,0 +1,31 @@
#include "wallpaper.h"
#include "common/settings.h"
#include "util/apple/osascript.h"
const char* ffDetectWallpaper(FF_MAYBE_UNUSED const FFinstance* instance, FFstrbuf* result)
{
// https://stackoverflow.com/questions/301215/getting-desktop-background-on-mac
#ifdef FF_HAVE_SQLITE3
FF_STRBUF_AUTO_DESTROY path;
ffStrbufInitCopy(&path, &instance->state.platform.homeDir);
ffStrbufAppendS(&path, "Library/Application Support/Dock/desktoppicture.db");
if (ffSettingsGetSQLite3String(instance, path.chars,
"SELECT value\n"
"FROM preferences\n"
"JOIN data ON preferences.data_id=data.ROWID\n"
"JOIN pictures ON preferences.picture_id=pictures.ROWID\n"
"JOIN displays ON pictures.display_id=displays.ROWID\n"
"JOIN spaces ON pictures.space_id=spaces.ROWID\n"
"WHERE display_id=1 AND space_id=1 AND key=1", result)
)
return NULL;
#endif
if (!ffOsascript("tell application \"Finder\" to get POSIX path of (get desktop picture as alias)", result))
return "ffOsascript() failed";
return NULL;
}
+26
View File
@@ -0,0 +1,26 @@
#include "wallpaper.h"
#include "common/settings.h"
#include "detection/gtk_qt/gtk_qt.h"
const char* ffDetectWallpaper(const FFinstance* instance, FFstrbuf* result)
{
const FFstrbuf* wallpaper = NULL;
const FFGTKResult* gtk = ffDetectGTK4(instance);
if (gtk->wallpaper.length)
wallpaper = &gtk->wallpaper;
else
{
const FFQtResult* qt = ffDetectQt(instance);
if (qt->wallpaper.length)
wallpaper = &qt->wallpaper;
}
if (!wallpaper)
return "Failed to detect the current wallpaper path";
if (ffStrbufStartsWithS(wallpaper, "file:///"))
ffStrbufAppendS(result, wallpaper->chars + strlen("file://"));
else
ffStrbufAppend(result, wallpaper);
return NULL;
}
@@ -0,0 +1,6 @@
#include "wallpaper.h"
const char* ffDetectWallpaper(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_UNUSED FFstrbuf* result)
{
return "Not supported on this platform";
}
@@ -0,0 +1,14 @@
#include "wallpaper.h"
#include "util/windows/registry.h"
const char* ffDetectWallpaper(FF_MAYBE_UNUSED const FFinstance* instance, FFstrbuf* result)
{
FF_HKEY_AUTO_DESTROY hKey = NULL;
if(!ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Desktop", &hKey, NULL))
return "ffRegOpenKeyForRead(Control Panel\\Desktop) failed";
if(!ffRegReadStrbuf(hKey, L"WallPaper", result, NULL))
return "ffRegReadStrbuf(WallPaper) failed";
return NULL;
}

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