Compare commits

...

253 Commits

Author SHA1 Message Date
Carter Li 636471c366 Merge pull request #2375 from fastfetch-cli/dev
Release v2.64.2
2026-06-05 18:36:58 +08:00
李通洲 cbc84fda6c Common (Lua): addresses AI's feedback 2026-06-05 18:21:28 +08:00
李通洲 fc7a0a8484 Codec (Linux): supports BINARY_LINK_TYPE=dynamic 2026-06-05 18:05:54 +08:00
李通洲 4d3b6c3b1b Common (QJS): supports BINARY_LINK_TYPE=dynamic 2026-06-05 17:49:49 +08:00
李通洲 70e67177fe Common (Lua): supports BINARY_LINK_TYPE=dynamic 2026-06-05 17:22:16 +08:00
李通洲 9fe7d6dbfa Logo: addresses review comments of AI 2026-06-05 16:34:02 +08:00
Carter Li a139a8c4a5 Doc: updates changelog [ci skip] 2026-06-05 16:22:04 +08:00
Valeriy Kosikhin da568c986e Logo (Builtin): update OpenWrt logo
Update the large logo for OpenWrt based on the official branding.
Add a small logo version.
Keep the old logo as openwrt_old.txt

Signed-off-by: Valeriy Kosikhin <vkosikhin@gmail.com>
2026-06-05 16:15:46 +08:00
Carter Li 727fbc0276 Doc: updates changelog 2026-06-05 15:29:00 +08:00
Carter Li 20aabdfd78 Global: resets keysHeight after every refresh 2026-06-05 15:27:25 +08:00
Carter Li e79aaf5ce1 Global: don't clear line in --logo-position right 2026-06-05 15:27:15 +08:00
Carter Li 53c2d07161 Release: v2.64.2 2026-06-05 14:51:50 +08:00
Carter Li 6b9f594620 Global: prevents ascii logo from being overwritten in --dynamic-interval mode 2026-06-05 14:47:01 +08:00
Carter Li ba3968784f Logo (Image): fixes image renders but quickly gets wiped
Regression from v2.64.0

Fixes: #2374
2026-06-05 13:12:07 +08:00
Carter Li 021ece1681 Merge pull request #2370 from fastfetch-cli/dev
Release: v2.64.1
2026-06-04 23:45:19 +08:00
李通洲 9787b56460 Release: v2.64.1 2026-06-04 20:15:54 +08:00
李通洲 54792e61ff Common (Lua): detects circular reference in encode_json 2026-06-04 20:15:54 +08:00
Carter Li b34e2a4055 Common (Base64): adds static to internal functions 2026-06-04 17:22:24 +08:00
Carter Li 3b56200ee4 Packages: adds option PACKAGES_REMOVE_DISABLED to remove disabled package managers from the build entirely 2026-06-04 17:22:24 +08:00
Carter Li de95a62e2f Codec (macOS): removes usage of JPEG XL; replaces enums with raw constants 2026-06-04 10:48:01 +08:00
Carter Li 72cb64a500 Common (Lua): optimises code; fixes incompatibility against lua 5.3 2026-06-04 10:48:01 +08:00
Carter Li d48bd733f0 Merge pull request #2368 from fastfetch-cli/dev
Release v2.64.0
2026-06-03 19:18:31 +08:00
李通洲 0585ea7797 Doc: update changelog 2026-06-03 18:34:09 +08:00
李通洲 794035f8d9 Shell: sets pretty name of busybox to ash 2026-06-03 18:29:33 +08:00
李通洲 723552f68b Shell: be more robust on busybox version detection 2026-06-03 18:29:10 +08:00
Carter Li 8dd38f5744 Release: v2.64.0 2026-06-03 16:04:00 +08:00
Carter Li 616a5c7aea Codec (Vulkan): be compatible with old Vulkan headers
Fixes #2367
2026-06-03 15:23:42 +08:00
Carter Li 5e1e94473e Bootmgr (macOS): don't hard-code the firmware name 2026-06-03 15:23:42 +08:00
CicaDATA 4eae8ac244 Logo (Builtin): updates NurOS logo and colors (#2366) 2026-06-03 02:21:23 -05:00
李通洲 8aeb7c2f10 Shell (Linux): improves performance of busybox (ash) version detection 2026-06-02 17:44:55 +08:00
Carter Li c20b532c7a Common (Format): adds | for center aligning 2026-06-02 16:03:04 +08:00
Carter Li 3c59161aca Common (Format): handles ANSI escapes when padding/truncating variable strings
Fixes #2364
2026-06-02 15:55:10 +08:00
Carter Li bd454632c3 FFstrbuf: inlines more functions 2026-06-02 15:42:40 +08:00
Carter Li e73adc27a0 Common: fixes wcwidth handling 2026-06-02 15:05:13 +08:00
Carter Li 15c6014c04 Common: don't inline ffUtf8CharLenWidth 2026-06-02 14:01:59 +08:00
Carter Li 54f18982ac Common: renames arrayUtil to arrutil 2026-06-02 10:59:18 +08:00
Carter Li 99c2f2a2c8 JsonSchema: adds codec 2026-06-02 10:58:57 +08:00
Carter Li 45f35b1c4d Library (Linux): adds simple debug log 2026-06-02 09:27:38 +08:00
Carter Li 428c05b9de Codec (Linux): optimises code 2026-06-02 09:10:55 +08:00
李通洲 23ca6d94ab CI: run codec module 2026-06-02 00:15:42 +08:00
李通洲 9e4e0cb838 Codec (Linux): removes VAEntrypointEncPicture 2026-06-01 23:45:17 +08:00
李通洲 95a370e5a2 Codec (macOS): fixes building 2026-06-01 20:48:59 +08:00
李通洲 e013005f34 Code (Vulkan): fixes compiling 2026-06-01 20:16:30 +08:00
李通洲 92b86f7cbb Codec: shows types only specifed by showType 2026-06-01 19:27:37 +08:00
李通洲 2e4b7baf44 Codec (Android): adds showType support 2026-06-01 19:27:37 +08:00
李通洲 a47ff0b2dc Codec (macOS): adds showType support 2026-06-01 19:27:37 +08:00
李通洲 1f13f6c8f5 Codec (Windows): adds showType support 2026-06-01 19:27:37 +08:00
李通洲 b0bb6fb58e Codec: don't show Unknown 2026-06-01 19:27:37 +08:00
Carter Li 37029dbbe3 Codec (Vulkan): adds showType support 2026-06-01 19:27:37 +08:00
Carter Li 35428606e7 Codec (Linux): adds FFCodecShowOptions; code cleanup 2026-06-01 19:27:37 +08:00
Carter Li 2c65eee00f Common (Lua): adds json_encode 2026-06-01 19:27:37 +08:00
Carter Li a1bf014352 Codec: normalizes platformApi string 2026-06-01 10:34:17 +08:00
Carter Li 412fc94dab WM (Linux): fixes possible segfault when detecting sway version
Fixes #2360
2026-06-01 10:16:26 +08:00
Carter Li b65de28805 Logo (Builtin): adds Quasar
Fixes #2338 #2323
2026-06-01 09:34:32 +08:00
李通洲 bc86c66cdd Codec (Windows): detects encoders detection support via MFT on Win10 or older 2026-06-01 09:16:22 +08:00
李通洲 9afa01812d Codec (Vulkan): disables impl if the vulkan headers are too old to use 2026-06-01 00:15:27 +08:00
李通洲 30a8a94cd2 Chore (Haiku): silences compiler warnings 2026-05-31 23:56:45 +08:00
李通洲 3a54617196 Codec: adds vulkan support 2026-05-31 23:45:20 +08:00
李通洲 3e3a03a233 Codec (Android): adds support 2026-05-31 23:37:50 +08:00
李通洲 b407669b69 JsonSchema: update 2026-05-31 23:37:49 +08:00
李通洲 e14ea926a5 Codec (macOS): adds platformApi 2026-05-31 23:37:49 +08:00
李通洲 9d8f794cb9 Codec (Windows): detects encoder support via d3d12va 2026-05-31 23:37:49 +08:00
Carter Li 825b8b8715 Codec (Linux): adds vdpau fallback impl 2026-05-31 23:37:49 +08:00
Carter Li 0c94fd87db Codec: updates default format 2026-05-31 23:37:49 +08:00
Carter Li 473a08d85c Decoder: renames to Codec and adds encoders detection support 2026-05-31 23:37:49 +08:00
Carter Li ae5132c388 Decoder (macOS): adds support 2026-05-31 23:37:49 +08:00
李通洲 1addcec7a2 Decoder (Linux): adds *nix support 2026-05-31 23:37:49 +08:00
李通洲 e75c37c101 Decoder (Windows): adds support 2026-05-31 23:37:49 +08:00
李通洲 b9ab823f77 Decoder: inits module 2026-05-31 23:37:48 +08:00
François Revol a63d854681 OS (Haiku): Fix warnings 2026-05-31 23:37:35 +08:00
François Revol 576548b15e WMTheme (Haiku): implement 2026-05-31 23:37:35 +08:00
François Revol 3043971259 Brightness (Haiku): Implement 2026-05-31 23:37:35 +08:00
François Revol ccf4f22f8b Bootmgr (Haiku): Preliminary implementation 2026-05-31 23:37:35 +08:00
LibereCode f932db713c Logo (Builtin): Minor tweak NixOS_small logo (#2357)
* [fix]: markdown-link to wiki

* [fix]: fix color at 1 spot

* [fix]: fix color at 1 spot, again

* Revert "[fix]: markdown-link to wiki"

This reverts commit 72f4d11c90.

"Remove unrelated changes"
2026-05-31 01:11:53 +08:00
李通洲 d2e8a8fd9e CMake: renames DISABLE_MODULE_* for MODULE_DISABLE_* to align with PACKAGE_DISABLE_* 2026-05-30 18:37:42 +08:00
李通洲 4c1f7c114a Chore: reports if embedded wcwidth is enabled 2026-05-30 18:27:17 +08:00
SirSputnikWiki 90bbfe195f Terminal (Linux): improves terminal name detection for nix packages (#2352)
* Improved terminal name detection for nix packages

* Improved terminal name detection for nix packages

* Update terminalshell_linux.c

Move ffStrbufStartsWithC(&result->processName, '.') before string comparation, as it's much cheaper.
2026-05-30 10:16:12 +08:00
Carter Li 1689fc81e9 Logo (Builtin): adds Origami and Origami_small
Fixes #2321 #2322
2026-05-29 16:05:53 +08:00
Carter Li 4190dd5a6e Logo (Builtin): adds BerserkArch
Fixes #2324 #2310
2026-05-29 16:05:52 +08:00
Carter Li 074f882d7e Wallpaper (Linux): adds COSMIC support 2026-05-29 15:40:27 +08:00
Carter Li 53102380b8 WMTheme (Linux): adds COSMIC support 2026-05-29 15:40:02 +08:00
李通洲 822bc158ba CMake: changes FF_MODULE_XX to FF_DISABLE_MODULE_XX 2026-05-28 23:14:49 +08:00
李通洲 8fbc29a70c Common (strutil): fixes unit tests 2026-05-28 22:41:47 +08:00
李通洲 0ef677a98c Logo (Builtin): add NixOS2
Fixes #2346
2026-05-28 20:12:46 +08:00
Carter Li 10b0d0ca3e CPU (Android): adds Exynos 2600 2026-05-28 19:20:21 +08:00
Carter Li ec4e820e92 Logo: exports ffLogoPrintDetected 2026-05-28 19:18:35 +08:00
Carter Li 6c09fe49e4 Logo (Builtin): warps logo definitions into #ifdef blocks 2026-05-28 18:42:10 +08:00
Carter Li 1ce6398391 Logo (Builtin): splits built-in logos into individual files 2026-05-28 18:42:10 +08:00
Carter Li d1bf208a92 Chore: renames stringUtils to strutil 2026-05-28 15:58:08 +08:00
Carter Li 7ce1e553b8 CMake: makes default structure configurable via CMake 2026-05-28 15:55:43 +08:00
Carter Li 9c878b6943 Chore: moves /src/data/help.json to /doc 2026-05-28 15:54:17 +08:00
Carter Li 6b9a6fd103 CMake: adds MODULE_<module> options to disable modules 2026-05-28 15:41:14 +08:00
Carter Li 896fe60461 CMake: adds option FF_ENABLE_WCWIDTH 2026-05-28 14:47:09 +08:00
Carter Li dadcccdf26 TerminalShell: code refactor 2026-05-28 10:31:35 +08:00
李通洲 0746af7549 Wifi (Linux): adds comments [ci skip] 2026-05-27 17:11:59 +08:00
Carter Li 88c3b7d118 Common (stringUtil): adds ffUtf8CharLenWidth 2026-05-26 16:11:30 +08:00
Carter Li 173d9695b6 Common: removes using of built-in wcwidth, which is locale-dependent 2026-05-26 16:10:01 +08:00
Carter Li 4b265cd56a Common: adds Attr FF_A_ALWAYS_INLINE 2026-05-26 15:37:17 +08:00
李通洲 1f211cf8d1 Brightness: adds ddcciSleep: null to skip DDC/CI detection 2026-05-24 10:58:10 +08:00
李通洲 bac60357c6 Logo: fixes paddingLeft not working with position: top 2026-05-24 08:39:25 +08:00
李通洲 3a0e188570 CMake (Windows): disables usage of WinRT on GCC
Fixes #2341
2026-05-23 22:49:04 +08:00
李通洲 9d5b40686b Global: really prints --stat at the right border 2026-05-23 09:50:49 +08:00
李通洲 a321cd877e Logo: resets color state after printing logo line 2026-05-23 09:44:03 +08:00
李通洲 5f810de1e0 Logo: overrides the auto detected max-width with the configured width, if set 2026-05-23 09:33:58 +08:00
李通洲 3f0a93d057 Logo: reworks position: top; adds a new option --logo-padding-bottom 2026-05-22 20:26:18 +08:00
Carter Li cbca6a965c Logo: prints ASCII logo line by line 2026-05-22 19:09:34 +08:00
Carter Li fde1195c27 TerminalFont (macOS): fixes fallback font detection of Ghostty; adds Muxy terminal support 2026-05-22 14:20:39 +08:00
Carter Li 9856d97bd1 Common (macOS): unifies AppBundle version detection code 2026-05-22 13:37:48 +08:00
Carter Li 2751737ebe CI: builds with quickjs-ng support 2026-05-22 10:24:25 +08:00
Carter Li 834292df29 Brightness (DFBSD): fixes compiling 2026-05-22 10:09:39 +08:00
Carter Li a9a29869a4 Format: tidy 2026-05-22 10:09:39 +08:00
Carter Li 242fb50461 Format: traits undefined result as an error 2026-05-22 09:26:52 +08:00
Carter Li b5c4ffcc85 Format (Lua): simplifies error messages 2026-05-21 09:25:41 +08:00
李通洲 2c3628c630 Format (QJS): converts UINT64 to double and drops usage of BigInt 2026-05-20 23:01:28 +08:00
李通洲 4cca9bf198 Presets: removes invalid comments 2026-05-20 18:40:36 +08:00
李通洲 0ed27d9700 Format: fixes a possible OOB read 2026-05-20 18:40:20 +08:00
李通洲 9bca4eb48f Format: normalizes arg name before pass to script language 2026-05-20 18:39:12 +08:00
李通洲 462b80fc36 CMake: corrects the package name of quickjs-ng 2026-05-20 18:17:38 +08:00
Carter Li f49620a95b CMake: hardens Lua handling 2026-05-20 16:18:50 +08:00
Carter Li 6e0949c739 CMake: fixes finding quickjs 2026-05-20 09:32:02 +08:00
Carter Li 4b18ab0de7 Brightness (macOS): fixes building 2026-05-20 09:31:35 +08:00
Carter Li 8abd75a746 Brightness: refactor 2026-05-20 00:09:09 +08:00
Carter Li d5b215e074 Brightness (FreeBSD): improves DDC/CI handling 2026-05-20 00:07:20 +08:00
Carter Li 0b22427091 WM (Linux): fixes swayfx version detection on NixOS 2026-05-19 17:20:56 +08:00
Carter Li aa34910b6c CMake: actually compiles with quickjs-ng definitions 2026-05-19 15:52:01 +08:00
李通洲 52972ed833 CI (Windows): bundles dlls of lua & qjs 2026-05-18 11:06:30 +08:00
李通洲 68e75effab CMake: adds comments [ci skip] 2026-05-18 11:01:37 +08:00
Carter Li bb79370d03 Brightness (FreeBSD): adds ddc-ci detection support (WIP) 2026-05-18 10:08:31 +08:00
李通洲 9613cdd146 CI: builds with quickjs support 2026-05-18 01:42:13 +08:00
李通洲 724b816252 CI: builds with lua support 2026-05-17 23:21:49 +08:00
李通洲 7c89a10add Common: adds Lua script support for custom format 2026-05-17 20:12:03 +08:00
李通洲 fb5ec76eb3 Global: skips module if format buffer is empty 2026-05-17 19:55:30 +08:00
Carter Li 7141214f95 WM (Linux): fixes swayfx version detection 2026-05-17 09:51:19 +08:00
Carter Li 7d6074968f Packaging: update debian stuff [ci skip] 2026-05-15 09:40:40 +08:00
Carter Li 3bd380802b Merge remote-tracking branch 'origin/master' into dev 2026-05-15 09:40:24 +08:00
李通洲 ec1200dc06 Media (Windows): removes using of C++20 std::bind_front 2026-05-14 19:50:38 +08:00
Carter Li 5c18c061b3 GPU (Linux): silences a warning in Release mode 2026-05-14 09:39:17 +08:00
Carter Li acf610416c Merge pull request #2331 from fastfetch-cli/dev
Release: v2.63.1
2026-05-13 19:54:48 +08:00
Carter Li 90d3b3d49f Release: v2.63.1 2026-05-13 19:41:21 +08:00
Carter Li bbc5b4de98 Wifi (Linux): disables usage of Netlink on big-endian platforms
Until some can confirm it works
2026-05-13 19:29:33 +08:00
Carter Li 7f9b6187a6 CommandOption: fixes segfault with unknown module 2026-05-13 19:28:36 +08:00
Carter Li 8067e43631 Media (Linux): be compatible with signed media length
Fixes Chrome support
2026-05-13 19:07:14 +08:00
Carter Li 61dba1ea05 Packaging: update debian stuff [ci skip] 2026-05-13 16:04:51 +08:00
Carter Li a94df76bfa Merge pull request #2330 from fastfetch-cli/dev
Release v2.63.0
2026-05-13 16:04:31 +08:00
Carter Li b2b748b07c DisplayServer (Linux): fixes a memory leak 2026-05-13 15:44:00 +08:00
Carter Li 77ce6b0e4c Settings (Linux): shuts libeet down if applicate 2026-05-13 15:33:55 +08:00
Carter Li d28d307b63 Release: v2.63.0 2026-05-13 14:56:22 +08:00
Carter Li 3492f9bfa1 Common (Linux): tidy 2026-05-13 14:38:16 +08:00
李通洲 79c67ec0d7 CI (Linux): installs libefl 2026-05-13 14:37:39 +08:00
Carter Li 6527f03a9b Logo (Builtin): add Ximper Linux
Fixes #2283
2026-05-13 13:53:00 +08:00
Carter Li a8b629f58c DE (Linux): fixes an inverted test 2026-05-13 13:23:23 +08:00
Carter Li 5df00a3394 Global: adds missing #endifs back 2026-05-13 13:14:21 +08:00
Carter Li 8a7c83cac6 Doc: update changelog 2026-05-13 11:08:02 +08:00
Carter Li 27bffb3464 Windows: removes unused config wmiTimeout 2026-05-13 11:07:48 +08:00
李通洲 875afb7cde Media (Windows): adds global.playerName selection support 2026-05-13 10:19:45 +08:00
李通洲 3e99a7035b Media (Windows): adds length & position detection support 2026-05-13 10:19:31 +08:00
Carter Li 63873763de Doc: update JsonSchema [ci skip] 2026-05-13 10:17:06 +08:00
Carter Li 27c83e88f2 Media: prints hours if the song is longer than 1 hour 2026-05-13 10:12:07 +08:00
Carter Li f48904805f Media: fixes percentage format 2026-05-13 10:12:07 +08:00
Carter Li 531cd0909a Media (Linux): don't use playerctld as a media player 2026-05-13 10:12:07 +08:00
李通洲 eafcdfec9e WM (Linux): fixes building 2026-05-12 23:10:09 +08:00
李通洲 d6bd855733 DateTime: adds AM/PM format support to date and time output
Fixes #2325
2026-05-12 22:54:49 +08:00
李通洲 af7e2d47d1 OS (Windows): adds support for Embedded variant in OS detection 2026-05-12 22:54:31 +08:00
Carter Li f71c0b0866 Media: adds progress number & bar format support 2026-05-12 19:14:56 +08:00
Carter Li 1400291ae9 Media (macOS): adds length & position detection support 2026-05-12 15:07:22 +08:00
Carter Li 7799dbe481 WM: adds full support of Enlightenment
Fixes #2165
2026-05-12 10:56:14 +08:00
Carter Li 8426833c36 DE (Linux): adds Enlightenment version detection support 2026-05-12 08:36:50 +08:00
Carter Li 235a2018fc Chore: update .clang-format [ci skip] 2026-05-12 08:36:50 +08:00
李通洲 470e3b4e57 IO (Linux): fixes a possible fd leak 2026-05-12 00:08:27 +08:00
Carter Li 1942dce980 Media (Linux): detects song length & play position 2026-05-11 23:25:52 +08:00
Carter Li efca4f3597 DBus: expands Get(U)Int to (u)int64 2026-05-11 23:24:45 +08:00
Carter Li 43ddbdca85 Logo (Builtin): tidy
Fk `clang-format`
2026-05-11 11:06:01 +08:00
Carter Li 5d29e26509 Logo (Builtin): cleans up Kylin 2026-05-11 11:03:15 +08:00
Carter Li 8daec2568c Common (Windows): adds a missing #include 2026-05-11 10:13:48 +08:00
Carter Li 320e1bf4e0 Doc: update changelog [ci skip] 2026-05-11 09:42:48 +08:00
Carter Li 38e98d3d51 Logo (Builtin): cleans up xj380 2026-05-11 09:37:57 +08:00
HNO₃ 50964fcddf Logo (Builtin): adds openRuyi (#2318)
* Logo: Add openRuyi

* Update ASCII art in openruyi.txt

* Fix casing of 'openRuyi' in builtin.c

---------

Co-authored-by: Z572 <z572@z572.online>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-05-11 09:37:02 +08:00
国企鱼 6c7a8a8c41 Logo (Builtin): adds XJ380 OS Logo (#2309) 2026-05-11 09:36:32 +08:00
Carter Li 92082eed54 Doc: update PR template [ci skip] 2026-05-11 08:56:31 +08:00
Carter Li 26b3a84b8a Terminal: fixes TDE konsole version detection
Fixes #2319
2026-05-11 08:51:46 +08:00
Carter Li 0747fc0887 CI (OmniOS): fixes build 2026-05-10 17:35:33 +08:00
Carter Li 60fbe1fd0b Common (Windows): uses WinRT APIs only when FF_HAVE_WINRT is defined 2026-05-10 16:46:20 +08:00
Carter Li f8667d9faa Doc: updates changelog 2026-05-10 16:20:48 +08:00
Carter Li 1c89bbc34e Chore: clang-format 2026-05-10 16:00:22 +08:00
Carter Li b37f020270 DisplayServer (Linux): binds minimal version to avoid breakage 2026-05-10 15:43:13 +08:00
Carter Li fbc9569e13 DisplayServer (Linux): updates kde-output-device-v2 again 2026-05-10 15:37:03 +08:00
François Revol a923f61115 Wallpaper (Haiku): adds support (#2314)
* Wallpaper (Haiku): Add support

* Refactor wallpaper detection logic and memory handling

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-05-09 20:35:25 -05:00
李通洲 bc0a515998 Common (Windows): works around a compiler optimise bug 2026-05-09 15:43:15 +08:00
李通洲 87d89130ad Common (Windows): fixes Windows 11 detection code 2026-05-09 15:43:15 +08:00
李通洲 f46aa316cb Wifi (Linux): improves protocol reporting 2026-05-09 14:34:23 +08:00
Carter Li fdb5f30cb8 CMake (Linux): removes linux/wireless detection
Always required now
2026-05-09 11:04:39 +08:00
Carter Li 91f1c4db10 Wifi: fixes 60 GHz band detection 2026-05-09 11:01:50 +08:00
Carter Li 44e2948b1d Wifi: adds 6 GHz channels detection 2026-05-09 11:01:05 +08:00
Carter Li b86acf6c36 Wifi (Linux): fixes bugs when multiple BSS exists; adds ioctl fallback 2026-05-09 11:00:40 +08:00
Carter Li 9a15666248 Wifi (Linux): switches to netlink impl 2026-05-08 22:43:16 +08:00
李通洲 f5dfec6dcb Battery (Windows): tidy
Co-authored-by: Copilot <copilot@github.com>
2026-05-08 14:31:42 +08:00
Carter Li 8c55c06fa7 OS (Linux): detects bedrock only on Linux 2026-05-06 18:15:57 +08:00
李通洲 8159f473cc Common (Windows): allows COM be used in C sources 2026-05-06 15:01:40 +08:00
李通洲 dca3b154ef Global (Windows): fixes possible use-before-init errors 2026-05-06 15:00:52 +08:00
李通洲 79b61f1391 Common (Windows): inits WinRT/COM globally 2026-05-06 14:38:10 +08:00
李通洲 ba54763dde Camera (Windows): adds support for Display P3 color space 2026-05-06 11:06:07 +08:00
Oliver Lin 451bc394ee OS (Linux): enhances Deepin version detection using /etc/os-version (#2300)
* feat(os): enhance Deepin detection with os-version data

Add a Deepin-specific enhancement in Linux OS detection that reads
`/etc/os-version` for `MinorVersion` and `EditionName`.

When available, it now:
- sets `versionID` to `MinorVersion`
- updates `prettyName` to include version and optional edition

This improves Deepin version accuracy and provides a clearer OS name
than relying solely on generic `os-release` fields.feat(os): enhance Deepin detection with os-version data

Add a Deepin-specific enhancement in Linux OS detection that reads
`/etc/os-version` for `MinorVersion` and `EditionName`.

When available, it now:
- sets `versionID` to `MinorVersion`
- updates `prettyName` to include version and optional edition

This improves Deepin version accuracy and provides a clearer OS name
than relying solely on generic `os-release` fields.

* fix(os): use distro name when formatting Deepin prettyName

Update Deepin enhancement formatting to build `prettyName` from
`result->name` instead of hardcoding "Deepin". This keeps output
consistent with the detected distro name while still appending version
and edition details.fix(os): use distro name when formatting Deepin prettyName

Update Deepin enhancement formatting to build `prettyName` from
`result->name` instead of hardcoding "Deepin". This keeps output
consistent with the detected distro name while still appending version
and edition details.

* fix(os/linux): guard Deepin minor version override

Only apply Deepin’s `minor` value to `versionID` when an edition is
present and `prettyName` does not already include parenthesized details.
This avoids incorrectly overriding parsed version info in enhanced names.fix(os/linux): guard Deepin minor version override

Only apply Deepin’s `minor` value to `versionID` when an edition is
present and `prettyName` does not already include parenthesized details.
This avoids incorrectly overriding parsed version info in enhanced names.

Co-authored-by: Copilot <copilot@github.com>

* Refactor Deepin enhancement detection logic

* Refactor detectDeepinEnhancement function

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-05-05 20:43:17 -05:00
李通洲 93f9ed1bf5 Wmtheme (Linux): adds NebiDE support
Ref: #2295
2026-05-04 19:44:42 +08:00
Sarp Mateson d9e4389ed4 Logo (Builtin): add NebiOS (#2295)
* added logo with nebisoft's color palette, updated builtin.c

* forgot to update the nebios logo with    color placeholders
2026-05-04 19:42:51 +08:00
李通洲 b465052ad2 Logo (Builtin): removes Ubuntu KDE 2026-05-02 22:19:26 +08:00
李通洲 2e6b9cd503 OS (Linux): adds comments 2026-05-02 22:18:08 +08:00
李通洲 0557f16c16 OS (Linux): adds Ubuntu Unity detection 2026-05-02 22:06:18 +08:00
李通洲 08e252a44c OS (Linux): adds Ubuntu Kylin detection 2026-05-02 21:59:22 +08:00
Oliver Lin 90e2d8f8d9 OS (Linux): detects Ubuntu Studio before Kubuntu on KDE systems (#2298)
* fix(os): detect Ubuntu Studio before KDE-based flavor checks

Add an explicit Ubuntu Studio detection in `getUbuntuFlavour()` by
checking for `/usr/share/doc/ubuntustudio-desktop` and setting
`name`, `id`, and `idLike` accordingly.

This prevents Ubuntu Studio systems from being misidentified as
Kubuntu when KDE/Plasma-related XDG config paths are present.fix(os): detect Ubuntu Studio before KDE-based flavor checks

Add an explicit Ubuntu Studio detection in `getUbuntuFlavour()` by
checking for `/usr/share/doc/ubuntustudio-desktop` and setting
`name`, `id`, and `idLike` accordingly.

This prevents Ubuntu Studio systems from being misidentified as
Kubuntu when KDE/Plasma-related XDG config paths are present.

* refactor(os): detect Ubuntu Studio via package presence
2026-05-02 21:54:33 +08:00
Angelo Verlain 0dd8d80e02 Logo (Builtin): correctly detects GNOME OS (#2296)
* Correctly detect GNOME OS

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-05-02 01:06:47 +08:00
Christopher L Fox Junior 3cddf31987 Add ASCII logo for KibaOS (#2294)
* Add ASCII logo for KibaOS

* Add KibaOS logo to builtin.c

* Update builtin.c

* Update builtin.c

* Add KibaOS logo to builtin logo configurations

Added KibaOS logo configuration to the logo data structure.

* Fix KibaOS Syntax
2026-05-01 17:13:32 +08:00
李通洲 fe1c5c8f6f Media (Windows): improves readability
Co-authored-by: Copilot <copilot@github.com>
2026-05-01 11:58:19 +08:00
李通洲 994bd53d30 Media (Windows): major code refactor
moves detection code into fastfetch binary

Co-authored-by: Copilot <copilot@github.com>
2026-04-30 20:26:57 +08:00
李通洲 383a4190ca Comon (macOS): tidy
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 13:26:46 +08:00
李通洲 42f2e5a745 Netif (macOS): improves reliability 2026-04-30 11:01:07 +08:00
Carter Li 14b8bb2bb5 Temps: validates temp color thresholds as integers in JSON parsing
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 09:33:48 +08:00
Carter Li b68ad3626c Sysctl: returns error on failed string fetch and removes malloc null check
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 09:31:28 +08:00
Carter Li cd25803e32 Option: adds a missing validation 2026-04-30 09:27:05 +08:00
Carter Li 3d6bffe7fe Settings: fixes DBusMessage reply leaks in XFConf functions
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 09:04:02 +08:00
Carter Li e694c8ac84 Properties: fixes a typo
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 08:50:23 +08:00
李通洲 dfff57dd85 Percent: improve reliability
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 08:40:30 +08:00
李通洲 c5141855a2 Path: removes dead code 2026-04-30 08:40:30 +08:00
李通洲 6cb186f229 Parsing: improves reliablity
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 08:40:30 +08:00
李通洲 e91f62aa70 Option: improve reliablity 2026-04-30 08:40:30 +08:00
李通洲 ab5cf94099 Networking: improves reliablity
Co-authored-by: Copilot <copilot@github.com>
2026-04-30 08:40:30 +08:00
李通洲 d9eccd70ed Battery (Windows): removes option useSetupApi 2026-04-29 18:54:18 +08:00
李通洲 025febc78d Battery (Windows): switches to query WMI with NtApi as a fast path
Co-authored-by: Copilot <copilot@github.com>
2026-04-29 18:50:04 +08:00
李通洲 69cc19d6f5 Brightness (Windows): cleanups debug log 2026-04-29 18:42:12 +08:00
李通洲 2e4dd1d262 Chore: silenses compiler warnings 2026-04-29 17:36:37 +08:00
李通洲 24ec0e6035 Common (Windows): removes old COM based WMI query implementation 2026-04-29 00:11:29 +08:00
李通洲 6e50aaf3ff Brightness (Windows): uses COM-less method to query WMI
Co-authored-by: Copilot <copilot@github.com>
2026-04-29 00:11:29 +08:00
李通洲 e7cd5f618d Bluetooth (Windows): uses CM API to detect BTH battery detection
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 19:52:38 +08:00
李通洲 55e4896524 Chore: runs clang-format 2026-04-28 19:45:19 +08:00
李通洲 594c73461e Netif: fixes compiler warnings 2026-04-28 15:19:44 +08:00
Or-simen 94ceeb4482 Chore: fixes typo from FF_UNITIALIZED to FF_UNINITIALIZED (#2290)
Co-authored-by: or sim <you@example.com>
2026-04-27 21:23:42 -05:00
李通洲 4ee7dd72d0 IO: improves code quality & reliablity 2026-04-28 09:03:24 +08:00
李通洲 414f7ce067 Netif: improves code quality
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 08:51:03 +08:00
李通洲 e1dffe794b Library: improves code quality
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 08:51:03 +08:00
李通洲 181b775f73 Init: don't print unecessary ANSI escape codes
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 23:15:30 +08:00
李通洲 c4c934d23e Format: fixes UINT64 handling
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 23:00:52 +08:00
李通洲 31c73543e8 Font: improves pt handling
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 22:57:29 +08:00
李通洲 d79e1d7fbc FFstrbuf: improves robustness of ffStrbufMatchSeparatedNS
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 22:49:31 +08:00
李通洲 3883047dce Platform: initializes pageSize
Noop, because the whole platform is statically initialized

Co-authored-by: Copilot <copilot@github.com>
2026-04-27 22:35:11 +08:00
李通洲 4eebc1b6ee Platform (Windows): adds comments
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 22:30:48 +08:00
李通洲 08b79ff4ae Platform (OpenBSD): silences a compiler warning
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 22:27:10 +08:00
李通洲 ffc38eb0f1 FFlist: add __restrict 2026-04-27 22:21:45 +08:00
李通洲 37ee193c40 DBus: improves message handling 2026-04-27 22:11:34 +08:00
李通洲 c10027f1d7 JsonConfig: fixes CPUUsage preparation never executed
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 21:56:52 +08:00
李通洲 039fa1ba77 CommandOption: generates JSON result entry even for unknown modules
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 20:28:11 +08:00
李通洲 0db820a6c1 Binary: skips short string entirely to improve performance
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 19:51:14 +08:00
tnut 8b611899d1 Packages (Linux): adds cards counting (NuTyX) (#2287)
* Packages:add cards counting (NuTyX)

* package.c
no need to add counts.catds

* Sort packages print alphabetically

* ditto

* ditto

* packages.c
update FF_ARG and ffpackagesModule.info

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2026-04-27 19:31:08 +08:00
李通洲 ba7e1eb18b Netif (Windows): correctly selects lowest-metric default route on IPv4
... and improve performance slightly
2026-04-26 16:57:38 +08:00
李通洲 6979b1efc5 Dep (3rdparty): upgrades display-library 2026-04-26 16:00:01 +08:00
878 changed files with 15443 additions and 8532 deletions
+8 -2
View File
@@ -1,7 +1,6 @@
# find . -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) ! -path "src/3rdparty/*" -print0 | xargs -0 clang-format -i
# find . -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" -o -name "*.m" -o -name "*.mm" \) -print0 | xargs -0 clang-format -i
BasedOnStyle: LLVM
Language: Cpp
UseTab: Never
IndentWidth: 4
@@ -81,3 +80,10 @@ AttributeMacros:
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: false
---
Language: ObjC
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
ObjCBreakBeforeNestedBlockParam: true
+1
View File
@@ -1,2 +1,3 @@
src/3rdparty/**
build/**
src/logo/builtin.c
+4
View File
@@ -21,6 +21,10 @@ Closes #
-
## Screenshots
<!-- Required if this PR introduces visual changes. -->
## Checklist
- [ ] I have tested my changes locally.
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
prepare: |
uname -a
pkg update
pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf
pkg install -y llvm cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf lua54 libva libvdpau
run: |
env CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
run: |
uname -a
sudo pkg update
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa lua54 libva libvdpau
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 || pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10
pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 || pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 lua
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
run: |
uname -a
apt-get update && apt-get install -y wget
apt-get install -y cmake make gcc libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
apt-get install -y cmake make gcc libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libefl-all-dev liblua5.4-dev libvdpau-dev libva-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
curl -L https://apt.kitware.com/keys/kitware-archive-latest.asc | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ jammy main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null
echo -e 'Acquire::https::Verify-Peer "false";\nAcquire::https::Verify-Host "false";' >> /etc/apt/apt.conf.d/99ignore-certificates
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev rpm
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libefl-all-dev liblua5.4-dev libvdpau-dev libva-dev rpm
CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
+3 -3
View File
@@ -39,12 +39,12 @@ jobs:
run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
run: sudo apt-get update && sudo apt-get install -y gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev libefl-all-dev libunwind-dev liblua5.4-dev libvdpau-dev libva-dev rpm ninja-build
- name: install linuxbrew packages
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa quickjs-ng --ignore-dependencies
- name: Initialize CodeQL
if: inputs.arch == 'amd64'
@@ -53,7 +53,7 @@ jobs:
languages: c
- name: configure project
run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: CC=gcc-13 CMAKE_PREFIX_PATH=/home/linuxbrew/.linuxbrew PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
+3 -3
View File
@@ -26,18 +26,18 @@ jobs:
run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y gcc-13 gcc-13-multilib libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev rpm ninja-build
run: sudo apt-get update && sudo apt-get install -y gcc-13 gcc-13-multilib libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev libefl-all-dev libunwind-dev liblua5.4-dev libvdpau-dev libva-dev rpm ninja-build
- name: install linuxbrew packages
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa quickjs-ng --ignore-dependencies
- name: cmake version
run: cmake --version
- name: configure project
run: CC=gcc-13 PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DCMAKE_C_FLAGS="-m32 -march=i686 -mtune=i686" -DCMAKE_SYSTEM_PROCESSOR_OVERRIDE=i686 -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=i386 -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: CC=gcc-13 CMAKE_PREFIX_PATH=/home/linuxbrew/.linuxbrew PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DCMAKE_C_FLAGS="-m32 -march=i686 -mtune=i686" -DCMAKE_SYSTEM_PROCESSOR_OVERRIDE=i686 -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=i386 -GNinja -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
uname -a
apt-get update && apt-get install -y software-properties-common
add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev rpm
apt-get update && apt-get install -y cmake make gcc-13 libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev libefl-all-dev liblua5.4-dev libvdpau-dev libva-dev rpm
CC=gcc-13 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
+2 -1
View File
@@ -25,7 +25,8 @@ jobs:
- name: install required packages
run: |
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew update
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa lua quickjs-ng
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
+3 -1
View File
@@ -14,12 +14,14 @@ jobs:
- name: setup alpine linux
uses: jirutka/setup-alpine@master
with:
branch: edge
- name: install dependencies
run: |
cat /etc/alpine-release
uname -a
apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev lua5.4-dev quickjs-ng-dev libvdpau-dev libva-dev gcc g++
shell: alpine.sh --root {0}
- name: build
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
environment_variables: 'CMAKE_BUILD_TYPE'
run: |
uname -a
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick
sudo pkgin -y install clang cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick libva libvdpau
CC=clang cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
run: uname -a
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_THREADS=OFF
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_EET=OFF -DENABLE_THREADS=OFF
- name: build project
run: cmake --build . --target package --verbose -j4
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
envs: 'CMAKE_BUILD_TYPE'
prepare: |
uname -a
pkg update --accept
pkg update --accept || true
pkg install gcc14 cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja
run: |
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
run: |
uname -a
sudo pkg_add -u
sudo pkg_add -r llvm-21.1.2p0 cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
sudo pkg_add -r llvm-21.1.2p0 cmake git wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa lua-5.4.7 # pkg-config is preinstalled
CC=clang-21 cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
release: "11.4-gcc-14"
prepare: |
uname -a
pkg install cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja dconf mesa
pkg install cmake git pkg-config glib2 dbus sqlite-3 imagemagick ninja dconf mesa lua
run: |
export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig
+2 -2
View File
@@ -37,7 +37,7 @@ jobs:
with:
msystem: ${{ inputs.msystem }}
update: true
install: git mingw-w64-clang-${{ inputs.msys-arch }}-7zip mingw-w64-clang-${{ inputs.msys-arch }}-cmake mingw-w64-clang-${{ inputs.msys-arch }}-clang mingw-w64-clang-${{ inputs.msys-arch }}-vulkan-loader mingw-w64-clang-${{ inputs.msys-arch }}-vulkan-headers mingw-w64-clang-${{ inputs.msys-arch }}-opencl-icd mingw-w64-clang-${{ inputs.msys-arch }}-opencl-headers mingw-w64-clang-${{ inputs.msys-arch }}-cppwinrt mingw-w64-clang-${{ inputs.msys-arch }}-imagemagick mingw-w64-clang-${{ inputs.msys-arch }}-chafa mingw-w64-clang-${{ inputs.msys-arch }}-directx-headers
install: git mingw-w64-clang-${{ inputs.msys-arch }}-7zip mingw-w64-clang-${{ inputs.msys-arch }}-cmake mingw-w64-clang-${{ inputs.msys-arch }}-clang mingw-w64-clang-${{ inputs.msys-arch }}-vulkan-loader mingw-w64-clang-${{ inputs.msys-arch }}-vulkan-headers mingw-w64-clang-${{ inputs.msys-arch }}-opencl-icd mingw-w64-clang-${{ inputs.msys-arch }}-opencl-headers mingw-w64-clang-${{ inputs.msys-arch }}-cppwinrt mingw-w64-clang-${{ inputs.msys-arch }}-imagemagick mingw-w64-clang-${{ inputs.msys-arch }}-chafa mingw-w64-clang-${{ inputs.msys-arch }}-lua mingw-w64-clang-${{ inputs.msys-arch }}-quickjs-ng mingw-w64-clang-${{ inputs.msys-arch }}-directx-headers
- name: print msys version
run: uname -a
@@ -49,7 +49,7 @@ jobs:
run: cmake --build . --verbose -j4
- name: copy necessary dlls
run: cp /${{ inputs.msystem-lower }}/bin/{OpenCL,vulkan-1}.dll .
run: cp /${{ inputs.msystem-lower }}/bin/{lua55,libqjs-0}.dll .
- name: list features
run: ./fastfetch --list-features
+128 -1
View File
@@ -1,7 +1,134 @@
# 2.64.2
Bugfixes:
* Fixes image rendering being wiped quickly (#2374)
* Regression from v2.64.0
* Fixes ASCII logo being overwritten in `--dynamic-interval` mode
* Regression from v2.64.0
Logos:
* Updates OpenWrt and adds a small variant (#2376)
* The old one is renamed to `openwrt_old`
# 2.64.1
Features:
* Adds a CMake option `-DPACKAGES_REMOVE_DISABLED` to remove detection code of disabled packages (`-DPACKAGES_DISABLE_<PACKAGE_NAME>`) for slightly smaller binary size (Packages)
Bugfixes:
* Fixes compatibility issues with Lua 5.3
* Avoid possible infinite recursion in `encode_json` when encoding deeply nested tables or circular references
* Fixes compilation issues when building with old macOS SDKs
# 2.64.0
New **optional build** dependencies:
* [`libva`](https://github.com/intel/libva) and [`libvdpau`](https://www.freedesktop.org/wiki/Software/VDPAU) for the new `Codec` module.
* [Lua 5.3 to 5.5](https://www.lua.org/) for Lua scripting support, or [QuickJS](https://github.com/quickjs-ng/quickjs) v0.15.0 or newer for JavaScript scripting support.
Features:
* Adds `Codec` module support for Windows, macOS, Linux, and Android for hardware-accelerated video codec detection (Codec)
* Backends used (results may vary depending on the backend due to driver differences):
* Linux and BSD: VA-API (default) and VDPAU (fallback for NVIDIA). Fastfetch must be built with `libva` and `libvdpau` support to enable these backends.
* Windows: D3D12VA (Windows 11) and D3D11VA+MFT (Windows 10 or older)
* macOS: VideoToolbox
* Android: AMediaCodec
* Common: Vulkan Video (disabled by default; can be enabled with `"useVulkan": true`)
* By default, both encoders and decoders are reported. If no codecs are detected for a given type, `None` is reported. This behavior can be configured using the `"showType": "encoder|decoder"` option.
* Adds experimental Lua script support for custom formats (Global)
* Basic usage (using `Title` as an example): `{ "type": "title", "format": "lua:return string.format('Hello %s@%s', (...).userName, (...).hostName)" }`. The `lua:` prefix indicates a Lua script. A `return` statement is required to pass the final result back to the fastfetch module; otherwise, `nil` is returned implicitly and the entire module output is skipped.
* Parameters are passed via variable arguments `(...)`. Users can assign them to named variables for better readability. For example: `lua:local args = ...; string.format('Hello %s@%s', args.userName, args.hostName)`.
* The Lua interpreter instance is shared across all modules. This allows users to store and manipulate data across modules. For example:
* `{ "type": "shell", "format": "lua:shell = ..." } // Note: no "return" here`
* `{ "type": "terminal", "format": "lua:return shell.prettyName .. ' in ' .. (...).prettyName" } // This will print the detected shell and terminal names`
* A `json_encode(table, is_pretty)` function has been added to the Lua API for easier debugging. For example, `lua:return json_encode(...)` will print all available variables and their values in JSON format.
* Supported Lua versions: Lua 5.3 to 5.5 (Lua 5.1 and LuaJIT are not supported). The Lua version is auto-detected at build time. Once built, users can check the configured Lua version using `fastfetch --list-features`.
* Adds experimental QuickJS script support for custom formats as an alternative to Lua (Global)
* Basic usage: `{ "type": "title", "format": "qjs:`Hello ${this.userName}@${this.hostName}`" }`. The `qjs:` prefix indicates a JavaScript script. No `return` statement is needed; the final result is simply the evaluated value of the script.
* Parameters are passed via the `this` object. Usage is mostly the same as Lua, but using JavaScript syntax.
* Requires [quickjs-ng v0.15.0](https://github.com/quickjs-ng/quickjs/releases/tag/v0.15.0) or newer.
* Adds CMake options `-DMODULE_DISABLE_<MODULE_NAME>=ON` to disable modules at compile time for a smaller binary size
* Use `cmake -L . | grep MODULE_DISABLE_` to list all available options.
* These options rely on LTO for dead code elimination (`-DCMAKE_BUILD_TYPE=Release` should enable LTO by default).
* Adds the ability to remove unneeded ASCII logos without modifying the fastfetch source code, further reducing binary size
* Simply remove the corresponding logo file from the logo directory (`src/logo/ascii/[a-z]/*`) and re-run `cmake`.
* Improves string manipulation specifiers in custom formats
* They are now ANSI escape-aware and work correctly with colored output (e.g., percentages with `num-color`) (#2364). Limitations:
* They are still not wide-character aware and treat CJK and emoji characters as raw bytes.
* Escape sequences in the middle of strings are not supported.
* A new `|` specifier has been added to center strings. For example, `{user-name|20}` will center the username in a 20-character-wide field.
* Adds preliminary `Bootmgr`, `Brightness`, and `WMTheme` detection support for Haiku (#2358, Haiku)
* Adds `Wallpaper` and `WMTheme` detection support for the COSMIC desktop environment (Linux)
* Improves terminal name detection for Nix packages (#2352, Terminal, Linux)
* Adds DDC/CI brightness detection support for FreeBSD (Brightness, FreeBSD)
* DDC/CI communication can be very slow. Users can set the `ddcciSleep: null` option to skip DDC/CI detection.
* Reworks the built-in logo printing logic. ASCII logos and modules are now printed line by line, avoiding issues like #2239
* Note: Image logos are not affected by this change and still print the entire image first before printing any modules.
* Adds a new `--logo-padding-bottom` option to control the padding between the bottom of the logo and the first module when `--logo-position top` is used
* Previously, `--logo-padding-right` was used for both right and bottom padding.
* Adds `Samsung Exynos 2600` to CPU detection (CPU, Android)
* Adds terminal font detection support for the Muxy terminal (TerminalFont, macOS)
* Improves the performance of BusyBox (ash) version detection and always reports `ash` as the pretty name (Shell, Linux)
Bugfixes:
* Fixes SwayFX version detection (WM, Linux)
* Fixes fallback font detection for Ghostty (TerminalFont, macOS)
* Fixes `--stat` output to correctly align with the right border (Global)
* Fixes boot manager on macOS 26 (mBoot) is incorrectly reported as `iBoot` (Bootmgr, macOS)
Logos:
* Adds Quasar (#2338, #2323), Origami, Origami_small (#2321, #2322), BerserkArch (#2324, #2310), and NixOS2 (#2346)
* Minor tweaks and color fixes for the NixOS_small logo (#2357)
* Updates NurOS (#2366)
# 2.63.1
Bugfixes:
* Fixes media length detection for Chrome on Linux (Media, Linux)
* Fixes segmentation fault when specifying unsupported modules on command line
* Disables usage of Netlink for Wi-Fi detection on s390x architectures (Wifi, Linux)
# 2.63.0
Changes:
* Introduces a new **build-only** dependency, `libefl`, for querying the Enlightenment window manager configuration:
* `libefl-all-dev` on Debian/Ubuntu
* `libefl-devel` on Fedora
* `efl` on Arch Linux
* The Windows-specific options `battery.useSetupApi` and `global.wmiTimeout` have been removed. (Windows)
Features:
* Adds wallpaper detection support on Haiku (#2314, Wallpaper, Haiku)
* Adds Wi-Fi 6 GHz channel detection and improves protocol reporting (Wifi, Linux)
* Improves Deepin version detection using `/etc/os-version` (#2300, OS, Linux)
* Adds Ubuntu Kylin and Ubuntu Unity flavor detection (OS, Linux)
* Adds NebiDE support (WMTheme, Linux)
* Adds package counting for `cards` on NuTyX (#2287, Packages, Linux)
* Adds `{am-pm}` to custom format for 12-hour time with am/pm (DateTime)
* Adds support for the Enlightenment desktop environment (#2165, WM, Linux)
* Adds support for playback progress detection (Media)
* The module now prints the current playback position and total media duration when supported by the player. If you prefer the previous behavior, you can set `media.percent.type: ["hide-others"]` to hide the new fields.
* Adds support for `global.playerName` for Windows (Media, Windows)
* This allows detecting a specified media player while ignoring others.
* Multi-battery detection is enabled on Windows by default (Battery, Windows)
Bugfixes:
* Improves DisplayServer compatibility on Linux by handling newer `kde-output-device-v2` protocol updates (DisplayServer, Linux)
* This fixes a long-standing issue where display detection fails with an `interface 'kde_output_device_mode_v2' has no event X` error.
* Improves Wi-Fi reliability on Linux by switching to a netlink implementation (Wifi, Linux)
* Improves network interface reliability and default route selection on macOS and Windows (Netif, macOS / Windows)
* Validates temperature color thresholds as integers when parsing JSON configs (Temps)
* Fixes TDE Konsole version detection (#2319, Terminal, Linux)
* Various internal cleanups and optimizations
Logos:
* Adds KibaOS, NebiOS, XJ380, openRuyi, Ximper
* Fixes GNOME OS built-in logo detection (#2296)
# 2.62.1
Bugfixes:
* Fixes Host module not working on some devices (#2279, Host, Linux)
* Fixes the Host module not working on some devices (#2279, Host, Linux)
* Regression from v2.61.0
Logos:
+199 -59
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.62.1
VERSION 2.64.2
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -74,9 +74,12 @@ cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeB
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_VA "Enable libva" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_VDPAU "Enable vdpau" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX OR FreeBSD OR GNU" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_EET "Enable eet" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX OR GNU" OFF)
@@ -104,7 +107,11 @@ option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
option(ENABLE_EMBEDDED_AMDGPUIDS "Embed amdgpu.ids into fastfetch, requires `python`" OFF)
option(ENABLE_WORDEXP "Enable using of wordexp(3) if available, instead of glob(3)" ON)
option(ENABLE_LUA "Enable lua scripting for format strings" ON)
option(ENABLE_QUICKJS "Enable quickjs scripting for format strings" ON)
option(ENABLE_LIBZFS "Enable libzfs" ON)
option(ENABLE_WCWIDTH "Detect wide-width characters with wcwidth when calculating logo and separator width. Disable for a smaller and slightly faster build, but logos containing CJK/emoji may be measured too narrow and render incorrectly. Such usecases are uncommon." ON)
set(DEFAULT_STRUCTURE "Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:LocalIp:Battery:PowerAdapter:Locale:Break:Colors" CACHE STRING "Default module structure for detection")
if(WIN32 AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
option(ENABLE_WIN81_COMPAT "Enable legacy Windows compatibility (Windows 8.1 and later; Windows 7 unsupported)" ON)
endif()
@@ -112,6 +119,14 @@ if(APPLE)
option(ENABLE_APPLE_MEMSIZE_USABLE "Use usable memory size as total memory size in Memory module, to match other systems" OFF)
endif()
file(GLOB FF_MODULE_DIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src/modules" "${CMAKE_CURRENT_SOURCE_DIR}/src/modules/*/")
foreach(FF_MODULE_DIR ${FF_MODULE_DIRS})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src/modules/${FF_MODULE_DIR}")
string(TOUPPER "${FF_MODULE_DIR}" FF_MODULE_UPPER)
option(MODULE_DISABLE_${FF_MODULE_UPPER} "Disable module ${FF_MODULE_DIR}" OFF)
endif()
endforeach()
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
set_property(CACHE BINARY_LINK_TYPE PROPERTY STRINGS ${BINARY_LINK_TYPE_OPTIONS})
@@ -119,7 +134,25 @@ if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS)
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
endif()
set(PACKAGE_MANAGERS AM APPIMAGE APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SOAR SORCERY WINGET XBPS)
set(PACKAGE_MANAGERS
AM APK APPIMAGE
BREW
CARDS CHOCO
DPKG
EMERGE EOPKG
FLATPAK
GUIX
HPKG
KISS
LINGLONG LPKG LPKGBUILD
MACPORTS MOSS MPORT
NIX
OPKG
PACMAN PACSTALL PALUDIS PISI PKG PKGSRC PKGTOOL
RPM
SCOOP SNAP SOAR SORCERY
WINGET
XBPS)
foreach(package_manager ${PACKAGE_MANAGERS})
if(package_manager STREQUAL "WINGET")
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON)
@@ -127,6 +160,7 @@ foreach(package_manager ${PACKAGE_MANAGERS})
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" OFF)
endif()
endforeach()
option(PACKAGES_REMOVE_DISABLED "Remove disabled package managers from the build entirely, instead of just skipping them at runtime" OFF)
if (LINUX)
set(CUSTOM_PCI_IDS_PATH "" CACHE STRING "Custom path to file pci.ids, defaults to `/usr/share/hwdata/pci.ids`")
@@ -160,7 +194,11 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointe
if(WIN32 OR Haiku)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
if(WIN32)
set(CMAKE_CXX_STANDARD 20)
else()
set(CMAKE_CXX_STANDARD 17)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
endif()
@@ -282,14 +320,14 @@ find_package(Python)
if(Python_FOUND)
message(STATUS "Minifying 'help.json'")
execute_process(COMMAND ${Python_EXECUTABLE} -c "import json,sys;json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))"
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json"
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/doc/help.json"
OUTPUT_VARIABLE DATATEXT_JSON_HELP)
if(DATATEXT_JSON_HELP STREQUAL "")
message(ERROR "DATATEXT_JSON_HELP is empty, which should not happen!")
endif()
else()
message(WARNING "Python3 is not found, 'help.json' will not be minified")
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
file(READ "doc/help.json" DATATEXT_JSON_HELP)
endif()
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc")
@@ -349,7 +387,6 @@ else()
endif()
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
@@ -361,7 +398,7 @@ endif()
# Ascii image data #
####################
file(GLOB LOGO_FILES CONFIGURE_DEPENDS "src/logo/ascii/*.txt")
file(GLOB LOGO_FILES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/logo/ascii/[a-z_]/*.txt")
set(LOGO_BUILTIN_H "#pragma once\n#pragma GCC diagnostic ignored \"-Wtrigraphs\"\n\n")
foreach(file ${LOGO_FILES})
fastfetch_load_text("${file}" content)
@@ -384,6 +421,7 @@ set(LIBFASTFETCH_SRC
src/common/impl/init.c
src/common/impl/jsonconfig.c
src/common/impl/library.c
src/common/impl/lua.c
src/common/impl/netif.c
src/common/impl/networking_common.c
src/common/impl/option.c
@@ -402,9 +440,12 @@ set(LIBFASTFETCH_SRC
src/common/impl/path.c
src/common/impl/FFPlatform.c
src/common/impl/smbios.c
src/common/impl/strutil.c
src/detection/bluetoothradio/bluetoothradio.c
src/detection/bootmgr/bootmgr.c
src/detection/chassis/chassis.c
src/detection/codec/codec.c
src/detection/codec/codec_vulkan.c
src/detection/cpu/cpu.c
src/detection/cpuusage/cpuusage.c
src/detection/command/command.c
@@ -446,6 +487,7 @@ set(LIBFASTFETCH_SRC
src/modules/btrfs/btrfs.c
src/modules/camera/camera.c
src/modules/chassis/chassis.c
src/modules/codec/codec.c
src/modules/colors/colors.c
src/modules/cpu/cpu.c
src/modules/cpucache/cpucache.c
@@ -532,6 +574,7 @@ if(LINUX)
src/detection/brightness/brightness_linux.c
src/detection/btrfs/btrfs_linux.c
src/detection/chassis/chassis_linux.c
src/detection/codec/codec_linux.c
src/detection/cpu/cpu_linux.c
src/detection/cpucache/cpucache_linux.c
src/detection/cpuusage/cpuusage_linux.c
@@ -619,6 +662,7 @@ elseif(ANDROID)
src/detection/brightness/brightness_nosupport.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/codec/codec_android.c
src/detection/cpu/cpu_linux.c
src/detection/cpucache/cpucache_linux.c
src/detection/cursor/cursor_linux.c
@@ -693,6 +737,7 @@ elseif(FreeBSD)
src/detection/brightness/brightness_bsd.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_bsd.c
src/detection/codec/codec_linux.c
src/detection/cpu/cpu_bsd.c
src/detection/cpucache/cpucache_shared.c
src/detection/cpuusage/cpuusage_bsd.c
@@ -787,6 +832,7 @@ elseif(NetBSD)
src/detection/brightness/brightness_nbsd.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nbsd.c
src/detection/codec/codec_linux.c
src/detection/cpu/cpu_nbsd.c
src/detection/cpucache/cpucache_shared.c
src/detection/cpuusage/cpuusage_bsd.c
@@ -871,6 +917,7 @@ elseif(OpenBSD)
src/detection/brightness/brightness_obsd.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_windows.c
src/detection/codec/codec_linux.c
src/detection/cpu/cpu_obsd.c
src/detection/cpucache/cpucache_shared.c
src/detection/cpuusage/cpuusage_bsd.c
@@ -947,12 +994,14 @@ elseif(APPLE)
src/common/apple/cf_helpers.c
src/common/apple/osascript.m
src/common/apple/smc_temps.c
src/common/apple/version.m
src/detection/battery/battery_apple.c
src/detection/bluetooth/bluetooth_apple.m
src/detection/bluetoothradio/bluetoothradio_apple.m
src/detection/bootmgr/bootmgr_apple.c
src/detection/brightness/brightness_apple.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/codec/codec_apple.c
src/detection/cpu/cpu_apple.c
src/detection/cpucache/cpucache_apple.c
src/detection/cpuusage/cpuusage_apple.c
@@ -1029,22 +1078,21 @@ elseif(WIN32)
src/common/impl/debug_windows.c
src/common/impl/kmod_windows.c
src/common/windows/getline.c
src/common/windows/com.cpp
src/common/windows/com.c
src/common/windows/registry.c
src/common/windows/unicode.c
src/common/windows/wmi.cpp
src/common/windows/variant.cpp
src/common/windows/version.c
src/detection/battery/battery_windows.c
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_windows.c
src/detection/bluetooth/bluetooth_windows.cpp
src/detection/bluetoothradio/bluetoothradio_windows.c
src/detection/board/board_windows.c
src/detection/bootmgr/bootmgr_windows.c
src/detection/brightness/brightness_windows.cpp
src/detection/brightness/brightness_windows.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_windows.c
src/detection/codec/codec_windows.cpp
src/detection/cpu/cpu_windows.c
src/detection/cpucache/cpucache_windows.c
src/detection/cpuusage/cpuusage_windows.c
@@ -1067,7 +1115,7 @@ elseif(WIN32)
src/detection/locale/locale_windows.c
src/detection/localip/localip_windows.c
src/detection/gamepad/gamepad_windows.c
src/detection/media/media_windows.c
src/detection/media/media_windows.cpp
src/detection/memory/memory_windows.c
src/detection/mouse/mouse_windows.c
src/detection/physicalmemory/physicalmemory_linux.c
@@ -1116,6 +1164,7 @@ elseif(SunOS)
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/codec/codec_linux.c
src/detection/disk/disk_sunos.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_sunos.c
@@ -1189,8 +1238,8 @@ elseif(Haiku)
src/detection/battery/battery_haiku.c
src/detection/bios/bios_windows.c
src/detection/board/board_windows.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_nosupport.c
src/detection/bootmgr/bootmgr_haiku.cpp
src/detection/brightness/brightness_haiku.cpp
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_windows.c
src/detection/cpu/cpu_haiku.c
@@ -1199,6 +1248,7 @@ elseif(Haiku)
src/detection/cursor/cursor_nosupport.c
src/detection/bluetooth/bluetooth_haiku.cpp
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/codec/codec_linux.c
src/detection/disk/disk_haiku.cpp
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_haiku.c
@@ -1238,11 +1288,11 @@ elseif(Haiku)
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_haiku.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_nosupport.c
src/detection/wallpaper/wallpaper_haiku.cpp
src/detection/wifi/wifi_nosupport.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/detection/wmtheme/wmtheme_haiku.cpp
src/detection/camera/camera_nosupport.c
)
elseif(GNU)
@@ -1268,6 +1318,7 @@ elseif(GNU)
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/bluetoothradio/bluetoothradio_linux.c
src/detection/codec/codec_linux.c
src/detection/disk/disk_linux.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
@@ -1334,12 +1385,21 @@ endif()
if(WIN32)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
message(STATUS "WinRT support is disabled due to known issues with g++")
set(HAVE_WINRT FALSE)
else()
include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX("winrt/Windows.Foundation.h" HAVE_WINRT)
if(HAVE_WINRT)
message(STATUS "WinRT headers are available, media detection will be enabled")
else()
message(WARNING "WinRT headers are NOT available, media detection will be disabled")
endif()
endif()
endif()
include(CheckFunctionExists)
check_function_exists(wcwidth HAVE_WCWIDTH)
if(NOT HAVE_WCWIDTH)
list(APPEND LIBFASTFETCH_SRC src/common/impl/wcwidth.c)
endif()
if(NOT WIN32)
check_function_exists(pipe2 HAVE_PIPE2)
endif()
@@ -1347,6 +1407,9 @@ check_function_exists(memrchr HAVE_MEMRCHR)
if(NOT HAVE_MEMRCHR)
list(APPEND LIBFASTFETCH_SRC src/common/impl/memrchr.c)
endif()
if(ENABLE_WCWIDTH)
list(APPEND LIBFASTFETCH_SRC src/common/impl/wcwidth.c)
endif()
if(ENABLE_SYSTEM_YYJSON)
find_package(yyjson)
@@ -1365,6 +1428,15 @@ add_library(libfastfetch OBJECT
${LIBFASTFETCH_SRC}
)
foreach(FF_MODULE_DIR ${FF_MODULE_DIRS})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src/modules/${FF_MODULE_DIR}")
string(TOUPPER "${FF_MODULE_DIR}" FF_MODULE_UPPER)
if(MODULE_DISABLE_${FF_MODULE_UPPER})
target_compile_definitions(libfastfetch PUBLIC FF_MODULE_DISABLE_${FF_MODULE_UPPER}=1)
endif()
endif()
endforeach()
include(CheckCSourceCompiles)
check_c_source_compiles("int main(void){int arr[1];return _Countof(arr);}" COMPILER_SUPPORTS_COUNT_OF)
if(COMPILER_SUPPORTS_COUNT_OF)
@@ -1436,7 +1508,7 @@ if(LINUX)
elseif(ANDROID)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE _FILE_OFFSET_BITS=64 "$<$<CONFIG:DEBUG>:__BIONIC_FORTIFY>" "$<$<CONFIG:DEBUG>:__BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED>")
elseif(WIN32)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00 NOMINMAX UNICODE) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN WINRT_LEAN_AND_MEAN _WIN32_WINNT=0x0A00 NOMINMAX UNICODE) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
elseif(APPLE)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 _DARWIN_C_SOURCE)
elseif(OpenBSD)
@@ -1498,10 +1570,6 @@ if(FreeBSD OR OpenBSD OR NetBSD)
unset(CMAKE_REQUIRED_DEFINITIONS)
endif()
if(HAVE_WCWIDTH)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_WCWIDTH)
endif()
if(HAVE_PIPE2)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_PIPE2)
endif()
@@ -1531,22 +1599,57 @@ if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
endif()
endif()
function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME) # [CMAKE_TARGET_NAME]
if(NOT ENABLE_${VARNAME})
return()
endif()
if(PKG_CONFIG_FOUND)
pkg_search_module(${VARNAME} QUIET ${PKGCONFIG_NAMES})
if(${VARNAME}_FOUND)
set(${VARNAME}_FOUND "pkg-config")
endif()
endif()
if(NOT ${VARNAME}_FOUND)
find_package(${CMAKE_NAME} QUIET)
set(${VARNAME}_FOUND ${${CMAKE_NAME}_FOUND})
set(${VARNAME}_INCLUDE_DIRS ${${CMAKE_NAME}_INCLUDE_DIRS})
set(${VARNAME}_LIBRARIES ${${CMAKE_NAME}_LIBRARIES})
set(${VARNAME}_CFLAGS_OTHER ${${CMAKE_NAME}_CFLAGS_OTHER})
if(${VARNAME}_FOUND)
set(${VARNAME}_FOUND "CMake")
# Some CMake packages (e.g. quickjs) are target-based only and
# don't expose *_INCLUDE_DIRS/*_LIBRARIES variables.
if(ARGC GREATER 3)
set(_FF_CMAKE_TARGET ${ARGV3})
if(NOT _FF_CMAKE_TARGET STREQUAL "")
if(NOT DEFINED ${VARNAME}_INCLUDE_DIRS OR "${${VARNAME}_INCLUDE_DIRS}" STREQUAL "")
get_target_property(_FF_CMAKE_TARGET_INCLUDES ${_FF_CMAKE_TARGET} INTERFACE_INCLUDE_DIRECTORIES)
if(_FF_CMAKE_TARGET_INCLUDES)
set(${VARNAME}_INCLUDE_DIRS ${_FF_CMAKE_TARGET_INCLUDES})
endif()
endif()
if(NOT DEFINED ${VARNAME}_LIBRARIES OR "${${VARNAME}_LIBRARIES}" STREQUAL "")
get_target_property(_FF_CMAKE_TARGET_LIBRARIES ${_FF_CMAKE_TARGET} INTERFACE_LINK_LIBRARIES)
if(_FF_CMAKE_TARGET_LIBRARIES)
set(${VARNAME}_LIBRARIES ${_FF_CMAKE_TARGET_LIBRARIES})
else()
set(${VARNAME}_LIBRARIES ${_FF_CMAKE_TARGET})
endif()
endif()
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
# INTERFACE_LINK_LIBRARIES doesn't expose libvarname.a
target_link_libraries(libfastfetch PRIVATE ${_FF_CMAKE_TARGET})
endif()
endif()
else()
set(${VARNAME}_INCLUDE_DIRS ${${CMAKE_NAME}_INCLUDE_DIRS})
set(${VARNAME}_LIBRARIES ${${CMAKE_NAME}_LIBRARIES})
set(${VARNAME}_CFLAGS_OTHER ${${CMAKE_NAME}_CFLAGS_OTHER})
endif()
endif()
endif()
if(NOT ${VARNAME}_FOUND)
@@ -1554,7 +1657,7 @@ function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
return()
endif()
message(STATUS "Library: found ${VARNAME}")
message(STATUS "Library: found ${VARNAME} by ${${VARNAME}_FOUND}")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_${VARNAME}=1)
target_include_directories(libfastfetch PRIVATE ${${VARNAME}_INCLUDE_DIRS})
@@ -1592,6 +1695,14 @@ ff_lib_enable(DRM
"libdrm"
"Libdrm"
)
ff_lib_enable(VA
"libva-drm"
"Libva-drm"
)
ff_lib_enable(VDPAU
"vdpau"
"vdpau"
)
ff_lib_enable(DRM_AMDGPU
"libdrm_amdgpu"
"Libdrm_Amdgpu"
@@ -1604,6 +1715,10 @@ ff_lib_enable(DCONF
"dconf"
"DConf"
)
ff_lib_enable(EET
"eet"
"Eet"
)
ff_lib_enable(DBUS
"dbus-1"
"DBus"
@@ -1667,6 +1782,36 @@ ff_lib_enable(ELF
"libelf"
"libelf"
)
ff_lib_enable(QUICKJS
"qjs"
"qjs"
"qjs"
)
if(ENABLE_LUA)
# Lua is a special case since its CMake config does not follow the usual pattern
find_package(Lua QUIET)
if(Lua_FOUND AND NOT DEFINED Lua_VERSION) # For CMake 4.2- compatible
set(Lua_VERSION ${LUA_VERSION_STRING})
set(Lua_VERSION_MAJOR ${LUA_VERSION_MAJOR})
set(Lua_VERSION_MINOR ${LUA_VERSION_MINOR})
endif()
if(Lua_FOUND)
if((NOT Lua_VERSION_MAJOR EQUAL 5) OR Lua_VERSION_MINOR LESS 3 OR Lua_VERSION_MINOR GREATER 5)
message(STATUS "Library: Lua version ${Lua_VERSION} is not supported, requires 5.3-5.5")
unset(Lua_FOUND)
else()
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LUA=1)
target_include_directories(libfastfetch PRIVATE ${LUA_INCLUDE_DIR})
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
target_link_libraries(libfastfetch PRIVATE ${LUA_LIBRARIES})
endif()
message(STATUS "Library: found LUA ${Lua_VERSION} by CMake")
endif()
else()
message(STATUS "Library: missing: LUA")
endif()
endif()
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS=1)
@@ -1690,8 +1835,11 @@ if(ENABLE_LIBZFS)
)
endif()
endif()
if(ENABLE_WCWIDTH)
target_compile_definitions(libfastfetch PUBLIC FF_ENABLE_WCWIDTH=1)
endif()
if(NOT HAVE_MEMRCHR)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_CUSTOM_MEMRCHR=1)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_CUSTOM_MEMRCHR=1)
endif()
if(LINUX)
@@ -1721,6 +1869,7 @@ elseif(APPLE)
PRIVATE "-framework OpenGL"
PRIVATE "-framework OpenCL"
PRIVATE "-framework SystemConfiguration"
PRIVATE "-framework VideoToolbox"
PRIVATE "-weak_framework CoreDisplay"
PRIVATE "-F /System/Library/PrivateFrameworks"
@@ -1747,6 +1896,11 @@ elseif(WIN32)
PRIVATE "mincore"
)
endif()
if(HAVE_WINRT)
target_link_libraries(libfastfetch
PRIVATE "runtimeobject"
)
endif()
elseif(FreeBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
@@ -1833,20 +1987,6 @@ target_link_libraries(libfastfetch
target_compile_options(libfastfetch PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti>)
if(WIN32)
set(CMAKE_CXX_STANDARD 20)
include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX("winrt/Windows.Foundation.h" HAVE_WINRT)
if(HAVE_WINRT)
add_library(ffwinrt MODULE src/detection/media/media_windows.dll.cpp)
target_link_libraries(ffwinrt PRIVATE "RuntimeObject")
target_compile_definitions(ffwinrt PRIVATE WIN32_LEAN_AND_MEAN=1 WINRT_LEAN_AND_MEAN=1)
target_link_options(ffwinrt
PRIVATE "-static" # stdc++, winpthread, gcc_s, etc.
)
endif()
set(CMAKE_CXX_STANDARD 17)
endif()
if(FreeBSD)
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
endif()
@@ -1856,12 +1996,6 @@ if(LINUX OR FreeBSD OR OpenBSD OR NetBSD)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
endif()
endif()
if(LINUX)
CHECK_INCLUDE_FILE("linux/wireless.h" HAVE_LINUX_WIRELESS)
if(HAVE_LINUX_WIRELESS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_WIRELESS=1)
endif()
endif()
if(NOT WIN32)
CHECK_INCLUDE_FILE("utmpx.h" HAVE_UTMPX)
if(HAVE_UTMPX)
@@ -1893,6 +2027,8 @@ if(NOT WIN32)
message(WARNING "pthread_timedjoin_np was not found; networking timeout will not work")
endif()
endif()
elseif(HAVE_WINRT)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WINRT=1)
endif()
set(PACKAGES_DISABLE_LIST "")
@@ -1909,7 +2045,10 @@ else()
list(TRANSFORM PACKAGES_DISABLE_LIST APPEND "_BIT")
list(JOIN PACKAGES_DISABLE_LIST " | " PACKAGES_DISABLE_LIST)
endif()
target_compile_definitions(libfastfetch PRIVATE FF_PACKAGES_DISABLE_LIST=${PACKAGES_DISABLE_LIST})
target_compile_definitions(libfastfetch PRIVATE "FF_PACKAGES_DISABLE_LIST=${PACKAGES_DISABLE_LIST}")
if(PACKAGES_REMOVE_DISABLED)
target_compile_definitions(libfastfetch PRIVATE FF_PACKAGES_REMOVE_DISABLED=1)
endif()
######################
# Executable targets #
@@ -2013,12 +2152,20 @@ if (BUILD_TESTS)
PRIVATE libfastfetch
)
add_executable(fastfetch-test-strutil
tests/strutil.c
)
target_link_libraries(fastfetch-test-strutil
PRIVATE libfastfetch
)
enable_testing()
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
add_test(NAME test-list COMMAND fastfetch-test-list)
add_test(NAME test-format COMMAND fastfetch-test-format)
add_test(NAME test-color COMMAND fastfetch-test-color)
add_test(NAME test-duration COMMAND fastfetch-test-duration)
add_test(NAME test-strutil COMMAND fastfetch-test-strutil)
endif()
##################
@@ -2039,13 +2186,6 @@ if (TARGET flashfetch)
)
endif()
if (TARGET ffwinrt)
install(
TARGETS ffwinrt
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
install(
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.bash"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions"
+18
View File
@@ -1,3 +1,21 @@
fastfetch (2.63.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.63.1
-- Carter Li <zhangsongcui@live.cn> Fri, 15 May 2026 09:31:54 +0800
fastfetch (2.63.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.63.0
-- Carter Li <zhangsongcui@live.cn> Wed, 13 May 2026 16:02:28 +0800
fastfetch (2.62.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.62.1
-- Carter Li <zhangsongcui@live.cn> Fri, 24 Apr 2026 15:45:15 +0800
fastfetch (2.62.0~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.62.0
+1 -1
View File
@@ -2,7 +2,7 @@ Source: fastfetch
Section: universe/utils
Priority: optional
Maintainer: Carter Li <zhangsongcui@live.cn>
Build-Depends: libelf-dev, libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build, python3-setuptools
Build-Depends: libelf-dev, libvulkan-dev, libwayland-dev, libxrandr-dev, libxcb-randr0-dev, libdconf-dev, libdbus-1-dev, libmagickcore-dev, libsqlite3-dev, librpm-dev, libegl-dev, libglx-dev, ocl-icd-opencl-dev, libpulse-dev, libdrm-dev, libddcutil-dev, libchafa-dev, libefl-all-dev, pkgconf, cmake (>= 3.12), debhelper (>= 11.2), dh-cmake, dh-cmake-compat (= 1), dh-sequence-cmake, dh-sequence-ctest, ninja-build, python3-setuptools
Standards-Version: 4.0.0
Homepage: https://github.com/fastfetch-cli/fastfetch
+89 -17
View File
@@ -313,6 +313,10 @@
"description": "Output format for the `Chassis` module. See Wiki for formatting syntax\n 1. {type}: Chassis type\n 2. {vendor}: Chassis vendor\n 3. {version}: Chassis version\n 4. {serial}: Chassis serial number",
"type": "string"
},
"codecFormat": {
"description": "Output format for the `Codec` module. See Wiki for formatting syntax\n 1. {gpu}: GPU name\n 2. {direction}: Decoder / Encoder\n 3. {types}: Compatibility alias of codec types\n 4. {platform-api}: Platform API used for detection",
"type": "string"
},
"commandFormat": {
"description": "Output format for the `Command` module. See Wiki for formatting syntax\n 1. {result}: Command result",
"type": "string"
@@ -334,7 +338,7 @@
"type": "string"
},
"datetimeFormat": {
"description": "Output format for the `DateTime` module. See Wiki for formatting syntax\n 1. {year}: Year\n 2. {year-short}: Last two digits of year\n 3. {month}: Month\n 4. {month-pretty}: Month with leading zero\n 5. {month-name}: Month name\n 6. {month-name-short}: Month name short\n 7. {week}: Week number on year\n 8. {weekday}: Weekday\n 9. {weekday-short}: Weekday short\n 10. {day-in-year}: Day in year\n 11. {day-in-month}: Day in month\n 12. {day-in-week}: Day in week\n 13. {hour}: Hour\n 14. {hour-pretty}: Hour with leading zero\n 15. {hour-12}: Hour 12h format\n 16. {hour-12-pretty}: Hour 12h format with leading zero\n 17. {minute}: Minute\n 18. {minute-pretty}: Minute with leading zero\n 19. {second}: Second\n 20. {second-pretty}: Second with leading zero\n 21. {offset-from-utc}: Offset from UTC in the ISO 8601 format\n 22. {timezone-name}: Locale-dependent timezone name or abbreviation\n 23. {day-pretty}: Day in month with leading zero",
"description": "Output format for the `DateTime` module. See Wiki for formatting syntax\n 1. {year}: Year\n 2. {year-short}: Last two digits of year\n 3. {month}: Month\n 4. {month-pretty}: Month with leading zero\n 5. {month-name}: Month name\n 6. {month-name-short}: Month name short\n 7. {week}: Week number on year\n 8. {weekday}: Weekday\n 9. {weekday-short}: Weekday short\n 10. {day-in-year}: Day in year\n 11. {day-in-month}: Day in month\n 12. {day-in-week}: Day in week\n 13. {hour}: Hour\n 14. {hour-pretty}: Hour with leading zero\n 15. {hour-12}: Hour 12h format\n 16. {hour-12-pretty}: Hour 12h format with leading zero\n 17. {minute}: Minute\n 18. {minute-pretty}: Minute with leading zero\n 19. {second}: Second\n 20. {second-pretty}: Second with leading zero\n 21. {offset-from-utc}: Offset from UTC in the ISO 8601 format\n 22. {timezone-name}: Locale-dependent timezone name or abbreviation\n 23. {day-pretty}: Day in month with leading zero\n 24. {am-pm}: AM or PM",
"type": "string"
},
"deFormat": {
@@ -410,7 +414,7 @@
"type": "string"
},
"mediaFormat": {
"description": "Output format for the `Media` module. See Wiki for formatting syntax\n 1. {combined}: Pretty media name\n 2. {title}: Media name\n 3. {artist}: Artist name\n 4. {album}: Album name\n 5. {status}: Status",
"description": "Output format for the `Media` module. See Wiki for formatting syntax\n 1. {combined}: Pretty media name\n 2. {title}: Media name\n 3. {artist}: Artist name\n 4. {album}: Album name\n 5. {status}: Status\n 6. {progress}: Progress in text\n 7. {progress-num}: Progress in percentage (number)\n 8. {progress-bar}: Progress in percentage (bar)\n 9. {player-name}: Player name\n 10. {player-id}: Player ID\n 11. {url}: URL",
"type": "string"
},
"memoryFormat": {
@@ -442,7 +446,7 @@
"type": "string"
},
"packagesFormat": {
"description": "Output format for the `Packages` module. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop-user}: Number of scoop-user packages\n 21. {scoop-global}: Number of scoop-global packages\n 22. {choco}: Number of choco packages\n 23. {pkgtool}: Number of pkgtool packages\n 24. {paludis}: Number of paludis packages\n 25. {winget}: Number of winget packages\n 26. {opkg}: Number of opkg packages\n 27. {am-system}: Number of am-system packages\n 28. {sorcery}: Number of sorcery packages\n 29. {lpkg}: Number of lpkg packages\n 30. {lpkgbuild}: Number of lpkgbuild packages\n 31. {guix-system}: Number of guix-system packages\n 32. {guix-user}: Number of guix-user packages\n 33. {guix-home}: Number of guix-home packages\n 34. {linglong}: Number of linglong packages\n 35. {pacstall}: Number of pacstall packages\n 36. {mport}: Number of mport packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {soar}: Number of soar packages\n 43. {kiss}: Number of kiss packages\n 44. {moss}: Number of moss packages\n 45. {nix-all}: Total number of all nix packages\n 46. {flatpak-all}: Total number of all flatpak app packages\n 47. {brew-all}: Total number of all brew packages\n 48. {guix-all}: Total number of all guix packages\n 49. {hpkg-all}: Total number of all hpkg packages",
"description": "Output format for the `Packages` module. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {am-system}: Number of am-system packages\n 3. {am-user}: Number of am-user (aka appman) packages\n 4. {appimage}: Number of appimage packages\n 5. {apk}: Number of apk packages\n 6. {brew}: Number of brew packages\n 7. {brew-all}: Total number of all brew packages\n 8. {brew-cask}: Number of brew-cask packages\n 9. {cards}: Number of cards packages\n 10. {choco}: Number of choco packages\n 11. {dpkg}: Number of dpkg packages\n 12. {emerge}: Number of emerge packages\n 13. {eopkg}: Number of eopkg packages\n 14. {flatpak-all}: Total number of all flatpak app packages\n 15. {flatpak-system}: Number of flatpak-system app packages\n 16. {flatpak-user}: Number of flatpak-user app packages\n 17. {guix-all}: Total number of all guix packages\n 18. {guix-home}: Number of guix-home packages\n 19. {guix-system}: Number of guix-system packages\n 20. {guix-user}: Number of guix-user packages\n 21. {hpkg-all}: Total number of all hpkg packages\n 22. {hpkg-system}: Number of hpkg-system packages\n 23. {hpkg-user}: Number of hpkg-user packages\n 24. {kiss}: Number of kiss packages\n 25. {linglong}: Number of linglong packages\n 26. {lpkg}: Number of lpkg packages\n 27. {lpkgbuild}: Number of lpkgbuild packages\n 28. {macports}: Number of macports packages\n 29. {mport}: Number of mport packages\n 30. {moss}: Number of moss packages\n 31. {nix-all}: Total number of all nix packages\n 32. {nix-default}: Number of nix-default packages\n 33. {nix-system}: Number of nix-system packages\n 34. {nix-user}: Number of nix-user packages\n 35. {opkg}: Number of opkg packages\n 36. {pacman}: Number of pacman packages\n 37. {pacman-branch}: Pacman branch on manjaro\n 38. {pacstall}: Number of pacstall packages\n 39. {paludis}: Number of paludis packages\n 40. {pisi}: Number of pisi packages\n 41. {pkg}: Number of pkg packages\n 42. {pkgsrc}: Number of pkgsrc packages\n 43. {pkgtool}: Number of pkgtool packages\n 44. {rpm}: Number of rpm packages\n 45. {scoop-global}: Number of scoop-global packages\n 46. {scoop-user}: Number of scoop-user packages\n 47. {snap}: Number of snap packages\n 48. {soar}: Number of soar packages\n 49. {sorcery}: Number of sorcery packages\n 50. {winget}: Number of winget packages\n 51. {xbps}: Number of xbps packages",
"type": "string"
},
"physicaldiskFormat": {
@@ -731,6 +735,11 @@
"description": "Top padding of the logo",
"minimum": 0
},
"bottom": {
"type": "integer",
"description": "Bottom padding of the logo; only supported when position is `top`",
"minimum": 0
},
"left": {
"type": "integer",
"description": "Left padding of the logo",
@@ -898,11 +907,6 @@
],
"default": false
},
"wmiTimeout": {
"type": "integer",
"description": "Set the timeout (ms) for WMI queries, `-1` for no timeout. Windows only",
"default": 5000
},
"processingTimeout": {
"type": "integer",
"description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
@@ -1445,6 +1449,7 @@
"cpu",
"cpucache",
"cpuusage",
"codec",
"command",
"colors",
"cursor",
@@ -1540,11 +1545,6 @@
"const": "battery",
"description": "Print battery information"
},
"useSetupApi": {
"description": "Whether to use the `CM API` on Windows to detect battery information. Supports multiple batteries, but is slower (Windows only)",
"type": "boolean",
"default": false
},
"temp": {
"$ref": "#/$defs/temperature"
},
@@ -1755,10 +1755,18 @@
"$ref": "#/$defs/percent"
},
"ddcciSleep": {
"type": "integer",
"description": "Sleep time in milliseconds between DDC/CI requests\nSee <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for details",
"minimum": 0,
"maximum": 400,
"description": "Sleep time in milliseconds between DDC/CI requests\nSet to null to skip DDC/CI detection\nSee <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for details",
"oneOf": [
{
"type": "null",
"description": "Skip DDC/CI detection"
},
{
"type": "integer",
"minimum": 0,
"maximum": 400
}
],
"default": 10
},
"compact": {
@@ -1888,6 +1896,67 @@
}
}
},
{
"title": "Codec",
"type": "object",
"additionalProperties": false,
"properties": {
"type": {
"const": "codec",
"description": "Print hardware video acceleration codec types (decode / encode)"
},
"splitGPU": {
"description": "Whether to print each GPU separately. If false, merge codecs from all GPUs",
"type": "boolean",
"default": false
},
"useVulkan": {
"description": "Whether to use Vulkan for codec detection instead of other platform-specific APIs",
"type": "boolean",
"default": false
},
"showType": {
"description": "Which types of codecs to detect and show",
"type": "string",
"oneOf": [
{
"const": "both",
"description": "Show both decoders and encoders"
},
{
"const": "decoder",
"description": "Show only decoders"
},
{
"const": "encoder",
"description": "Show only encoders"
}
],
"default": "both"
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/codecFormat"
},
"condition": {
"$ref": "#/$defs/conditions"
}
}
},
{
"title": "CPU",
"type": "object",
@@ -3259,6 +3328,9 @@
"const": "media",
"description": "Print the name of the currently playing song"
},
"percent": {
"$ref": "#/$defs/percent"
},
"key": {
"$ref": "#/$defs/key"
},
+4
View File
@@ -50,6 +50,10 @@
"driverSpecific": true,
"temp": true
},
{
"type": "codec",
"splitGPU": true
},
"memory",
"physicalmemory",
{
+4
View File
@@ -52,6 +52,10 @@
"driverSpecific": true,
"temp": true
},
{
"type": "codec",
"splitGPU": true
},
"memory",
"physicalmemory",
{
-3
View File
@@ -1,6 +1,3 @@
// Load with --config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
-3
View File
@@ -1,6 +1,3 @@
// Load with --config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"display": {
-3
View File
@@ -1,6 +1,3 @@
// Load with --config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -33,7 +33,7 @@ endBold = r"\fR" # end bold text tag
# path to the current directory
pathToCurrentDir = path.dirname(__file__)
# path to the JSON option file
pathToHelpFile = path.join(pathToCurrentDir, "../src/data/help.json")
pathToHelpFile = path.join(pathToCurrentDir, "../doc/help.json")
# man page section
manSection = 1
# title (center header)
+141 -88
View File
@@ -21,7 +21,7 @@
// SOFTWARE.
/// \file adl_defines.h
/// \brief Contains all definitions exposed by ADL for \ALL platforms.\n <b>Included in ADL SDK</b>
/// \brief Contains all definitions exposed by ADL for \WIN platforms.\n <b>Included in ADL SDK</b>
///
/// This file contains all definitions used by ADL.
/// The ADL definitions include the following:
@@ -61,6 +61,8 @@
#define ADL_ADAPTER_INDEX_ALL -1
/// Defines APIs with iOption none
#define ADL_MAIN_API_OPTION_NONE 0
/// Defines the maximum of RPC endpoint
#define ADL_MAX_RPC_ENDPOINT 32
/// @}
/// \name Definitions for iOption parameter used by
@@ -141,6 +143,12 @@
#define ADL_ERR_FEATURESYNC_NOT_STARTED -24
/// Adapter is in an invalid power state
#define ADL_ERR_INVALID_POWER_STATE -25
/// The RPC server is in busy state
#define ADL_ERR_SERVER_BUSY -26
/// The GPU is occupied by application which cannot be powered off
#define ADL_ERR_GPU_IN_USE -27
/// The general RPC connection error
#define ADL_ERR_RPC -28
/// @}
/// </A>
@@ -380,6 +388,7 @@
#define ADL_BUSTYPE_PCIE_GEN2 3 /* PCI Express 2nd generation bus */
#define ADL_BUSTYPE_PCIE_GEN3 4 /* PCI Express 3rd generation bus */
#define ADL_BUSTYPE_PCIE_GEN4 5 /* PCI Express 4th generation bus */
#define ADL_BUSTYPE_PCIE_GEN5 6 /* PCI Express 5th generation bus */
/// @}
/// \defgroup define_ws_caps Workstation Capabilities
@@ -872,7 +881,7 @@
typedef enum ADLThreadingModel
{
ADL_THREADING_UNLOCKED = 0, /*!< Default behavior. ADL will not enforce serialization of ADL API executions by multiple threads. Multiple threads will be allowed to enter to ADL at the same time. Note that ADL library is not guaranteed to be thread-safe. Client that calls ADL_Main_Control_Create have to provide its own mechanism for ADL calls serialization. */
ADL_THREADING_LOCKED /*!< ADL will enforce serialization of ADL API when called by multiple threads. Only single thread will be allowed to enter ADL API at the time. This option makes ADL calls thread-safe. You shouldn't use this option if ADL calls will be executed on Linux on x-server rendering thread. It can cause the application to hung. */
ADL_THREADING_LOCKED /*!< ADL will enforce serialization of ADL API when called by multiple threads. Only single thread will be allowed to enter ADL API at the time. This option makes ADL calls thread-safe. */
}ADLThreadingModel;
/// @}
@@ -1844,12 +1853,12 @@ enum ADLOD8FeatureControl
ADL_OD8_TEMPERATURE_FAN = 1 << 6, //FanTargetTemperature
ADL_OD8_TEMPERATURE_SYSTEM = 1 << 7, //MaxOpTemp
ADL_OD8_MEMORY_TIMING_TUNE = 1 << 8,
ADL_OD8_FAN_ZERO_RPM_CONTROL = 1 << 9 ,
ADL_OD8_AUTO_UV_ENGINE = 1 << 10, //Auto under voltage
ADL_OD8_AUTO_OC_ENGINE = 1 << 11, //Auto overclock engine
ADL_OD8_AUTO_OC_MEMORY = 1 << 12, //Auto overclock memory
ADL_OD8_FAN_CURVE = 1 << 13, //Fan curve
ADL_OD8_WS_AUTO_FAN_ACOUSTIC_LIMIT = 1 << 14, //Workstation Manual Fan controller
ADL_OD8_FAN_ZERO_RPM_CONTROL = 1 << 9,
ADL_OD8_AUTO_UV_ENGINE = 1 << 10, //Auto under voltage
ADL_OD8_AUTO_OC_ENGINE = 1 << 11, //Auto overclock engine
ADL_OD8_AUTO_OC_MEMORY = 1 << 12, //Auto overclock memory
ADL_OD8_FAN_CURVE = 1 << 13, //Fan curve
ADL_OD8_WS_AUTO_FAN_ACOUSTIC_LIMIT = 1 << 14, //Workstation Manual Fan controller
ADL_OD8_GFXCLK_QUADRATIC_CURVE = 1 << 15,
ADL_OD8_OPTIMIZED_GPU_POWER_MODE = 1 << 16,
ADL_OD8_ODVOLTAGE_LIMIT = 1 << 17,
@@ -1860,43 +1869,45 @@ enum ADLOD8FeatureControl
ADL_OD8_TDC_LIMIT = 1 << 22, //TDC slider
ADL_OD8_FULL_CONTROL_MODE = 1 << 23, //Full control
ADL_OD8_POWER_SAVING_FEATURE_CONTROL = 1 << 24, //Power saving feature control
ADL_OD8_POWER_GAUGE = 1 << 25 //Power Gauge
ADL_OD8_ACTIMING_PARAMETERS_TUNE = 1 << 25, // AC Timing Parameters Tuning
ADL_OD8_OVERDRIVE_INTERFACE = 1 << 26, // Version info feature ID for RSX, do not expose in ADL.
ADL_OD8_AUTO_UV_ENGINE_V2 = 1 << 27, // Auto UV 2.0 with actual stress testing.
ADL_OD8_POWER_GAUGE = 1 << 28 //Power Gauge
};
typedef enum ADLOD8SettingId
{
OD8_GFXCLK_FMAX = 0,
OD8_GFXCLK_FMIN,
OD8_GFXCLK_FREQ1,
OD8_GFXCLK_VOLTAGE1,
OD8_GFXCLK_FREQ2,
OD8_GFXCLK_VOLTAGE2,
OD8_GFXCLK_FREQ3,
OD8_GFXCLK_VOLTAGE3,
OD8_UCLK_FMAX,
OD8_POWER_PERCENTAGE,
OD8_FAN_MIN_SPEED,
OD8_FAN_ACOUSTIC_LIMIT,
OD8_FAN_TARGET_TEMP,
OD8_OPERATING_TEMP_MAX,
OD8_AC_TIMING,
OD8_FAN_ZERORPM_CONTROL,
OD8_AUTO_UV_ENGINE_CONTROL,
OD8_AUTO_OC_ENGINE_CONTROL,
OD8_AUTO_OC_MEMORY_CONTROL,
OD8_FAN_CURVE_TEMPERATURE_1,
OD8_FAN_CURVE_SPEED_1,
OD8_FAN_CURVE_TEMPERATURE_2,
OD8_FAN_CURVE_SPEED_2,
OD8_FAN_CURVE_TEMPERATURE_3,
OD8_FAN_CURVE_SPEED_3,
OD8_FAN_CURVE_TEMPERATURE_4,
OD8_FAN_CURVE_SPEED_4,
OD8_FAN_CURVE_TEMPERATURE_5,
OD8_FAN_CURVE_SPEED_5,
OD8_WS_FAN_AUTO_FAN_ACOUSTIC_LIMIT,
OD8_GFXCLK_CURVE_COEFFICIENT_A, // As part of the agreement with UI team, the min/max voltage limits for the
OD8_GFXCLK_FMAX = 0,
OD8_GFXCLK_FMIN,
OD8_GFXCLK_FREQ1,
OD8_GFXCLK_VOLTAGE1,
OD8_GFXCLK_FREQ2,
OD8_GFXCLK_VOLTAGE2,
OD8_GFXCLK_FREQ3,
OD8_GFXCLK_VOLTAGE3,
OD8_UCLK_FMAX,
OD8_POWER_PERCENTAGE,
OD8_FAN_MIN_SPEED, //10
OD8_FAN_ACOUSTIC_LIMIT,
OD8_FAN_TARGET_TEMP,
OD8_OPERATING_TEMP_MAX,
OD8_AC_TIMING,
OD8_FAN_ZERORPM_CONTROL,
OD8_AUTO_UV_ENGINE_CONTROL,
OD8_AUTO_OC_ENGINE_CONTROL,
OD8_AUTO_OC_MEMORY_CONTROL,
OD8_FAN_CURVE_TEMPERATURE_1,
OD8_FAN_CURVE_SPEED_1, //20
OD8_FAN_CURVE_TEMPERATURE_2,
OD8_FAN_CURVE_SPEED_2,
OD8_FAN_CURVE_TEMPERATURE_3,
OD8_FAN_CURVE_SPEED_3,
OD8_FAN_CURVE_TEMPERATURE_4,
OD8_FAN_CURVE_SPEED_4,
OD8_FAN_CURVE_TEMPERATURE_5,
OD8_FAN_CURVE_SPEED_5,
OD8_WS_FAN_AUTO_FAN_ACOUSTIC_LIMIT,
OD8_GFXCLK_CURVE_COEFFICIENT_A, // 30 As part of the agreement with UI team, the min/max voltage limits for the
OD8_GFXCLK_CURVE_COEFFICIENT_B, // quadratic curve graph will be stored in the min and max limits of
OD8_GFXCLK_CURVE_COEFFICIENT_C, // coefficient a, b and c. A, b and c themselves do not have limits.
OD8_GFXCLK_CURVE_VFT_FMIN,
@@ -1906,7 +1917,7 @@ typedef enum ADLOD8SettingId
OD8_OD_VOLTAGE,// RSX - voltage offset feature
OD8_ADV_OC_LIMITS_SETTING,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_1,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_2,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_2, //40
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_3,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_4,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_POINT_5,
@@ -1915,8 +1926,33 @@ typedef enum ADLOD8SettingId
OD8_GFX_VOLTAGE_LIMIT_SETTING,
OD8_TDC_PERCENTAGE,
OD8_FULL_CONTROL_MODE_SETTING,
OD8_FULL_CONTROL_MODE_GFXCLK,
OD8_FULL_CONTROL_MODE_UCLK, // 50,
OD8_IDLE_POWER_SAVING_FEATURE_CONTROL,
OD8_RUNTIME_POWER_SAVING_FEATURE_CONTROL,
OD8_FULL_CONTROL_MODE_FEATURE_CONTROL,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_FREQ_ANCHOR_1,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_FREQ_ANCHOR_2,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_FREQ_ANCHOR_3,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_FREQ_ANCHOR_4,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_FREQ_ANCHOR_5,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_FREQ_ANCHOR_6,
OD8_PER_ZONE_GFX_VOLTAGE_OFFSET_VOLTAGE_LIMIT, //60
OD8_ACTIMING_PARAMETER_TRRDS,
OD8_ACTIMING_PARAMETER_TCL,
OD8_ACTIMING_PARAMETER_TCWL,
OD8_ACTIMING_PARAMETER_TRCDRD,
OD8_ACTIMING_PARAMETER_TRCDWR,
OD8_ACTIMING_PARAMETER_TRAS,
OD8_ACTIMING_PARAMETER_TRPAB,
OD8_ACTIMING_PARAMETER_TRFC,
OD8_ACTIMING_PARAMETER_TRFCPB,
OD8_ACTIMING_PARAMETER_TRREFD, //70
OD8_ACTIMING_PARAMETER_TREF,
OD8_ACTIMING_PARAMETER_TWR,
OD8_ACTIMING_PARAMETER_TWTRS,
OD8_OVERDRIVE_INTERFACE_ID, //74
OD8_AUTO_UV_ENGINE_V2_ID, //75
OD8_POWER_GAUGE,
OD8_COUNT
} ADLOD8SettingId;
@@ -1980,28 +2016,28 @@ typedef enum ADLSensorType
PMLOG_SSDGPU_POWERLIMIT = 49, // DGPU Power limit
PMLOG_TEMPERATURE_HOTSPOT_GCD = 50,
PMLOG_TEMPERATURE_HOTSPOT_MCD = 51,
PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE = 52,
PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE = 53,
PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE = 54,
PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE = 55,
PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE = 56,
PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE = 57,
PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE = 58,
PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE = 59,
PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE = 60,
PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE = 61,
PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE = 62,
PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE = 63,
PMLOG_THROTTLER_TDC_GFX_PERCENTAGE = 64,
PMLOG_THROTTLER_TDC_SOC_PERCENTAGE = 65,
PMLOG_THROTTLER_TDC_USR_PERCENTAGE = 66,
PMLOG_THROTTLER_PPT0_PERCENTAGE = 67,
PMLOG_THROTTLER_PPT1_PERCENTAGE = 68,
PMLOG_THROTTLER_PPT2_PERCENTAGE = 69,
PMLOG_THROTTLER_PPT3_PERCENTAGE = 70,
PMLOG_THROTTLER_FIT_PERCENTAGE = 71,
PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE = 72,
PMLOG_BOARD_POWER = 73,
PMLOG_THROTTLE_PERCENTAGE_TEMP_GFX = 52,
PMLOG_THROTTLE_PERCENTAGE_TEMP_MEM = 53,
PMLOG_THROTTLE_PERCENTAGE_TEMP_VR = 54,
PMLOG_THROTTLE_PERCENTAGE_POWER = 55,
PMLOG_THROTTLE_PERCENTAGE_TDC = 56,
PMLOG_THROTTLE_PERCENTAGE_VMAX = 57,
PMLOG_BUS_CURR_MAX_SPEED = 58,
PMLOG_RESERVED_1 = 59, //Currently Unused
PMLOG_RESERVED_2 = 60, //Currently Unused
PMLOG_RESERVED_3 = 61, //Currently Unused
PMLOG_RESERVED_4 = 62, //Currently Unused
PMLOG_RESERVED_5 = 63, //Currently Unused
PMLOG_RESERVED_6 = 64, //Currently Unused
PMLOG_RESERVED_7 = 65, //Currently Unused
PMLOG_RESERVED_8 = 66, //Currently Unused
PMLOG_RESERVED_9 = 67, //Currently Unused
PMLOG_RESERVED_10 = 68, //Currently Unused
PMLOG_RESERVED_11 = 69, //Currently Unused
PMLOG_RESERVED_12 = 70, //Currently Unused
PMLOG_RESERVED_13 = 71, //Currently Unused
PMLOG_RESERVED_14 = 72,
PMLOG_BOARD_POWER = 73,
PMLOG_MAX_SENSORS_REAL
} ADLSensorType;
@@ -2068,28 +2104,29 @@ typedef enum ADL_PMLOG_SENSORS
ADL_PMLOG_SSDGPU_POWERLIMIT = 49, // DGPU Power limit
ADL_PMLOG_TEMPERATURE_HOTSPOT_GCD = 50,
ADL_PMLOG_TEMPERATURE_HOTSPOT_MCD = 51,
ADL_PMLOG_THROTTLER_TEMP_EDGE_PERCENTAGE = 52,
ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_PERCENTAGE = 53,
ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_GCD_PERCENTAGE = 54,
ADL_PMLOG_THROTTLER_TEMP_HOTSPOT_MCD_PERCENTAGE = 55,
ADL_PMLOG_THROTTLER_TEMP_MEM_PERCENTAGE = 56,
ADL_PMLOG_THROTTLER_TEMP_VR_GFX_PERCENTAGE = 57,
ADL_PMLOG_THROTTLER_TEMP_VR_MEM0_PERCENTAGE = 58,
ADL_PMLOG_THROTTLER_TEMP_VR_MEM1_PERCENTAGE = 59,
ADL_PMLOG_THROTTLER_TEMP_VR_SOC_PERCENTAGE = 60,
ADL_PMLOG_THROTTLER_TEMP_LIQUID0_PERCENTAGE = 61,
ADL_PMLOG_THROTTLER_TEMP_LIQUID1_PERCENTAGE = 62,
ADL_PMLOG_THROTTLER_TEMP_PLX_PERCENTAGE = 63,
ADL_PMLOG_THROTTLER_TDC_GFX_PERCENTAGE = 64,
ADL_PMLOG_THROTTLER_TDC_SOC_PERCENTAGE = 65,
ADL_PMLOG_THROTTLER_TDC_USR_PERCENTAGE = 66,
ADL_PMLOG_THROTTLER_PPT0_PERCENTAGE = 67,
ADL_PMLOG_THROTTLER_PPT1_PERCENTAGE = 68,
ADL_PMLOG_THROTTLER_PPT2_PERCENTAGE = 69,
ADL_PMLOG_THROTTLER_PPT3_PERCENTAGE = 70,
ADL_PMLOG_THROTTLER_FIT_PERCENTAGE = 71,
ADL_PMLOG_THROTTLER_GFX_APCC_PLUS_PERCENTAGE = 72,
ADL_PMLOG_BOARD_POWER = 73,
ADL_PMLOG_THROTTLE_PERCENTAGE_TEMP_GFX = 52,
ADL_PMLOG_THROTTLE_PERCENTAGE_TEMP_MEM = 53,
ADL_PMLOG_THROTTLE_PERCENTAGE_TEMP_VR = 54,
ADL_PMLOG_THROTTLE_PERCENTAGE_POWER = 55,
ADL_PMLOG_THROTTLE_PERCENTAGE_TDC = 56,
ADL_PMLOG_THROTTLE_PERCENTAGE_VMAX = 57,
ADL_PMLOG_BUS_CURR_MAX_SPEED = 58,
ADL_PMLOG_RESERVED_1 = 59, //Currently Unused
ADL_PMLOG_RESERVED_2 = 60, //Currently Unused
ADL_PMLOG_RESERVED_3 = 61, //Currently Unused
ADL_PMLOG_RESERVED_4 = 62, //Currently Unused
ADL_PMLOG_RESERVED_5 = 63, //Currently Unused
ADL_PMLOG_RESERVED_6 = 64, //Currently Unused
ADL_PMLOG_RESERVED_7 = 65, //Currently Unused
ADL_PMLOG_RESERVED_8 = 66, //Currently Unused
ADL_PMLOG_RESERVED_9 = 67, //Currently Unused
ADL_PMLOG_RESERVED_10 = 68, //Currently Unused
ADL_PMLOG_RESERVED_11 = 69, //Currently Unused
ADL_PMLOG_RESERVED_12 = 70, //Currently Unused
ADL_PMLOG_CLK_NPUCLK = 71, //NPU frequency
ADL_PMLOG_NPU_BUSY_AVG = 72, //NPU busy
ADL_PMLOG_BOARD_POWER = 73,
ADL_PMLOG_TEMPERATURE_INTAKE = 74,
ADL_PMLOG_MAX_SENSORS_REAL
} ADL_PMLOG_SENSORS;
@@ -2393,6 +2430,9 @@ typedef enum ADL_PMLOG_SENSORS
/// Indicates there is crossGPU clone
#define ADL_CROSSGPUDISPLAYCLONE 0x2
/// @}
/// @}
/// \defgroup define_D3DKMT_HANDLE
@@ -2493,7 +2533,11 @@ typedef enum ADL_UIFEATURES_GROUP
ADL_UIFEATURES_GROUP_PROVSR = 12,
ADL_UIFEATURES_GROUP_SMA = 13,
ADL_UIFEATURES_GROUP_CAMERA = 14,
ADL_UIFEATURES_GROUP_FRTCPRO = 15
ADL_UIFEATURES_GROUP_FRTCPRO = 15,
ADL_UIFEATURES_GROUP_DELAGNEXT = 16,
ADL_UIFEATURES_GROUP_RTBOOST = 17,
ADL_UIFEATURES_GROUP_UAI = 18
} ADL_UIFEATURES_GROUP;
@@ -2587,9 +2631,18 @@ typedef enum ADL_USER_SETTINGS
ADL_USER_SETTINGS_USU_PROFILE = 1 << 4, //notify USU settings change
ADL_USER_SETTINGS_CVDC_PROFILE = 1 << 5, //notify Color Vision Deficiency Corretion settings change
ADL_USER_SETTINGS_SCE_PROFILE = 1 << 6,
ADL_USER_SETTINGS_PROVSR = 1 << 7
ADL_USER_SETTINGS_PROVSR = 1 << 7,
ADL_USER_SETTINGS_RTBOOST_PROFILE=1 << 8,
ADL_USER_SETTINGS_USU2_PROFILE = 1 << 9, //notify USU2 settings change
} ADL_USER_SETTINGS;
//FRAME_TIMESTAMPS_SHARED_MEMORY type
typedef enum FRAME_TIMESTAMPS_SHARED_MEMORY_TYPE
{
FRAME_TIMESTAMPS_SHARED_MEMORY_TYPE_UNKNOWN = 0,
FRAME_TIMESTAMPS_SHARED_MEMORY_TYPE_LEGACY,
FRAME_TIMESTAMPS_SHARED_MEMORY_TYPE_INDEXED
}FRAME_TIMESTAMPS_SHARED_MEMORY_TYPE;
#define ADL_REG_DEVICE_FUNCTION_1 0x00000001
#endif /* ADL_DEFINES_H_ */
+2 -6
View File
@@ -33,14 +33,10 @@
#include "adl_structures.h"
#if defined (LINUX)
#define __stdcall
#endif /* (LINUX) */
/// Memory Allocation Call back
typedef void* ( __stdcall *ADL_MAIN_MALLOC_CALLBACK )( int );
#define ADL_SDK_MAJOR_VERSION 17
#define ADL_SDK_MINOR_VERSION 1
#define ADL_SDK_MAJOR_VERSION 18
#define ADL_SDK_MINOR_VERSION 0
#endif /* ADL_SDK_H_ */
+29 -36
View File
@@ -21,7 +21,7 @@
// SOFTWARE.
/// \file adl_structures.h
///\brief This file contains the structure declarations that are used by the public ADL interfaces for \ALL platforms.\n <b>Included in ADL SDK</b>
///\brief This file contains the structure declarations that are used by the public ADL interfaces for \WIN platforms.\n <b>Included in ADL SDK</b>
///
/// All data structures used in AMD Display Library (ADL) public interfaces should be defined in this header file.
///
@@ -41,7 +41,7 @@
////////////////////////////////////////////////////////////////////////////////////////////
typedef struct AdapterInfo
{
/// \ALL_STRUCT_MEM
/// \WIN_STRUCT_MEM
/// Size of the structure.
int iSize;
@@ -59,7 +59,7 @@ typedef struct AdapterInfo
int iVendorID;
/// Adapter name.
char strAdapterName[ADL_MAX_PATH];
/// Display name. For example, "\\\\Display0" for Windows or ":0:0" for Linux.
/// Display name. For example, "\\\\Display0" for Windows.
char strDisplayName[ADL_MAX_PATH];
/// Present or not; 1 if present and 0 if not present.It the logical adapter is present, the display name such as \\\\.\\Display1 can be found from OS
int iPresent;
@@ -80,38 +80,8 @@ typedef struct AdapterInfo
#endif /* (_WIN32) || (_WIN64) */
#if defined (LINUX)
/// \LNX_STRUCT_MEM
/// Internal X screen number from GPUMapInfo (DEPRICATED use XScreenInfo)
int iXScreenNum;
/// Internal driver index from GPUMapInfo
int iDrvIndex;
/// \deprecated Internal x config file screen identifier name. Use XScreenInfo instead.
char strXScreenConfigName[ADL_MAX_PATH];
#endif /* (LINUX) */
} AdapterInfo, *LPAdapterInfo;
/////////////////////////////////////////////////////////////////////////////////////////////
///\brief Structure containing information about the Linux X screen information.
///
/// This structure is used to store the current screen number and xorg.conf ID name assoicated with an adapter index.
/// This structure is updated during ADL_Main_Control_Refresh or ADL_ScreenInfo_Update.
/// Note: This structure should be used in place of iXScreenNum and strXScreenConfigName in AdapterInfo as they will be
/// deprecated.
/// \nosubgrouping
////////////////////////////////////////////////////////////////////////////////////////////
#if defined (LINUX)
typedef struct XScreenInfo
{
/// Internal X screen number from GPUMapInfo.
int iXScreenNum;
/// Internal x config file screen identifier name.
char strXScreenConfigName[ADL_MAX_PATH];
} XScreenInfo, *LPXScreenInfo;
#endif /* (LINUX) */
/////////////////////////////////////////////////////////////////////////////////////////////
///\brief Structure containing information about an controller mode
///
@@ -453,8 +423,12 @@ typedef struct ADLDDCInfo2
int ulMaxBacklightMinLuminanceData;
int ulMinBacklightMinLuminanceData;
// Display screen width/height
int ulScreenWidth;
int ulScreenHeight;
// Reserved for future use
int iReserved[4];
int iReserved[2];
} ADLDDCInfo2, *LPADLDDCInfo2;
/////////////////////////////////////////////////////////////////////////////////////////////
@@ -3614,6 +3588,23 @@ typedef struct ADL_BOOST_SETTINGS
int GlobalMinRes_Step; //Gloabl Min Resolution step value
}ADL_BOOST_SETTINGS;
/////////////////////////////////////////////////////////////////////////////////////////////
///\brief Structure containing information about BOOST Settings
///
/// Elements of BOOST settings.
/// \nosubgrouping
////////////////////////////////////////////////////////////////////////////////////////////
typedef struct ADL_BOOST_SETTINGSX2
{
int Hotkey; // Hotkey value
int GlobalEnable; //Global enable value
int GlobalMinRes; //Gloabl Min Resolution value
int GlobalMinRes_MinLimit; //Gloabl Min Resolution slider min limit value
int GlobalMinRes_MaxLimit; //Gloabl Min Resolution slider max limit value
int GlobalMinRes_Step; //Gloabl Min Resolution step value
int VsrSupported; //Allows for interop with Upscaling/RSR
}ADL_BOOST_SETTINGSX2;
/////////////////////////////////////////////////////////////////////////////////////////////
///\brief Structure containing information about ProVSR Settings change reason
@@ -3817,7 +3808,7 @@ typedef struct ADL_RADEON_LED_PATTERN_CONFIG
////////////////////////////////////////////////////////////////////////////////////////////
typedef struct AdapterInfoX2
{
/// \ALL_STRUCT_MEM
/// \WIN_STRUCT_MEM
/// Size of the structure.
int iSize;
@@ -4164,6 +4155,7 @@ typedef struct ADLHDCPSettings
///
/// This structure is used to store the Mantle Driver information
/// \nosubgrouping
/// \deprecated This structure has been deprecated.
////////////////////////////////////////////////////////////////////////////////////////////
typedef struct ADLMantleAppInfo
@@ -4286,4 +4278,5 @@ typedef struct ADLSmartShiftSettings
int iCurrentValue;
int iFlags; //refer to define_smartshift_bits
}ADLSmartShiftSettings, *LPADLSmartShiftSettings;
#endif /* ADL_STRUCTURES_H_ */
#endif /* ADL_STRUCTURES_H_ */
+1 -1
View File
@@ -1,6 +1,6 @@
{
"home": "https://github.com/GPUOpen-LibrariesAndSDKs/display-library",
"license": "MIT (embeded in source)",
"version": "ADL SDK 17.1",
"version": "ADL SDK 18.1",
"author": "Advanced Micro Devices, Inc"
}
+2 -2
View File
@@ -18,9 +18,9 @@ typedef struct FFlist {
void* ffListAdd(FFlist* list, uint32_t elementSize);
// Removes the first element, and copy its value to `*result`
bool ffListShift(FFlist* list, uint32_t elementSize, void* result);
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result);
// Removes the last element, and copy its value to `*result`
bool ffListPop(FFlist* list, uint32_t elementSize, void* result);
bool ffListPop(FFlist* list, uint32_t elementSize, void* __restrict result);
static inline void ffListInit(FFlist* list) {
list->capacity = 0;
+22 -5
View File
@@ -9,6 +9,7 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "common/memrchr.h"
#ifdef FF_USE_SYSTEM_YYJSON
#include <yyjson.h>
@@ -71,11 +72,6 @@ bool ffStrbufRemoveSubstr(FFstrbuf* strbuf, uint32_t startIndex, uint32_t endInd
void ffStrbufRemoveS(FFstrbuf* strbuf, const char* str);
void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* strings[]);
FF_A_NODISCARD uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
FF_A_NODISCARD uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str);
FF_A_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c);
void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace);
// Returns true if the strbuf is modified
@@ -417,6 +413,27 @@ static inline FF_A_NODISCARD bool ffStrbufContainIgnCase(const FFstrbuf* strbuf,
return ffStrbufContainIgnCaseS(strbuf, str->chars);
}
FF_A_NODISCARD static inline uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
assert(start <= strbuf->length);
const char* ptr = (const char*) memchr(strbuf->chars + start, c, strbuf->length - start);
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
}
FF_A_NODISCARD static inline uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str) {
assert(start <= strbuf->length);
const char* ptr = strstr(strbuf->chars + start, str);
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
}
FF_A_NODISCARD static inline uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
assert(start <= strbuf->length);
const char* ptr = (const char*) memrchr(strbuf->chars, c, start + 1);
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
}
static inline FF_A_NODISCARD uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c) {
return ffStrbufNextIndexC(strbuf, 0, c);
}
+44 -3
View File
@@ -24,16 +24,39 @@ const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result) {
}
return NULL;
} else if (CFGetTypeID(cf) == CFDataGetTypeID()) {
if (CFDataGetLength((CFDataRef) cf) != sizeof(int)) {
return "Data length is not sizeof(int)";
if (CFDataGetLength((CFDataRef) cf) != sizeof(*result)) {
return "Data length is not sizeof(int32_t)";
}
CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(int)), (uint8_t*) result);
CFDataGetBytes((CFDataRef) cf, CFRangeMake(0, sizeof(*result)), (uint8_t*) result);
return NULL;
}
return "TypeID is neither 'CFNumber' nor 'CFData'";
}
const char* ffCfNumGetDouble(CFTypeRef cf, double* result) {
if (CFGetTypeID(cf) == CFNumberGetTypeID()) {
if (!CFNumberGetValue((CFNumberRef) cf, kCFNumberDoubleType, result) &&
!CFNumberGetValue((CFNumberRef) cf, kCFNumberFloatType, result)) {
return "Number type is not Double or Float";
}
return NULL;
}
return "TypeID is neither 'CFNumber'";
}
const char* ffCfDateGetEpoch(CFTypeRef cf, uint64_t* result) {
if (CFGetTypeID(cf) != CFDateGetTypeID()) {
return "TypeID is not 'CFDate'";
}
CFAbsoluteTime absTime = CFDateGetAbsoluteTime((CFDateRef) cf);
// Convert from seconds to milliseconds and add the difference between 1970 and 2001 in milliseconds
*result = (uint64_t) ((absTime + 978307200 /*kCFAbsoluteTimeIntervalSince1970*/) * 1000);
return NULL;
}
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result) {
ffStrbufClear(result);
if (!cf) {
@@ -149,6 +172,15 @@ const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* res
return ffCfNumGetInt64(cf, result);
}
const char* ffCfDictGetDouble(CFDictionaryRef dict, CFStringRef key, double* result) {
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
if (cf == NULL) {
return "CFDictionaryGetValue() failed";
}
return ffCfNumGetDouble(cf, result);
}
const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length) {
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
if (cf == NULL) {
@@ -182,3 +214,12 @@ const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryR
*result = cf;
return NULL;
}
const char* ffCfDictGetDateAsEpoch(CFDictionaryRef dict, CFStringRef key, uint64_t* result) {
CFTypeRef cf = (CFTypeRef) CFDictionaryGetValue(dict, key);
if (cf == NULL) {
return "CFDictionaryGetValue() failed";
}
return ffCfDateGetEpoch(cf, result);
}
+4
View File
@@ -8,14 +8,18 @@
const char* ffCfStrGetString(CFTypeRef cf, FFstrbuf* result);
const char* ffCfNumGetInt(CFTypeRef cf, int32_t* result);
const char* ffCfNumGetInt64(CFTypeRef cf, int64_t* result);
const char* ffCfNumGetDouble(CFTypeRef cf, double* result);
const char* ffCfDateGetEpoch(CFTypeRef cf, uint64_t* result);
const char* ffCfDataGetDataAsString(CFTypeRef cf, FFstrbuf* result);
const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result);
const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result);
const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result);
const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result);
const char* ffCfDictGetDouble(CFDictionaryRef dict, CFStringRef key, double* result);
const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length);
const char* ffCfDictGetDataAsString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result);
const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result);
const char* ffCfDictGetDateAsEpoch(CFDictionaryRef dict, CFStringRef key, uint64_t* result);
static inline CFNumberRef ffCfCreateInt(int value) {
return CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value);
-2
View File
@@ -1,8 +1,6 @@
#include "osascript.h"
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <CoreData/CoreData.h>
bool ffOsascript(const char* input, FFstrbuf* result)
{
+1 -2
View File
@@ -1,9 +1,8 @@
#include "smc_temps.h"
#include "common/apple/cf_helpers.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include <stdint.h>
#include <math.h>
#include <IOKit/IOKitLib.h>
static const char kSmcCmdReadBytes = 5;
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "fastfetch.h"
bool ffGetAppNameAndVersion(const char* exePath, FFstrbuf* retName, FFstrbuf* retVersion);
+43
View File
@@ -0,0 +1,43 @@
#include "common/apple/version.h"
#include "common/strutil.h"
#import <Foundation/Foundation.h>
#define APP_CONTENTS_MACOS ".app/Contents/MacOS"
bool ffGetAppNameAndVersion(const char* exePath, FFstrbuf* retName, FFstrbuf* retVersion) {
char* lastSlash = strrchr(exePath, '/');
if (!lastSlash) {
return false;
}
if ((size_t) (lastSlash - exePath) > strlen("X" APP_CONTENTS_MACOS) && memcmp(lastSlash - strlen(APP_CONTENTS_MACOS), APP_CONTENTS_MACOS, strlen(APP_CONTENTS_MACOS)) != 0) {
return false;
}
lastSlash -= strlen("MacOS");
char infoPlistPath[PATH_MAX];
memcpy(infoPlistPath, exePath, lastSlash - exePath);
memcpy(infoPlistPath + (lastSlash - exePath), "Info.plist", sizeof("Info.plist")); // X.app/Contents/Info.plist
NSError* error;
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@(infoPlistPath)]
error:&error];
if (!dict) {
return false;
}
if (retName) {
NSString* bundleName = dict[@"CFBundleDisplayName"] ?: dict[@"CFBundleName"];
if (bundleName) {
ffStrbufSetS(retName, bundleName.UTF8String);
}
}
if (retVersion) {
NSString* bundleVersion = dict[@"CFBundleShortVersionString"];
if (bundleVersion) {
ffStrbufSetS(retVersion, bundleVersion.UTF8String);
}
}
return true;
}
+1
View File
@@ -16,3 +16,4 @@
#define FF_A_UNUSED __attribute__((__unused__))
#define FF_A_PACKED __attribute__((__packed__))
#define FF_A_WEAK_IMPORT __attribute__((__weak_import__))
#define FF_A_ALWAYS_INLINE __attribute__((__always_inline__))
+3 -3
View File
@@ -29,12 +29,12 @@ typedef struct FFDBusData {
const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data); // Returns an error message or NULL on success
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result);
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result);
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result);
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint64_t* result);
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2);
DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property);
bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result);
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result);
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result);
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int64_t* result);
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint64_t* result);
void ffDBusDestroyData(FFDBusData* data);
static inline DBusMessage* ffDBusGetAllProperties(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface) {
+1 -1
View File
@@ -9,6 +9,6 @@ typedef struct FFformatarg {
} FFformatarg;
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
bool ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, arguments) \
ffParseFormatString((buffer), (formatstr), sizeof(arguments) / sizeof(*arguments), (arguments));
+2 -1
View File
@@ -1,5 +1,5 @@
#include "FFPlatform_private.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/io.h"
#include "detection/version/version.h"
@@ -26,6 +26,7 @@ void ffPlatformInit(FFPlatform* platform) {
ffStrbufInit(&info->release);
ffStrbufInit(&info->version);
ffStrbufInit(&info->architecture);
info->pageSize = 0;
ffPlatformInitImpl(platform);
+4 -3
View File
@@ -1,7 +1,7 @@
#include "FFPlatform_private.h"
#include "common/FFstrbuf.h"
#include "common/arrayUtils.h"
#include "common/stringUtils.h"
#include "common/arrutil.h"
#include "common/strutil.h"
#include "common/io.h"
#include "fastfetch_config.h"
@@ -18,6 +18,7 @@
#include <sys/sysctl.h>
#elif defined(__OpenBSD__)
#include <sys/sysctl.h>
#include <sys/stat.h>
#include <kvm.h>
#include "common/path.h"
#elif defined(__HAIKU__)
@@ -97,7 +98,7 @@ static void getExePath(FFPlatform* platform) {
struct stat st;
if (stat(exePath, &st) == 0 && S_ISREG(st.st_mode)) {
int cntp;
struct kinfo_file* kf = kvm_getfiles(kd, KERN_FILE_BYPID, platform->pid, sizeof(*kf), &cntp);
struct kinfo_file* kf = kvm_getfiles(kd, KERN_FILE_BYPID, (pid_t) platform->pid, sizeof(*kf), &cntp);
if (kf) {
int i;
for (i = 0; i < cntp; i++) {
+2 -2
View File
@@ -1,7 +1,7 @@
#include "FFPlatform_private.h"
#include "common/io.h"
#include "common/library.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/windows/unicode.h"
#include "common/windows/registry.h"
#include "common/windows/nt.h"
@@ -145,7 +145,7 @@ static void getUserName(FFPlatform* platform) {
PLSA_UNICODE_STRING userName = NULL;
if (NT_SUCCESS(LsaGetUserName(&userName, NULL))) {
ffStrbufSetNWS(&platform->userName, userName->Length / sizeof(wchar_t), userName->Buffer);
RtlFreeUnicodeString(userName);
RtlFreeUnicodeString(userName); // Required. userName.Buffer is allocated separately
LsaFreeMemory(userName);
} else {
ffStrbufSetS(&platform->userName, getenv("USERNAME"));
+2 -2
View File
@@ -12,7 +12,7 @@ void* ffListAdd(FFlist* list, uint32_t elementSize) {
return ffListGet(list, elementSize, list->length - 1);
}
bool ffListShift(FFlist* list, uint32_t elementSize, void* result) {
bool ffListShift(FFlist* list, uint32_t elementSize, void* __restrict result) {
if (list->length == 0) {
return false;
}
@@ -23,7 +23,7 @@ bool ffListShift(FFlist* list, uint32_t elementSize, void* result) {
return true;
}
bool ffListPop(FFlist* list, uint32_t elementSize, void* result) {
bool ffListPop(FFlist* list, uint32_t elementSize, void* __restrict result) {
if (list->length == 0) {
return false;
}
+7 -31
View File
@@ -1,6 +1,6 @@
#include "common/FFstrbuf.h"
#include "common/mallocHelper.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include <ctype.h>
#include <inttypes.h>
@@ -411,32 +411,6 @@ void ffStrbufRemoveStrings(FFstrbuf* strbuf, uint32_t numStrings, const char* st
}
}
uint32_t ffStrbufNextIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
assert(start <= strbuf->length);
const char* ptr = (const char*) memchr(strbuf->chars + start, c, strbuf->length - start);
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
}
uint32_t ffStrbufNextIndexS(const FFstrbuf* strbuf, uint32_t start, const char* str) {
assert(start <= strbuf->length);
const char* ptr = strstr(strbuf->chars + start, str);
return ptr ? (uint32_t) (ptr - strbuf->chars) : strbuf->length;
}
uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t start, char c) {
assert(start <= strbuf->length);
// We need to loop one higher than the actual index, because uint32_t is guaranteed to be >= 0, so this statement would always be true
for (uint32_t i = start + 1; i > 0; i--) {
if (strbuf->chars[i - 1] == c) {
return i - 1;
}
}
return strbuf->length;
}
void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace) {
if (strbuf->length == 0) {
return;
@@ -790,9 +764,10 @@ bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const
}
for (const char* p = comp; p < comp + compLength;) {
const char* colon = memchr(p, separator, compLength);
const char* colon = memchr(p, separator, (size_t) (comp + compLength - p));
if (colon == NULL) {
return strcmp(strbuf->chars, p) == 0;
uint32_t remainingLen = (uint32_t) (comp + compLength - p);
return strbuf->length == remainingLen && memcmp(strbuf->chars, p, remainingLen) == 0;
}
uint32_t substrLength = (uint32_t) (colon - p);
@@ -817,9 +792,10 @@ bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength
}
for (const char* p = comp; p < comp + compLength;) {
const char* colon = memchr(p, separator, compLength);
const char* colon = memchr(p, separator, (size_t) (comp + compLength - p));
if (colon == NULL) {
return strcasecmp(strbuf->chars, p) == 0;
uint32_t remainingLen = (uint32_t) (comp + compLength - p);
return strbuf->length == remainingLen && strncasecmp(strbuf->chars, p, remainingLen) == 0;
}
uint32_t substrLength = (uint32_t) (colon - p);
+1 -1
View File
@@ -34,7 +34,7 @@ void ffBase64EncodeRaw(uint32_t size, const char* str, uint32_t* out_size, char*
static uint8_t decode_table[256];
void init_decode_table() {
static void init_decode_table() {
uint8_t ch = 0;
do {
int32_t code = -1;
+2 -3
View File
@@ -1,6 +1,6 @@
#include "common/binary.h"
#include "common/io.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include <string.h>
#include <fcntl.h>
@@ -72,6 +72,7 @@ static bool handleMachSection(const FFMemoryMapping* mapping, const char* name,
}
uint32_t len = (uint32_t) strnlen(p, size - off);
if (len < minLength) {
off += len; // Skip short strings
continue;
}
if (*p >= ' ' && *p <= '~') { // Ignore control characters
@@ -177,8 +178,6 @@ static const char* dumpMachHeader(const FFMemoryMapping* mapping, off_t offset,
}
}
}
return NULL;
}
return NULL;
+3 -2
View File
@@ -4,7 +4,7 @@
#include "common/io.h"
#include "common/library.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include <libelf.h> // #1254
#include <fcntl.h>
@@ -112,8 +112,9 @@ const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* s
if (*p == '\0') {
continue;
}
uint32_t len = (uint32_t) strlen(p);
uint32_t len = (uint32_t) strnlen(p, data->d_size - off);
if (len < minLength) {
off += len;
continue;
}
// Only process printable ASCII characters
+3 -2
View File
@@ -1,6 +1,6 @@
#include "common/binary.h"
#include "common/io.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/windows/nt.h"
#include <windows.h>
@@ -49,8 +49,9 @@ const char* ffBinaryExtractStrings(const char* peFile, bool (*cb)(const char* st
if (*p == '\0') {
continue;
}
uint32_t len = (uint32_t) strlen(p);
uint32_t len = (uint32_t) strnlen(p, section->SizeOfRawData - off);
if (len < minLength) {
off += len;
continue;
}
// Only process printable ASCII characters
+24 -6
View File
@@ -3,7 +3,7 @@
#include "common/printing.h"
#include "common/time.h"
#include "common/jsonconfig.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "fastfetch_datatext.h"
#include "modules/modules.h"
@@ -70,12 +70,15 @@ void ffPrepareCommandOption(FFdata* data) {
#define FF_IF_MODULE_MATCH(moduleNameConstant) if (moduleLen == strlen(moduleNameConstant) && ffStrEqualsIgnCase(moduleType, moduleNameConstant) && !ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleNameConstant, ':'))
switch (moduleType[0]) {
#if !FF_MODULE_DISABLE_CPUUSAGE
case 'C':
case 'c':
FF_IF_MODULE_MATCH(FF_CPUUSAGE_MODULE_NAME)
ffPrepareCPUUsage();
break;
#endif
#if !FF_MODULE_DISABLE_DISKIO
case 'D':
case 'd':
FF_IF_MODULE_MATCH(FF_DISKIO_MODULE_NAME) {
@@ -84,7 +87,9 @@ void ffPrepareCommandOption(FFdata* data) {
ffPrepareDiskIO(&options);
}
break;
#endif
#if !FF_MODULE_DISABLE_NETIO
case 'N':
case 'n':
FF_IF_MODULE_MATCH(FF_NETIO_MODULE_NAME) {
@@ -93,7 +98,9 @@ void ffPrepareCommandOption(FFdata* data) {
ffPrepareNetIO(&options);
}
break;
#endif
#if !FF_MODULE_DISABLE_PUBLICIP
case 'P':
case 'p':
FF_IF_MODULE_MATCH(FF_PUBLICIP_MODULE_NAME) {
@@ -102,7 +109,9 @@ void ffPrepareCommandOption(FFdata* data) {
ffPreparePublicIp(&options);
}
break;
#endif
#if !FF_MODULE_DISABLE_WEATHER
case 'W':
case 'w':
FF_IF_MODULE_MATCH(FF_WEATHER_MODULE_NAME) {
@@ -111,6 +120,7 @@ void ffPrepareCommandOption(FFdata* data) {
ffPrepareWeather(&options);
}
break;
#endif
}
#undef FF_IF_MODULE_MATCH
@@ -157,7 +167,7 @@ static void genJsonResult(FFdata* data, FFModuleBaseInfo* baseInfo, void* option
}
}
static void parseStructureCommand(
static bool parseStructureCommand(
FFdata* data,
const char* line,
void (*fn)(FFdata*, FFModuleBaseInfo* baseInfo, void* options)) {
@@ -167,18 +177,26 @@ static void parseStructureCommand(
if (ffStrEqualsIgnCase(line, baseInfo->name)) {
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
baseInfo->initOptions(optionBuf);
if (__builtin_expect(data->resultDoc != NULL, false)) {
if (data->resultDoc != NULL) {
fn(data, baseInfo, optionBuf);
} else {
baseInfo->printModule(optionBuf);
}
baseInfo->destroyOptions(optionBuf);
return;
return true;
}
}
}
ffPrintError(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
if (data->resultDoc) {
yyjson_mut_doc* doc = data->resultDoc;
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", line);
yyjson_mut_obj_add_str(doc, module, "error", "Unknown module type");
} else {
ffPrintError(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
}
return false;
}
void ffPrintCommandOption(FFdata* data) {
@@ -213,7 +231,7 @@ void ffPrintCommandOption(FFdata* data) {
: FF_COLOR_FG_RED),
ms);
}
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len - 1, str); // Save; Up 1; Right 9999999; Left <len - 1>; Print <str>; Load
}
}
+52 -7
View File
@@ -3,7 +3,7 @@
#ifdef FF_HAVE_DBUS
#include "common/thread.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
static bool loadLibSymbols(FFDBusLibrary* lib) {
FF_LIBRARY_LOAD(dbus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
@@ -76,7 +76,7 @@ bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result)
uint8_t value;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
ffStrbufAppendC(result, (char) value);
return false; // Don't append a comma
return true;
}
if (argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY) {
@@ -92,6 +92,25 @@ bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result)
// At this point we have an array
int subArgType = dbus->lib->ffdbus_message_iter_get_arg_type(&subIter);
if (subArgType == DBUS_TYPE_INVALID) {
return false;
}
if (subArgType == DBUS_TYPE_BYTE) {
while (true) {
uint8_t value;
dbus->lib->ffdbus_message_iter_get_basic(&subIter, &value);
ffStrbufAppendC(result, (char) value);
if (!dbus->lib->ffdbus_message_iter_next(&subIter)) {
break;
}
}
return true;
}
bool foundAValue = false;
while (true) {
@@ -133,7 +152,7 @@ bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result) {
return ffDBusGetBool(dbus, &subIter, result);
}
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result) {
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint64_t* result) {
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
if (argType == DBUS_TYPE_BYTE) {
@@ -151,6 +170,13 @@ bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result) {
}
if (argType == DBUS_TYPE_UINT32) {
uint32_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
if (argType == DBUS_TYPE_UINT64) {
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
@@ -164,7 +190,7 @@ bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result) {
return ffDBusGetUint(dbus, &subIter, result);
}
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result) {
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int64_t* result) {
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
if (argType == DBUS_TYPE_INT16) {
@@ -175,6 +201,13 @@ bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result) {
}
if (argType == DBUS_TYPE_INT32) {
int32_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = value;
return true;
}
if (argType == DBUS_TYPE_INT64) {
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
return true;
}
@@ -189,12 +222,24 @@ bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result) {
if (argType == DBUS_TYPE_UINT16) {
uint16_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = (int16_t) value;
*result = (int32_t) value;
return true;
}
if (argType == DBUS_TYPE_UINT32) {
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
uint32_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
*result = (int32_t) value;
return true;
}
if (argType == DBUS_TYPE_UINT64) {
uint64_t value = 0;
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
if (value > INT64_MAX) {
return false;
}
*result = (int64_t) value;
return true;
}
@@ -267,7 +312,7 @@ bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char*
return ret;
}
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result) {
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint64_t* result) {
DBusMessage* reply = ffDBusGetProperty(dbus, busName, objectPath, interface, property);
if (reply == NULL) {
return false;
+8 -3
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "common/FFlist.h"
#include "common/FFstrbuf.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/font.h"
#include <string.h>
@@ -425,10 +425,11 @@ void ffFontInitXft(FFfont* font, const char* xft) {
if (value.length > 0) {
if (
(keyLen == 4 && ffStrStartsWithIgnCase(keyStart, "size")) ||
(keyLen == 9 && ffStrStartsWithIgnCase(keyStart, "pixelsize"))) {
(keyLen == 9 && (ffStrStartsWithIgnCase(keyStart, "pixelsize") || ffStrStartsWithIgnCase(keyStart, "pointsize")))) {
if (sizeEmpty && ffCharIsDigit(value.chars[0])) {
ffStrbufAppend(&font->size, &value);
ffStrbufAppendS(&font->size, keyLen == 4 ? "pt" : "px");
ffStrbufAppendS(&font->size,
(keyLen == 9 && ffStrStartsWithIgnCase(keyStart, "pixelsize")) ? "px" : "pt");
}
} else if (keyLen == 5 && ffStrStartsWithIgnCase(keyStart, "style")) {
// style may contain multiple words: "Bold Italic"
@@ -457,6 +458,10 @@ void ffFontInitXft(FFfont* font, const char* xft) {
ffStrbufInit(style);
strbufAppendNSExcludingC(style, value.length, value.chars, '-');
ffStrbufTrim(style, ' ');
if (style->length == 0) {
ffStrbufDestroy(style);
--font->styles.length;
}
}
}
}
+389 -6
View File
@@ -2,7 +2,8 @@
#include "common/format.h"
#include "common/parsing.h"
#include "common/textModifier.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/library.h"
#include <inttypes.h>
@@ -108,10 +109,349 @@ static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start,
}
static inline bool formatArgSet(const FFformatarg* arg) {
return arg->value != NULL && ((arg->type == FF_ARG_TYPE_DOUBLE && *(double*) arg->value > 0.0) || (arg->type == FF_ARG_TYPE_FLOAT && *(float*) arg->value > 0.0) || (arg->type == FF_ARG_TYPE_INT && *(int*) arg->value > 0) || (arg->type == FF_ARG_TYPE_STRBUF && ((FFstrbuf*) arg->value)->length > 0) || (arg->type == FF_ARG_TYPE_STRING && ffStrSet((char*) arg->value)) || (arg->type == FF_ARG_TYPE_UINT8 && *(uint8_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_UINT16 && *(uint16_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_UINT && *(uint32_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_BOOL && *(bool*) arg->value) || (arg->type == FF_ARG_TYPE_LIST && ((FFlist*) arg->value)->length > 0));
return arg->value != NULL && ((arg->type == FF_ARG_TYPE_DOUBLE && *(double*) arg->value > 0.0) || (arg->type == FF_ARG_TYPE_FLOAT && *(float*) arg->value > 0.0) || (arg->type == FF_ARG_TYPE_INT && *(int32_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_STRBUF && ((FFstrbuf*) arg->value)->length > 0) || (arg->type == FF_ARG_TYPE_STRING && ffStrSet((char*) arg->value)) || (arg->type == FF_ARG_TYPE_UINT8 && *(uint8_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_UINT16 && *(uint16_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_UINT && *(uint32_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_UINT64 && *(uint64_t*) arg->value > 0) || (arg->type == FF_ARG_TYPE_BOOL && *(bool*) arg->value) || (arg->type == FF_ARG_TYPE_LIST && ((FFlist*) arg->value)->length > 0));
}
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments) {
FF_A_UNUSED static inline void normalizeArgName(FFstrbuf* dst, const char* src) {
ffStrbufClear(dst);
bool flag = false;
for (const char* p = src; *p; ++p) {
if (*p == '-') {
flag = true;
} else if (flag) {
ffStrbufAppendC(dst, (char) toupper((unsigned char) *p));
flag = false;
} else {
ffStrbufAppendC(dst, *p);
}
}
}
#if FF_HAVE_LUA
#include "common/lua.h"
static void appendLuaError(FFstrbuf* buffer, const char* prefix, lua_State* L) {
const char* err = lua_tolstring(L, -1, NULL);
if (err) {
const char* tmp = strchr(err, ':');
if (tmp) {
err = tmp + 1;
while (*err == ' ') {
++err;
}
}
}
ffStrbufAppendF(buffer, "%s: %s", prefix, err ? err : "unknown");
}
static bool parseLuaString(FFstrbuf* buffer, const char* script, uint32_t scriptLen, uint32_t numArgs, const FFformatarg* arguments) {
const char* err = ffLuaLoadState();
if (err) {
ffStrbufAppendF(buffer, "Lua init error: %s", err);
return false;
}
FF_STRBUF_AUTO_DESTROY argNameBuf = ffStrbufCreate();
bool ret = false;
lua_State* L = luaData.L;
// Clear stack and load chunk
lua_settop(L, 0);
if (luaL_loadbuffer(L, script, scriptLen, "") != LUA_OK) {
appendLuaError(buffer, "Lua load error", L);
} else {
// Build args table for name lookup only.
lua_createtable(L, 0, 0);
for (uint32_t i = 0; i < numArgs; ++i) {
const FFformatarg* arg = &arguments[i];
switch (arg->type) {
case FF_ARG_TYPE_INT:
lua_pushinteger(L, (lua_Integer) * (int32_t*) arg->value);
break;
case FF_ARG_TYPE_UINT:
lua_pushinteger(L, (lua_Integer) * (uint32_t*) arg->value);
break;
case FF_ARG_TYPE_UINT64:
lua_pushinteger(L, (lua_Integer) * (uint64_t*) arg->value);
break;
case FF_ARG_TYPE_UINT16:
lua_pushinteger(L, (lua_Integer) * (uint16_t*) arg->value);
break;
case FF_ARG_TYPE_UINT8:
lua_pushinteger(L, (lua_Integer) * (uint8_t*) arg->value);
break;
case FF_ARG_TYPE_FLOAT:
lua_pushnumber(L, (lua_Number) * (float*) arg->value);
break;
case FF_ARG_TYPE_DOUBLE:
lua_pushnumber(L, (lua_Number) * (double*) arg->value);
break;
case FF_ARG_TYPE_BOOL:
lua_pushboolean(L, *(bool*) arg->value);
break;
case FF_ARG_TYPE_STRING:
lua_pushlstring(L, (const char*) arg->value, strlen((const char*) arg->value));
break;
case FF_ARG_TYPE_STRBUF: {
const FFstrbuf* sb = (const FFstrbuf*) arg->value;
lua_pushlstring(L, sb->chars, sb->length);
break;
}
case FF_ARG_TYPE_LIST: {
const FFlist* list = (const FFlist*) arg->value;
lua_createtable(L, 0, 0);
for (uint32_t li = 0; li < list->length; ++li) {
const FFstrbuf* item = FF_LIST_GET(FFstrbuf, *list, li);
lua_pushlstring(L, item->chars, item->length);
lua_seti(L, -2, (lua_Integer) (li + 1));
}
break;
}
default:
lua_pushnil(L);
break;
}
if (arg->name && arg->name[0]) {
normalizeArgName(&argNameBuf, arg->name);
} else {
ffStrbufSetF(&argNameBuf, "arg%" PRIu32, i + 1);
}
lua_setfield(L, -2, argNameBuf.chars);
}
if (lua_pcall(L, 1, LUA_MULTRET, 0) != LUA_OK) {
appendLuaError(buffer, "Lua runtime error", L);
} else {
int nresults = lua_gettop(L);
if (nresults == 0) {
ffStrbufAppendS(buffer, "Lua result error: no result");
} else {
// Convert first result to string
const char* res = lua_tolstring(L, 1, NULL);
if (res) {
ffStrbufAppendS(buffer, res);
} else {
luaL_tolstring(L, 1, NULL);
const char* sval = lua_tolstring(L, -1, NULL);
if (sval) {
ffStrbufAppendS(buffer, sval);
}
}
ret = true;
}
}
}
lua_settop(L, 0);
return ret;
}
#endif
#if FF_HAVE_QUICKJS
#include <quickjs.h>
struct FFQuickJSData {
FF_LIBRARY_SYMBOL(JS_NewRuntime)
FF_LIBRARY_SYMBOL(JS_NewContext)
FF_LIBRARY_SYMBOL(JS_FreeRuntime)
FF_LIBRARY_SYMBOL(JS_EvalThis)
FF_LIBRARY_SYMBOL(JS_GetException)
FF_LIBRARY_SYMBOL(JS_ToCStringLen2)
FF_LIBRARY_SYMBOL(JS_FreeCString)
FF_LIBRARY_SYMBOL(JS_NewStringLen)
FF_LIBRARY_SYMBOL(JS_NewArray)
FF_LIBRARY_SYMBOL(JS_NewBigUint64)
FF_LIBRARY_SYMBOL(JS_SetPropertyUint32)
FF_LIBRARY_SYMBOL(JS_NewObject)
FF_LIBRARY_SYMBOL(JS_SetPropertyStr)
FF_LIBRARY_SYMBOL(JS_FreeValue)
JSRuntime* rt;
JSContext* ctx;
bool inited;
} qjsData;
static const char* loadQuickJSState(void) {
if (qjsData.inited) {
if (qjsData.ctx == NULL) {
return "QuickJS is not available";
}
return NULL;
}
qjsData.inited = true;
#ifdef _WIN32
FF_LIBRARY_LOAD_MESSAGE(libqjs, "libqjs-0" FF_LIBRARY_EXTENSION, 0)
#else
FF_LIBRARY_LOAD_MESSAGE(libqjs, "libqjs" FF_LIBRARY_EXTENSION, 0)
#endif
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_NewRuntime)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_NewContext)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_FreeRuntime)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_EvalThis)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_GetException)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_ToCStringLen2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_FreeCString)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_NewStringLen)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_NewArray)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_SetPropertyUint32)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_NewObject)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_SetPropertyStr)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libqjs, qjsData, JS_FreeValue)
qjsData.rt = qjsData.ffJS_NewRuntime();
if (qjsData.rt == NULL) {
return "JS_NewRuntime() failed";
}
qjsData.ctx = qjsData.ffJS_NewContext(qjsData.rt);
if (qjsData.ctx == NULL) {
qjsData.ffJS_FreeRuntime(qjsData.rt);
qjsData.rt = NULL;
return "JS_NewContext() failed";
}
libqjs = NULL; // don't close quickjs
return NULL;
}
static bool parseQuickJSString(FFstrbuf* buffer, const char* script, uint32_t scriptLen, uint32_t numArgs, const FFformatarg* arguments) {
const char* err = loadQuickJSState();
if (err) {
ffStrbufAppendF(buffer, "Qjs init error: %s", err);
return false;
}
JSContext* ctx = qjsData.ctx;
JSValue argsObj = qjsData.ffJS_NewObject(ctx);
FF_STRBUF_AUTO_DESTROY argNameBuf = ffStrbufCreate();
for (uint32_t i = 0; i < numArgs; ++i) {
const FFformatarg* arg = &arguments[i];
JSValue value;
switch (arg->type) {
case FF_ARG_TYPE_INT:
value = JS_NewInt32(ctx, *(int32_t*) arg->value);
break;
case FF_ARG_TYPE_UINT:
value = JS_NewUint32(ctx, *(uint32_t*) arg->value);
break;
case FF_ARG_TYPE_UINT64: {
uint64_t val = *(uint64_t*) arg->value;
if (val <= INT32_MAX) {
value = JS_NewInt32(ctx, (int32_t) val);
} else {
value = JS_NewFloat64(ctx, (double) val);
}
break;
}
case FF_ARG_TYPE_UINT16:
value = JS_NewUint32(ctx, *(uint16_t*) arg->value);
break;
case FF_ARG_TYPE_UINT8:
value = JS_NewUint32(ctx, *(uint8_t*) arg->value);
break;
case FF_ARG_TYPE_FLOAT:
value = JS_NewFloat64(ctx, *(float*) arg->value);
break;
case FF_ARG_TYPE_DOUBLE:
value = JS_NewFloat64(ctx, *(double*) arg->value);
break;
case FF_ARG_TYPE_BOOL:
value = JS_NewBool(ctx, *(bool*) arg->value);
break;
case FF_ARG_TYPE_STRING:
value = qjsData.ffJS_NewStringLen(ctx, (const char*) arg->value, strlen((const char*) arg->value));
break;
case FF_ARG_TYPE_STRBUF: {
const FFstrbuf* sb = (const FFstrbuf*) arg->value;
value = qjsData.ffJS_NewStringLen(ctx, sb->chars, sb->length);
break;
}
case FF_ARG_TYPE_LIST: {
const FFlist* list = (const FFlist*) arg->value;
JSValue arr = qjsData.ffJS_NewArray(ctx);
for (uint32_t li = 0; li < list->length; ++li) {
const FFstrbuf* item = FF_LIST_GET(FFstrbuf, *list, li);
JSValue itemValue = qjsData.ffJS_NewStringLen(ctx, item->chars, item->length);
qjsData.ffJS_SetPropertyUint32(ctx, arr, li, itemValue);
}
value = arr;
break;
}
default:
value = JS_UNDEFINED;
break;
}
if (arg->name && arg->name[0]) {
normalizeArgName(&argNameBuf, arg->name);
} else {
ffStrbufSetF(&argNameBuf, "arg%" PRIu32, i + 1);
}
qjsData.ffJS_SetPropertyStr(ctx, argsObj, argNameBuf.chars, value);
}
JSValue result = qjsData.ffJS_EvalThis(ctx, argsObj, script, scriptLen, "", JS_EVAL_TYPE_GLOBAL | JS_EVAL_FLAG_STRICT);
qjsData.ffJS_FreeValue(ctx, argsObj);
bool ret = false;
if (JS_IsException(result)) {
JSValue exc = qjsData.ffJS_GetException(ctx);
const char* message = qjsData.ffJS_ToCStringLen2(ctx, NULL, exc, false);
qjsData.ffJS_FreeValue(ctx, exc);
ffStrbufAppendF(buffer, "Qjs runtime error: %s", message ?: "unknown");
if (message) {
qjsData.ffJS_FreeCString(ctx, message);
}
} else if (JS_IsUndefined(result)) {
ffStrbufAppendS(buffer, "Qjs result error: undefined result");
} else {
size_t len;
const char* res = qjsData.ffJS_ToCStringLen2(ctx, &len, result, false);
if (res) {
ffStrbufAppendNS(buffer, (uint32_t) len, res);
qjsData.ffJS_FreeCString(ctx, res);
}
ret = true;
}
qjsData.ffJS_FreeValue(ctx, result);
return ret;
}
#endif
static bool skipAnsiEscape(FFstrbuf* in, FFstrbuf* out, FFstrbuf* trailingEscape) {
if (__builtin_expect(in->chars[0] == '\e' && in->chars[1] == '[', false)) {
// skip ANSI escape codes at the start of the string for truncation
const char* p = in->chars + 2;
while (*p && (ffCharIsDigit(*p) || *p == ';')) {
++p;
}
if (*p && isascii(*p)) {
++p;
}
uint32_t prefixLen = (uint32_t) (p - in->chars);
ffStrbufAppendNS(out, prefixLen, in->chars);
ffStrbufSubstrAfter(in, prefixLen - 1);
if (trailingEscape) {
// likely have a `CSI m` reset at the end of the string
uint32_t iLastEscape = ffStrbufLastIndexC(in, '\e');
if (iLastEscape != in->length) {
ffStrbufSetNS(trailingEscape, in->length - iLastEscape, in->chars + iLastEscape);
ffStrbufSubstrBefore(in, iLastEscape);
}
}
return true;
}
return false;
}
static bool parseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments) {
uint32_t argCounter = 0;
uint32_t numOpenIfs = 0;
@@ -129,6 +469,12 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
// jump to next char, the start of the placeholder value
++i;
// unmatched trailing '{'
if (i >= formatstr->length) {
ffStrbufAppendC(buffer, '{');
break;
}
// double {{ elvaluates to a single { and doesn't count as start
if (formatstr->chars[i] == '{') {
ffStrbufAppendC(buffer, '{');
@@ -267,7 +613,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
char* pSep = placeholderValue.chars;
char cSep = '\0';
while (*pSep && *pSep != ':' && *pSep != '<' && *pSep != '>' && *pSep != '~') {
while (*pSep && *pSep != ':' && *pSep != '<' && *pSep != '>' && *pSep != '|' && *pSep != '~') {
++pSep;
}
if (*pSep) {
@@ -297,6 +643,8 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
} else if (cSep == '~') {
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
FF_STRBUF_AUTO_DESTROY trailingEscape = ffStrbufCreate();
skipAnsiEscape(&tempString, buffer, &trailingEscape);
char* pEnd = NULL;
int32_t start = (int32_t) strtol(pSep + 1, &pEnd, 10);
@@ -322,6 +670,10 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
}
}
if (trailingEscape.length > 0) {
ffStrbufAppend(buffer, &trailingEscape);
}
if (*pEnd) {
*pSep = cSep;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
@@ -344,6 +696,9 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
FF_STRBUF_AUTO_DESTROY trailingEscape = ffStrbufCreate();
skipAnsiEscape(&tempString, buffer, &trailingEscape);
if (tempString.length == (uint32_t) truncLength) {
ffStrbufAppend(buffer, &tempString);
} else if (tempString.length > (uint32_t) truncLength) {
@@ -361,18 +716,46 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
} else if (cSep == ':') {
ffStrbufAppend(buffer, &tempString);
} else {
if (cSep == '<') {
if (cSep == '<') { // left align
ffStrbufAppend(buffer, &tempString);
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
} else {
} else if (cSep == '>') { // right align
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
ffStrbufAppend(buffer, &tempString);
} else if (cSep == '|') { // center align
uint32_t padding = ((uint32_t) truncLength - tempString.length) / 2;
ffStrbufAppendNC(buffer, padding, ' ');
ffStrbufAppend(buffer, &tempString);
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length - padding, ' ');
}
}
if (trailingEscape.length > 0) {
ffStrbufAppend(buffer, &trailingEscape);
}
}
}
if (!instance.config.display.pipe) {
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
}
return true;
}
bool ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments) {
#if FF_HAVE_QUICKJS
if (ffStrbufStartsWithS(formatstr, "qjs:")) {
return parseQuickJSString(buffer, formatstr->chars + 4, formatstr->length - 4, numArgs, arguments);
}
#endif
#if FF_HAVE_LUA
if (ffStrbufStartsWithS(formatstr, "lua:")) {
// If outputFormat starts with "lua:", treat the rest as a Lua script
return parseLuaString(buffer, formatstr->chars + 4, formatstr->length - 4, numArgs, arguments);
}
#endif
return parseFormatString(buffer, formatstr, numArgs, arguments);
}
+39 -7
View File
@@ -29,6 +29,7 @@ static void initState(FFstate* state) {
ffPlatformInit(&state->platform);
state->dynamicInterval = 0;
#if !FF_MODULE_DISABLE_TERMINALTHEME
{
// don't enable bright color if the terminal is in light mode
FFTerminalThemeResult result;
@@ -36,6 +37,7 @@ static void initState(FFstate* state) {
state->terminalLightTheme = true;
}
}
#endif
}
static void defaultConfig(void) {
@@ -57,9 +59,9 @@ void ffInitInstance(void) {
initState(&instance.state);
}
static volatile bool ffDisableLinewrap = true;
static volatile bool ffHideCursor = true;
#if _WIN32
static volatile bool ffDisableLinewrap = false;
static volatile bool ffHideCursor = false;
#ifdef _WIN32
static volatile UINT oldCp = CP_UTF8;
#endif
@@ -122,7 +124,10 @@ void ffStart(void) {
if (instance.config.display.noBuffer) {
setvbuf(stdout, NULL, _IONBF, 0);
}
struct sigaction action = { .sa_handler = exitSignalHandler };
struct sigaction action;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
action.sa_handler = exitSignalHandler;
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
sigaction(SIGQUIT, &action, NULL);
@@ -170,6 +175,15 @@ void ffDestroyInstance(void) {
destroyState();
}
#if FF_HAVE_LUA
#include <lua.h>
#endif
#if FF_HAVE_QUICKJS
#include <quickjs.h>
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
#endif
// Must be in a file compiled with the libfastfetch target, because the FF_HAVE* macros are not defined for the executable targets
void ffListFeatures(void) {
fputs(
@@ -200,6 +214,9 @@ void ffListFeatures(void) {
#if FF_HAVE_DCONF
"dconf\n"
#endif
#if FF_HAVE_EET
"eet\n"
#endif
#if FF_HAVE_DBUS
"dbus\n"
#endif
@@ -245,23 +262,38 @@ void ffListFeatures(void) {
#if FF_HAVE_LIBZFS
"libzfs\n"
#endif
#if FF_HAVE_VA
"va\n"
#endif
#if FF_HAVE_VDPAU
"vdpau\n"
#endif
#if FF_USE_SYSTEM_YYJSON
"System yyjson\n"
#endif
#if FF_HAVE_LINUX_VIDEODEV2
"linux/videodev2\n"
#endif
#if FF_HAVE_LINUX_WIRELESS
"linux/wireless\n"
#endif
#if FF_HAVE_EMBEDDED_PCIIDS
"Embedded pciids\n"
#endif
#if FF_ENABLE_WCWIDTH
"Embedded wcwidth\n"
#endif
#if FF_HAVE_WINRT
"WinRT headers\n"
#endif
#if FF_WIN81_COMPAT
"Windows 8.1 Compatibility\n"
#endif
#if FF_APPLE_MEMSIZE_USABLE
"Apple memsize_usable\n"
#endif
#if FF_HAVE_LUA
LUA_VERSION "\n"
#endif
#if FF_HAVE_QUICKJS
"QuickJS " FF_STR(QJS_VERSION_MAJOR) "." FF_STR(QJS_VERSION_MINOR) "." FF_STR(QJS_VERSION_PATCH) QJS_VERSION_SUFFIX "\n"
#endif
"",
stdout);
+5 -6
View File
@@ -1,6 +1,6 @@
#include "common/io.h"
#include "fastfetch.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/time.h"
#include <fcntl.h>
@@ -252,14 +252,15 @@ bool ffSuppressIO(bool suppress) {
}
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty) {
FF_AUTO_CLOSE_FD int dfd = open(folder->chars, O_RDONLY | O_CLOEXEC);
int dfd = open(folder->chars, O_RDONLY | O_CLOEXEC | O_DIRECTORY); // Ownership of dfd will be transformed to dir
if (dfd < 0) {
return;
}
DIR* dir = fdopendir(dfd);
FF_AUTO_CLOSE_DIR DIR* dir = fdopendir(dfd);
if (dir == NULL) {
return;
close(dfd);
return; // Should not happen
}
uint32_t folderLength = folder->length;
@@ -310,8 +311,6 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
puts(entry->d_name);
}
closedir(dir);
}
void ffListFilesRecursively(const char* path, bool pretty) {
+13 -5
View File
@@ -1,6 +1,6 @@
#include "fastfetch.h"
#include "common/io.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/windows/nt.h"
#include "common/windows/unicode.h"
@@ -387,10 +387,12 @@ void ffListFilesRecursively(const char* path, bool pretty) {
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...) {
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE;
DWORD inputMode;
if (!GetConsoleMode(hInput, &inputMode)) {
DWORD inputMode = 0;
bool hasInputMode = !!GetConsoleMode(hInput, &inputMode);
if (!hasInputMode) {
hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL);
hInput = hConin;
hasInputMode = !!GetConsoleMode(hInput, &inputMode);
}
SetConsoleMode(hInput, 0);
@@ -439,12 +441,16 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
while (true) {
DWORD bytes = 0;
if (!ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL) || bytes == 0) {
if (!ReadFile(hInput, buffer + bytesRead, (DWORD) (sizeof(buffer) - 1 - bytesRead), &bytes, NULL) || bytes == 0) {
va_end(args);
return "ReadFile() failed";
}
bytesRead += bytes;
if (__builtin_expect(bytesRead >= sizeof(buffer) - 1, false)) {
va_end(args);
return "terminal response buffer overflow";
}
buffer[bytesRead] = '\0';
va_list cargs;
@@ -461,7 +467,9 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
}
}
SetConsoleMode(hInput, inputMode);
if (hasInputMode) {
SetConsoleMode(hInput, inputMode);
}
va_end(args);
+20 -11
View File
@@ -4,7 +4,7 @@
#include "common/printing.h"
#include "common/io.h"
#include "common/time.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "detection/version/version.h"
#include "modules/modules.h"
@@ -133,16 +133,12 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_
static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
switch (type[0]) {
case 'b':
case 'B': {
if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME)) {
ffPrepareCPUUsage();
}
break;
}
#if !FF_MODULE_DISABLE_CPUUSAGE
case 'c':
case 'C': {
if (ffStrEqualsIgnCase(type, FF_COMMAND_MODULE_NAME)) {
if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME)) {
ffPrepareCPUUsage();
} else if (ffStrEqualsIgnCase(type, FF_COMMAND_MODULE_NAME)) {
FF_A_CLEANUP(ffDestroyCommandOptions) FFCommandOptions options;
ffInitCommandOptions(&options);
if (module) {
@@ -152,6 +148,9 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
}
break;
}
#endif
#if !FF_MODULE_DISABLE_DISKIO
case 'd':
case 'D': {
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME)) {
@@ -164,6 +163,9 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
}
break;
}
#endif
#if !FF_MODULE_DISABLE_NETIO
case 'n':
case 'N': {
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME)) {
@@ -176,6 +178,9 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
}
break;
}
#endif
#if !FF_MODULE_DISABLE_PUBLICIP
case 'p':
case 'P': {
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME)) {
@@ -188,6 +193,9 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
}
break;
}
#endif
#if !FF_MODULE_DISABLE_WEATHER
case 'w':
case 'W': {
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME)) {
@@ -200,6 +208,7 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module) {
}
break;
}
#endif
}
}
@@ -259,7 +268,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
yyjson_val* conditions = yyjson_obj_get(module, "condition");
if (conditions) {
if (!yyjson_is_obj(conditions)) {
return "Property 'conditions' must be an object";
return "Property 'condition' must be an object";
}
yyjson_val* system = yyjson_obj_get(conditions, "system");
@@ -327,7 +336,7 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
: FF_COLOR_FG_RED),
ms);
}
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
printf("\e7\e[1A\e[9999999C\e[%dD%s\e8", len - 1, str); // Save; Up 1; Right 9999999; Left <len - 1>; Print <str>; Load
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
#include "common/kmod.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include <sys/module.h>
#include <sys/param.h>
+1 -1
View File
@@ -1,5 +1,5 @@
#include "common/kmod.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include <sys/modctl.h>
#include <errno.h>
+1 -1
View File
@@ -1,7 +1,7 @@
#include "common/kmod.h"
#include "common/windows/nt.h"
#include "common/mallocHelper.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
bool ffKmodLoaded(const char* modName) {
ULONG bufferSize = 0;
+11 -5
View File
@@ -1,8 +1,8 @@
#include "fastfetch.h"
#include "common/library.h"
#include "common/debug.h"
#if _WIN32
#include "common/debug.h"
#include "common/windows/nt.h"
#include <errno.h>
#include <ntstatus.h>
@@ -30,7 +30,7 @@
static void* libraryLoad(const char* path, int maxVersion) {
void* result = dlopen(path, FF_DLOPEN_FLAGS);
#ifdef _WIN32
#if _WIN32
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
FF_UNUSED(maxVersion)
@@ -50,6 +50,10 @@ static void* libraryLoad(const char* path, int maxVersion) {
#else
if (result == NULL) {
FF_DEBUG("dlopen(\"%s\"): %s", path, dlerror());
}
if (result != NULL || maxVersion < 0) {
return result;
}
@@ -65,6 +69,8 @@ static void* libraryLoad(const char* path, int maxVersion) {
result = dlopen(pathbuf.chars, FF_DLOPEN_FLAGS);
if (result != NULL) {
break;
} else {
FF_DEBUG("dlopen(\"%s\"): %s", pathbuf.chars, dlerror());
}
ffStrbufSubstrBefore(&pathbuf, originalLength);
@@ -114,7 +120,7 @@ void* dlopen(const char* path, FF_A_UNUSED int mode) {
PVOID module = NULL;
status = LdrLoadDll(NULL, NULL, &(UNICODE_STRING) {
.Length = (USHORT) pathWBytes - sizeof(wchar_t), // Exclude null terminator
.Length = (USHORT) (pathWBytes - sizeof(wchar_t)), // Exclude null terminator
.MaximumLength = (USHORT) pathWBytes,
.Buffer = pathW,
},
@@ -139,7 +145,7 @@ int dlclose(void* handle) {
void* dlsym(void* handle, const char* symbol) {
void* address;
USHORT symbolBytes = (USHORT) strlen(symbol) + 1;
USHORT symbolBytes = (USHORT) (strlen(symbol) + 1);
NTSTATUS status = LdrGetProcedureAddress(handle, &(ANSI_STRING) {
.Length = symbolBytes - sizeof(char),
.MaximumLength = symbolBytes,
@@ -158,7 +164,7 @@ void* ffLibraryGetModule(const wchar_t* libraryFileName) {
assert(libraryFileName != NULL && "Use \"ffGetPeb()->ImageBaseAddress\" instead");
void* module = NULL;
USHORT libraryFileNameBytes = (USHORT) (wcslen(libraryFileName) * sizeof(wchar_t)) + sizeof(wchar_t);
USHORT libraryFileNameBytes = (USHORT) (wcslen(libraryFileName) * sizeof(wchar_t) + sizeof(wchar_t));
NTSTATUS status = LdrGetDllHandle(NULL, NULL, &(UNICODE_STRING) {
.Length = libraryFileNameBytes - sizeof(wchar_t),
.MaximumLength = libraryFileNameBytes,
+233
View File
@@ -0,0 +1,233 @@
#if FF_HAVE_LUA
#include "common/lua.h"
#include "common/mallocHelper.h"
struct FFLuaData luaData;
static yyjson_mut_val* lua2yyjson(lua_State* L, int idx, yyjson_mut_doc* doc, int depth) {
if (__builtin_expect(depth > 15, false)) {
yyjson_mut_doc_free(doc);
lua_pushlstring(
L, "yyjson: recursion depth exceeded; possible circular reference", strlen("yyjson: recursion depth exceeded; possible circular reference"));
lua_error(L); // noreturn
__builtin_unreachable();
}
if (idx < 0) {
idx = lua_gettop(L) + idx + 1;
}
int type = lua_type(L, idx);
switch (type) {
case LUA_TNIL:
return yyjson_mut_null(doc);
case LUA_TBOOLEAN:
return yyjson_mut_bool(doc, lua_toboolean(L, idx));
case LUA_TNUMBER: {
if (lua_isinteger(L, idx)) {
lua_Integer i = lua_tointeger(L, idx);
return yyjson_mut_sint(doc, (int64_t) i);
} else {
return yyjson_mut_real(doc, lua_tonumber(L, idx));
}
}
case LUA_TSTRING: {
size_t len;
const char* str = lua_tolstring(L, idx, &len);
return yyjson_mut_strncpy(doc, str, len);
}
case LUA_TTABLE: {
lua_Unsigned len = lua_rawlen(L, idx);
int is_array = 1;
if (len == 0) {
lua_pushnil(L);
is_array = 0;
if (lua_next(L, idx) != 0) {
lua_pop(L, 2);
}
} else {
lua_pushnil(L);
while (lua_next(L, idx) != 0) {
if (lua_type(L, -2) != LUA_TNUMBER) {
is_array = 0;
lua_pop(L, 2);
break;
}
int isnum = false;
lua_Integer k = lua_tointegerx(L, -2, &isnum);
if (!isnum || (lua_Unsigned) k > len) {
is_array = 0;
lua_pop(L, 2);
break;
}
lua_pop(L, 1);
}
}
if (is_array) {
yyjson_mut_val* arr = yyjson_mut_arr(doc);
for (lua_Unsigned i = 1; i <= len; i++) {
lua_rawgeti(L, idx, (lua_Integer) i);
yyjson_mut_val* val = lua2yyjson(L, -1, doc, depth + 1);
yyjson_mut_arr_append(arr, val);
lua_pop(L, 1);
}
return arr;
} else {
yyjson_mut_val* obj = yyjson_mut_obj(doc);
lua_pushnil(L);
while (lua_next(L, idx) != 0) {
size_t klen;
const char* key_str = luaL_tolstring(L, -2, &klen);
yyjson_mut_val* key = yyjson_mut_strncpy(doc, key_str, klen);
lua_pop(L, 1);
yyjson_mut_val* val = lua2yyjson(L, -1, doc, depth + 1);
yyjson_mut_obj_add(obj, key, val);
lua_pop(L, 1);
}
return obj;
}
}
default:
return yyjson_mut_null(doc);
}
}
static int yyjsonEncode(lua_State* L) {
luaL_checkany(L, 1);
bool pretty = false;
if (lua_isboolean(L, 2)) {
pretty = (int) lua_toboolean(L, 2);
}
yyjson_mut_doc* doc = yyjson_mut_doc_new(NULL);
if (__builtin_expect(!doc, false)) {
lua_pushlstring(L, "yyjson: yyjson_mut_doc_new() failed", strlen("yyjson: yyjson_mut_doc_new() failed"));
return lua_error(L);
}
yyjson_mut_val* root = lua2yyjson(L, 1, doc, 0);
yyjson_mut_doc_set_root(doc, root);
size_t jsonLen;
yyjson_write_err err = {};
FF_AUTO_FREE const char* jsonStr = yyjson_mut_write_opts(doc, YYJSON_WRITE_ALLOW_INF_AND_NAN | (pretty ? YYJSON_WRITE_PRETTY_TWO_SPACES : 0), NULL, &jsonLen, &err);
if (__builtin_expect(jsonStr != NULL, true)) {
lua_pushlstring(L, jsonStr, jsonLen);
yyjson_mut_doc_free(doc);
return 1;
} else {
yyjson_mut_doc_free(doc);
{
FF_STRBUF_AUTO_DESTROY errBuf = ffStrbufCreateStatic("yyjson: yyjson_mut_write_opts() failed: ");
ffStrbufAppendS(&errBuf, err.msg);
lua_pushlstring(L, errBuf.chars, errBuf.length);
}
return lua_error(L); // longjmp
}
}
const char* ffLuaLoadState(void) {
if (luaData.inited) {
if (luaData.L == NULL) {
return "Lua library is not available";
}
return NULL;
}
luaData.inited = true;
// clang-format off
#ifdef _WIN32
#define FF_LOAD_LIBLUA(version) FF_LIBRARY_LOAD_MESSAGE(liblua, \
"lua5" #version FF_LIBRARY_EXTENSION, 0)
#else
#define FF_LOAD_LIBLUA(version) FF_LIBRARY_LOAD_MESSAGE(liblua, \
"liblua5." #version FF_LIBRARY_EXTENSION, 0, \
"liblua-5." #version FF_LIBRARY_EXTENSION, 0, \
"liblua5." #version FF_LIBRARY_EXTENSION ".5." #version, 0)
#endif
// clang-format on
#if LUA_VERSION_NUM == 505
FF_LOAD_LIBLUA(5)
#elif LUA_VERSION_NUM == 504
FF_LOAD_LIBLUA(4)
#elif LUA_VERSION_NUM == 503
FF_LOAD_LIBLUA(3)
#else
#error "Unsupported Lua version"
#endif
#undef FF_LOAD_LIBLUA
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaL_newstate)
#if LUA_VERSION_NUM >= 505
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaL_openselectedlibs)
#else
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaL_requiref)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaopen_base)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaopen_math)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaopen_string)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(liblua, luaopen_table)
#endif
#if !FF_DISABLE_DLOPEN
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, luaL_checkany)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, luaL_loadbufferx)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, luaL_tolstring)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_callk)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_createtable)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_error)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_gettop)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_isinteger)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_next)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pcallk)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pushboolean)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pushcclosure)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pushinteger)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pushlstring)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pushnil)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pushnumber)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_pushvalue)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_rawgeti)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_rawlen)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_setfield)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_setglobal)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_seti)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_settop)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_toboolean)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_tointegerx)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_tolstring)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_tonumberx)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(liblua, luaData, lua_type)
#endif
lua_State* L = ffluaL_newstate();
if (L == NULL) {
return "luaL_newstate() failed";
}
#if LUA_VERSION_NUM >= 505
ffluaL_openselectedlibs(L, LUA_GLIBK | LUA_MATHLIBK | LUA_STRLIBK | LUA_TABLIBK, 0);
#else
ffluaL_requiref(L, LUA_GNAME, ffluaopen_base, 1);
ffluaL_requiref(L, LUA_MATHLIBNAME, ffluaopen_math, 1);
ffluaL_requiref(L, LUA_STRLIBNAME, ffluaopen_string, 1);
ffluaL_requiref(L, LUA_TABLIBNAME, ffluaopen_table, 1);
lua_settop(L, 0);
#endif
lua_pushcfunction(L, yyjsonEncode);
lua_setglobal(L, "json_encode");
luaData.L = L;
liblua = NULL; // don't close lua
return NULL;
}
#endif
+28 -7
View File
@@ -1,6 +1,5 @@
#include "common/netif.h"
#include "common/io.h"
#include "common/mallocHelper.h"
#include <net/if.h>
#include <net/if_dl.h>
@@ -98,7 +97,16 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
return false;
}
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == (pid_t) pid));
bool gotResponse = false;
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0) {
if (rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == (pid_t) pid) {
gotResponse = true;
break;
}
}
if (!gotResponse) {
return false;
}
#ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
if ((rtmsg.hdr.rtm_flags & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY))
@@ -109,8 +117,10 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
#ifndef __sun
&& sdl->sdl_len
#endif
) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
&& sdl->sdl_family == AF_LINK) {
if (sdl->sdl_nlen > IF_NAMESIZE) {
return false;
}
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
result->ifIndex = sdl->sdl_index;
@@ -171,7 +181,16 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
return false;
}
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0 && !(rtmsg.hdr.rtm_seq == 2 && rtmsg.hdr.rtm_pid == (pid_t) pid));
bool gotResponse = false;
while (recv(pfRoute, &rtmsg, sizeof(rtmsg), 0) > 0) {
if (rtmsg.hdr.rtm_seq == 2 && rtmsg.hdr.rtm_pid == (pid_t) pid) {
gotResponse = true;
break;
}
}
if (!gotResponse) {
return false;
}
#ifndef __sun // On Solaris, the RTF_GATEWAY flag is not set for default routes for some reason
if ((rtmsg.hdr.rtm_flags & (RTF_UP | RTF_GATEWAY)) == (RTF_UP | RTF_GATEWAY))
@@ -182,8 +201,10 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
#ifndef __sun
&& sdl->sdl_len
#endif
) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
&& sdl->sdl_family == AF_LINK) {
if (sdl->sdl_nlen > IF_NAMESIZE) {
return false;
}
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
result->ifIndex = sdl->sdl_index;
+6 -2
View File
@@ -65,7 +65,9 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
if ((rtm->rtm_flags & RTF_GATEWAY) && !(rtm->rtm_flags & RTF_REJECT) && (sa->sa_family == AF_INET)) {
struct sockaddr_dl* sdl = (struct sockaddr_dl*) get_rt_address(rtm, RTA_IFP);
if (sdl && sdl->sdl_family == AF_LINK) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
if (sdl->sdl_nlen > IF_NAMESIZE) {
continue;
}
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
result->ifIndex = sdl->sdl_index;
@@ -106,7 +108,9 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
if ((rtm->rtm_flags & RTF_GATEWAY) && !(rtm->rtm_flags & RTF_REJECT) && (sa->sa_family == AF_INET6)) {
struct sockaddr_dl* sdl = (struct sockaddr_dl*) get_rt_address(rtm, RTA_IFP);
if (sdl && sdl->sdl_family == AF_LINK) {
assert(sdl->sdl_nlen <= IF_NAMESIZE);
if (sdl->sdl_nlen > IF_NAMESIZE) {
continue;
}
memcpy(result->ifName, sdl->sdl_data, sdl->sdl_nlen);
result->ifName[sdl->sdl_nlen] = '\0';
result->ifIndex = sdl->sdl_index;
+1 -1
View File
@@ -25,7 +25,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
// TODO: Get the preferred source address
return true;
}
result->ifName[0] = '0';
result->ifName[0] = '\0';
return false;
}
+1 -1
View File
@@ -71,7 +71,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
}
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET6);
FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET6, SOCK_RAW, AF_INET6);
if (pfRoute < 0) {
return false;
}
+2 -6
View File
@@ -1,5 +1,4 @@
#include "common/netif.h"
#include "common/mallocHelper.h"
#include <ws2tcpip.h> // AF_INET6, IN6_IS_ADDR_UNSPECIFIED
#include <iphlpapi.h>
@@ -7,7 +6,7 @@
bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
PMIB_IPFORWARD_TABLE2 pIpForwardTable = NULL;
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_UNSPEC, &pIpForwardTable))) {
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET, &pIpForwardTable))) {
return false;
}
@@ -18,7 +17,6 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
MIB_IPFORWARD_ROW2* row = &pIpForwardTable->Table[i];
if (row->DestinationPrefix.PrefixLength == 0 &&
row->DestinationPrefix.Prefix.Ipv4.sin_family == AF_INET &&
row->DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr == 0) {
MIB_IF_ROW2 ifRow = {
.InterfaceIndex = row->InterfaceIndex,
@@ -39,7 +37,6 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
smallestMetric = realMetric;
result->ifIndex = row->InterfaceIndex;
foundDefault = true;
break;
}
}
}
@@ -53,7 +50,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) {
bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
PMIB_IPFORWARD_TABLE2 pIpForwardTable = NULL;
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_UNSPEC, &pIpForwardTable))) {
if (!NETIO_SUCCESS(GetIpForwardTable2(AF_INET6, &pIpForwardTable))) {
return false;
}
@@ -64,7 +61,6 @@ bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) {
MIB_IPFORWARD_ROW2* row = &pIpForwardTable->Table[i];
if (row->DestinationPrefix.PrefixLength == 0 &&
row->DestinationPrefix.Prefix.Ipv6.sin6_family == AF_INET6 &&
IN6_IS_ADDR_UNSPECIFIED(&row->DestinationPrefix.Prefix.Ipv6.sin6_addr)) {
MIB_IF_ROW2 ifRow = {
.InterfaceIndex = row->InterfaceIndex,
+11 -3
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "common/library.h"
#include "common/networking.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/debug.h"
#ifdef FF_HAVE_ZLIB
@@ -146,16 +146,24 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd) {
result = zlibData.ffinflate(&zs, Z_FINISH);
}
// Check for decompression errors before using result
if (result != Z_STREAM_END) {
FF_DEBUG("Decompression failed with zlib error: %d", result);
zlibData.ffinflateEnd(&zs);
return false;
}
zlibData.ffinflateEnd(&zs);
// Calculate decompressed size
// Calculate decompressed size (from the last inflate call)
uint32_t decompressedSize = (uint32_t) (availableOut - zs.avail_out);
decompressedBuffer.length += decompressedSize;
decompressedBuffer.chars[decompressedBuffer.length] = '\0';
FF_DEBUG("Successfully decompressed %u bytes compressed data to %u bytes", compressedSize, decompressedBuffer.length);
// Modify Content-Length header and remove Content-Encoding header
FF_STRBUF_AUTO_DESTROY newBuffer = ffStrbufCreateA(headerSize + decompressedSize + 64);
// Use decompressedBuffer.length (total) not decompressedSize (last chunk only)
FF_STRBUF_AUTO_DESTROY newBuffer = ffStrbufCreateA(headerSize + decompressedBuffer.length + 64);
char* line = NULL;
size_t len = 0;
+9 -9
View File
@@ -2,7 +2,7 @@
#include "common/networking.h"
#include "common/time.h"
#include "common/library.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/mallocHelper.h"
#include "common/debug.h"
@@ -448,7 +448,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
// Check for Content-Length header to pre-allocate enough memory
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
if (clHeader) {
contentLength = (uint32_t) strtoul(clHeader + 16, NULL, 10);
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
if (contentLength > 0) {
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
// Ensure buffer is large enough, adding header size and some margin
@@ -473,18 +473,18 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
FF_DEBUG("No HTTP header end marker found");
return "No HTTP header end found";
}
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
return "Invalid response";
}
FF_DEBUG("Received valid HTTP 200 response, content %u bytes, total %u bytes", contentLength, buffer->length);
if (contentLength > 0 && buffer->length != contentLength + headerEnd + 4) {
FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + headerEnd + 4);
return "Content length mismatch";
}
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
FF_DEBUG("Received valid HTTP 200 response, content %u bytes, total %u bytes", contentLength, buffer->length);
} else {
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
return "Invalid response";
}
// If compression was used, try to decompress
#ifdef FF_HAVE_ZLIB
if (state->compression) {
+11 -11
View File
@@ -4,7 +4,7 @@
// Must be included after <mswsock.h>
#include "fastfetch.h"
#include "common/networking.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/debug.h"
static LPFN_CONNECTEX ConnectEx;
@@ -320,7 +320,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
// Check for Content-Length header to pre-allocate enough memory
const char* clHeader = strcasestr(buffer->chars, "Content-Length:");
if (clHeader) {
contentLength = (uint32_t) strtoul(clHeader + 16, NULL, 10);
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
if (contentLength > 0) {
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
// Ensure buffer is large enough, adding header size and some margin
@@ -345,20 +345,20 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
FF_DEBUG("No HTTP header end marker found");
return "No HTTP header end found";
}
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
return "Invalid response";
}
FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes",
contentLength,
buffer->length);
if (contentLength > 0 && buffer->length != contentLength + headerEnd + 4) {
FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + headerEnd + 4);
return "Content length mismatch";
}
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes",
contentLength,
buffer->length);
} else {
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
return "Invalid response";
}
// If compression was used, try to decompress
#ifdef FF_HAVE_ZLIB
if (state->compression) {
+11 -7
View File
@@ -1,10 +1,14 @@
#include "fastfetch.h"
#include "common/option.h"
#include "common/color.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include <limits.h>
// Return start position of the inner key if the argument key belongs to the module specified, NULL otherwise
const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName) {
assert(argumentKey && moduleName);
const char* subKey = argumentKey;
if (!(subKey[0] == '-' && subKey[1] == '-')) {
return NULL;
@@ -47,13 +51,13 @@ uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) {
}
char* end;
uint32_t num = (uint32_t) strtoul(value, &end, 10);
if (*end != '\0') {
unsigned long num = strtoul(value, &end, 10);
if (value[0] == '-' || *end != '\0' || num > UINT32_MAX) {
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
exit(479);
}
return num;
return (uint32_t) num;
}
int32_t ffOptionParseInt32(const char* argumentKey, const char* value) {
@@ -63,13 +67,13 @@ int32_t ffOptionParseInt32(const char* argumentKey, const char* value) {
}
char* end;
int32_t num = (int32_t) strtol(value, &end, 10);
if (*end != '\0') {
long num = strtol(value, &end, 10);
if (*end != '\0' || num < INT32_MIN || num > INT32_MAX) {
fprintf(stderr, "Error: usage: %s <num>\n", argumentKey);
exit(479);
}
return num;
return (int32_t) num;
}
int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]) {
+10 -2
View File
@@ -1,8 +1,6 @@
#include "fastfetch.h"
#include "common/parsing.h"
#include <ctype.h>
#ifdef _WIN32
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
@@ -101,6 +99,16 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK3]");
}
} else if (gtk2->length > 0 && gtk4->length > 0) {
if (ffStrbufIgnCaseEqual(gtk2, gtk4)) {
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK2/4]");
} else {
ffStrbufAppend(buffer, gtk2);
ffStrbufAppendS(buffer, " [GTK2], ");
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK4]");
}
} else if (gtk3->length > 0 && gtk4->length > 0) {
if (ffStrbufIgnCaseEqual(gtk3, gtk4)) {
ffStrbufAppend(buffer, gtk4);
+1 -9
View File
@@ -1,6 +1,6 @@
#include "common/path.h"
#include "common/io.h"
#include "common/arrayUtils.h"
#include "common/arrutil.h"
#if !_WIN32
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) {
@@ -128,13 +128,6 @@ char* frealpath(HANDLE hFile, char* resolved_name) {
errno = E2BIG;
return NULL;
}
if (outBytes > MAX_PATH) {
errno = E2BIG;
return NULL;
}
return resolved_name;
} else {
/* UTF-8 worst-case: up to 4 bytes per UTF-16 code unit */
char tmp[(MAX_PATH + 4) * 4];
@@ -152,7 +145,6 @@ char* frealpath(HANDLE hFile, char* resolved_name) {
}
memcpy(resolved_name, tmp, outBytes);
return resolved_name;
}
return resolved_name;
+9 -5
View File
@@ -4,7 +4,7 @@
#include "common/option.h"
#include "common/jsonconfig.h"
#include "common/textModifier.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module) {
if (module->outputColor.length) {
@@ -59,9 +59,6 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConf
const bool borderAsValue = options->barBorderLeftElapsed.length && options->barBorderRightElapsed.length;
uint8_t blocksPercent = (uint8_t) (percent / 100.0 * options->barWidth + 0.5);
assert(blocksPercent <= options->barWidth);
if (!borderAsValue && options->barBorderLeft.length) {
if (!options->pipe && options->barColorBorder.length > 0) {
ffStrbufAppendF(buffer, "\e[%sm", options->barColorBorder.chars);
@@ -86,6 +83,9 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConf
FFPercentageTypeFlags percentType = config.type == 0 ? options->percentType : config.type;
uint8_t blocksPercent = (uint8_t) (percent / 100.0 * options->barWidth + 0.5);
assert(blocksPercent <= options->barWidth);
bool autoColorElapsed = ffStrbufIgnCaseEqualS(&options->barColorElapsed, "auto");
bool monochrome = (percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT) || !autoColorElapsed;
@@ -190,7 +190,11 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConf
}
}
}
ffStrbufAppendF(buffer, "%*.*f%s%%", options->percentWidth, options->percentNdigits, percent, options->percentSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
if (percent == -DBL_MAX) {
ffStrbufAppendS(buffer, "-");
} else {
ffStrbufAppendF(buffer, "%*.*f%s%%", options->percentWidth, options->percentNdigits, percent, options->percentSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_ALWAYS ? " " : "");
}
if (colored && !options->pipe) {
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
+14 -6
View File
@@ -81,16 +81,24 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
}
}
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
bool ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (moduleArgs) {
ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
bool success;
if (__builtin_expect(moduleArgs != NULL, 1)) {
success = ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
} else {
ffStrbufAppendS(&buffer, "unknown");
ffStrbufSetStatic(&buffer, "undefined format");
success = false;
}
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
ffStrbufPutTo(&buffer, stdout);
if (success) {
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
ffStrbufPutTo(&buffer, stdout);
} else {
ffPrintError(moduleName, moduleIndex, moduleArgs, printType, "%s", buffer.chars);
}
return success;
}
void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...) {
+1 -1
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "common/processing.h"
#include "common/io.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
#include "common/mallocHelper.h"
#include <stdlib.h>
+1 -1
View File
@@ -55,7 +55,7 @@ bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buff
++(*line);
}
// Allow faster parsing of quotet values
// Allow faster parsing of quoted values
if (**line == '"' || **line == '\'') {
valueEnd = **line;
++(*line);
+133 -4
View File
@@ -220,11 +220,12 @@ FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName,
}
if (type == FF_VARIANT_TYPE_INT) {
int32_t value;
int64_t value;
if (ffDBusGetInt(&dbus, &rootIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .intValue = value };
return (FFvariant) { .intValue = (int32_t) value };
}
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
@@ -234,6 +235,7 @@ FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName,
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .strValue = value.chars }; // Leaks value.chars
}
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
@@ -245,6 +247,7 @@ FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName,
}
}
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
@@ -292,11 +295,12 @@ FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* pro
dbus.lib->ffdbus_message_iter_next(&dictIterator);
if (type == FF_VARIANT_TYPE_INT) {
int32_t value;
int64_t value;
if (ffDBusGetInt(&dbus, &dictIterator, &value)) {
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .intValue = value };
return (FFvariant) { .intValue = (int32_t) value };
}
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
@@ -306,6 +310,7 @@ FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* pro
dbus.lib->ffdbus_message_unref(reply);
return (FFvariant) { .strValue = value.chars }; // Leaks value.chars
}
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
@@ -317,9 +322,11 @@ FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* pro
}
}
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
dbus.lib->ffdbus_message_unref(reply);
return FF_VARIANT_NULL;
}
#else // FF_HAVE_DBUS
@@ -478,3 +485,125 @@ bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result) {
return true;
}
#endif
#ifdef FF_HAVE_EET
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wfloat-conversion"
#include <Eet.h>
#pragma GCC diagnostic pop
typedef struct E_Font_Default {
char* text_class;
char* font;
int size;
} E_Font_Default;
typedef struct E_Config {
char* theme_default_border_style;
char* icon_theme;
int use_e_cursor;
int cursor_size;
char* desktop_default_background;
Eina_List* font_defaults;
} E_Config; // Must be the same name as the top level struct in e.cfg
#define FF_EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(clas, type) \
(ffeet_eina_file_data_descriptor_class_set(clas, sizeof(*(clas)), #type, sizeof(type)))
#define FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, member, type) \
do { \
struct_type ___ett; \
ffeet_data_descriptor_element_add(edd, #member, type, EET_G_UNKNOWN, (char*) (&(___ett.member)) - (char*) (&(___ett)), 0, /* 0, */ NULL, NULL); \
} while (0)
#define FF_EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, member, subtype) \
do { \
struct_type ___ett; \
ffeet_data_descriptor_element_add(edd, #member, EET_T_UNKNOW, EET_G_LIST, (char*) (&(___ett.member)) - (char*) (&(___ett)), 0, /* 0, */ NULL, subtype); \
} while (0)
bool ffSettingsGetEnlightenmentProperty(ffEnlightenmentSettings* result) {
FF_LIBRARY_LOAD(libeet, false, "libeet" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_init, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_open, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_data_descriptor_file_new, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_data_read, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_close, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_shutdown, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_data_descriptor_free, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_eina_file_data_descriptor_class_set, false);
FF_LIBRARY_LOAD_SYMBOL(libeet, eet_data_descriptor_element_add, false);
if (ffeet_init() == 0) {
return false;
}
FF_STRBUF_AUTO_DESTROY fileName = ffStrbufCreateCopy(&instance.state.platform.homeDir);
ffStrbufAppendS(&fileName, ".e/e/config/standard/e.cfg");
Eet_File* ef = ffeet_open(fileName.chars, EET_FILE_MODE_READ);
if (!ef) {
ffeet_shutdown();
return false;
}
Eet_Data_Descriptor_Class fontDdc;
FF_EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&fontDdc, E_Font_Default);
Eet_Data_Descriptor* fontDdd = ffeet_data_descriptor_file_new(&fontDdc);
if (!fontDdd) {
ffeet_close(ef);
ffeet_shutdown();
return false;
}
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(fontDdd, E_Font_Default, text_class, EET_T_STRING);
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(fontDdd, E_Font_Default, font, EET_T_STRING);
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(fontDdd, E_Font_Default, size, EET_T_INT);
Eet_Data_Descriptor_Class eddc;
FF_EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, E_Config);
Eet_Data_Descriptor* edd = ffeet_data_descriptor_file_new(&eddc);
if (!edd) {
ffeet_data_descriptor_free(fontDdd);
ffeet_close(ef);
ffeet_shutdown();
return false;
}
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, E_Config, theme_default_border_style, EET_T_STRING);
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, E_Config, icon_theme, EET_T_STRING);
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, E_Config, use_e_cursor, EET_T_INT);
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, E_Config, cursor_size, EET_T_INT);
FF_EET_DATA_DESCRIPTOR_ADD_BASIC(edd, E_Config, desktop_default_background, EET_T_STRING);
FF_EET_DATA_DESCRIPTOR_ADD_LIST(edd, E_Config, font_defaults, fontDdd);
E_Config* parsed = ffeet_data_read(ef, edd, "config");
if (parsed) {
// TODO: find a better method to get the main theme name
result->theme = parsed->theme_default_border_style;
result->icon_theme = parsed->icon_theme;
result->use_e_cursor = !!parsed->use_e_cursor;
result->cursor_size = parsed->cursor_size;
result->desktop_default_background = parsed->desktop_default_background;
E_Font_Default* firstFont = eina_list_data_get(parsed->font_defaults);
if (firstFont) {
result->font = firstFont->font;
}
}
ffeet_close(ef);
ffeet_data_descriptor_free(edd);
ffeet_data_descriptor_free(fontDdd);
if (!parsed) {
// We don't shutdown eet so that `result->*` are not freed
ffeet_shutdown();
}
return !!parsed;
}
#else
bool ffSettingsGetEnlightenmentProperty(FF_A_UNUSED ffEnlightenmentSettings* result) {
return false;
}
#endif
+80
View File
@@ -0,0 +1,80 @@
#include "common/strutil.h"
uint8_t ffUtf8CharLenWidth(const char* str, uint32_t length, uint8_t* width) {
if (__builtin_expect(length == 0 || *str == '\0', false)) {
if (width) {
*width = 0;
}
return 0;
}
unsigned char first = (unsigned char) *str;
if (__builtin_expect(first < 0x80, true)) {
if (width) {
*width = 1;
}
return 1;
}
uint8_t bytes;
if ((first & 0xE0) == 0xC0) {
bytes = 2;
} else if ((first & 0xF0) == 0xE0) {
bytes = 3;
} else if ((first & 0xF8) == 0xF0) {
bytes = 4;
} else {
if (width) {
*width = 1;
}
return 1;
}
if (length < bytes) {
if (width) {
*width = 1;
}
return 1;
}
for (uint8_t i = 1; i < bytes; ++i) {
unsigned char continuation = (unsigned char) str[i];
if (continuation == '\0' || (continuation & 0xC0) != 0x80) {
if (width) {
*width = 1;
}
return 1;
}
}
uint32_t ucs = (uint32_t) (first & ((1U << (8 - bytes)) - 1));
for (uint8_t i = 1; i < bytes; ++i) {
ucs <<= 6;
ucs |= (uint32_t) ((unsigned char) str[i] & 0x3F);
}
int wcWidth = mk_wcwidth(ucs);
if (width) {
*width = (uint8_t) (wcWidth < 0 ? 0 : wcWidth);
}
return bytes;
}
uint32_t ffUtf8StrWidth(const char* str, uint32_t length) {
uint32_t result = 0;
const char* ptr = str;
while (length > 0 && *ptr != '\0') {
uint8_t width = 0;
uint8_t bytes = ffUtf8CharLenWidth(ptr, length, &width);
if (__builtin_expect(bytes == 0, false)) {
break;
}
result += width;
ptr += bytes;
length -= bytes;
}
return result > 0 ? result : (uint32_t) (ptr - str);
}
+4 -5
View File
@@ -47,10 +47,12 @@ const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
if (sysctlbyname(propName, result->chars + result->length, &neededLength, NULL, 0) == 0) {
result->length += (uint32_t) neededLength - 1;
if (sysctlbyname(propName, result->chars + result->length, &neededLength, NULL, 0) != 0) {
return "sysctlbyname() failed to retrieve string data";
}
result->length += (uint32_t) neededLength - 1;
result->chars[result->length] = '\0';
return NULL;
@@ -81,9 +83,6 @@ void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength) {
}
void* data = malloc(*resultLength);
if (data == NULL) {
return NULL;
}
if (sysctl(request, requestLength, data, resultLength, NULL, 0) != 0) {
free(data);
+13 -3
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "common/temps.h"
#include "common/textModifier.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
void ffTempsAppendNum(double celsius, FFstrbuf* buffer, FFColorRangeConfig config, const FFModuleArgs* module) {
if (celsius == -DBL_MAX) { // ignores invalid value
@@ -123,7 +123,12 @@ bool ffTempsParseJsonObject(yyjson_val* key, yyjson_val* value, bool* useTemp, F
yyjson_val* greenVal = yyjson_obj_get(value, "green");
if (greenVal) {
int num = yyjson_get_int(greenVal);
if (!yyjson_is_int(greenVal)) {
fputs("Error: usage: temp.green must be an integer between 0 and 100\n", stderr);
exit(480);
}
int num = unsafe_yyjson_get_int(greenVal);
if (num < 0 || num > 100) {
fputs("Error: usage: temp.green must be between 0 and 100\n", stderr);
exit(480);
@@ -133,7 +138,12 @@ bool ffTempsParseJsonObject(yyjson_val* key, yyjson_val* value, bool* useTemp, F
yyjson_val* yellowVal = yyjson_obj_get(value, "yellow");
if (yellowVal) {
int num = yyjson_get_int(yellowVal);
if (!yyjson_is_int(yellowVal)) {
fputs("Error: usage: temp.yellow must be an integer between 0 and 100\n", stderr);
exit(480);
}
int num = unsafe_yyjson_get_int(yellowVal);
if (num < 0 || num > 100) {
fputs("Error: usage: temp.yellow must be between 0 and 100\n", stderr);
exit(480);
+5 -5
View File
@@ -19,11 +19,11 @@ int mk_wcwidth(uint32_t wc) {
case widechar_widened_in_9:
// Our renderer supports Unicode 9
return 2;
// case widechar_nonprint:
// case widechar_combining:
// case widechar_unassigned:
// case widechar_non_character:
// return -1;
case widechar_nonprint:
case widechar_combining:
case widechar_unassigned:
case widechar_non_character:
return 0;
default:
// Use the width widechar_width gave us.
return width;
+187
View File
@@ -0,0 +1,187 @@
#pragma once
#include "fastfetch.h"
#if FF_HAVE_LUA
#if !FF_DISABLE_DLOPEN
// Hack. LUA_API is defined as extern which prevents us from implementing the functions ourselves.
#include <luaconf.h>
#undef LUA_API
#undef LUALIB_API
#undef LUAMOD_API
#define LUA_API static inline
#define LUALIB_API LUA_API
#define LUAMOD_API LUA_API
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#ifndef LUA_GNAME
#define LUA_GNAME "_G"
#endif
#include "common/library.h"
extern struct FFLuaData {
#if !FF_DISABLE_DLOPEN
FF_LIBRARY_SYMBOL(luaL_checkany)
FF_LIBRARY_SYMBOL(luaL_loadbufferx)
FF_LIBRARY_SYMBOL(luaL_tolstring)
FF_LIBRARY_SYMBOL(lua_callk)
FF_LIBRARY_SYMBOL(lua_createtable)
FF_LIBRARY_SYMBOL(lua_error)
FF_LIBRARY_SYMBOL(lua_gettop)
FF_LIBRARY_SYMBOL(lua_isinteger)
FF_LIBRARY_SYMBOL(lua_next)
FF_LIBRARY_SYMBOL(lua_pcallk)
FF_LIBRARY_SYMBOL(lua_pushboolean)
FF_LIBRARY_SYMBOL(lua_pushcclosure)
FF_LIBRARY_SYMBOL(lua_pushinteger)
FF_LIBRARY_SYMBOL(lua_pushlstring)
FF_LIBRARY_SYMBOL(lua_pushnil)
FF_LIBRARY_SYMBOL(lua_pushnumber)
FF_LIBRARY_SYMBOL(lua_pushvalue)
FF_LIBRARY_SYMBOL(lua_rawgeti)
FF_LIBRARY_SYMBOL(lua_rawlen)
FF_LIBRARY_SYMBOL(lua_setfield)
FF_LIBRARY_SYMBOL(lua_setglobal)
FF_LIBRARY_SYMBOL(lua_seti)
FF_LIBRARY_SYMBOL(lua_settop)
FF_LIBRARY_SYMBOL(lua_toboolean)
FF_LIBRARY_SYMBOL(lua_tointegerx)
FF_LIBRARY_SYMBOL(lua_tolstring)
FF_LIBRARY_SYMBOL(lua_tonumberx)
FF_LIBRARY_SYMBOL(lua_type)
#endif
lua_State* L;
bool inited;
} luaData;
#if !FF_DISABLE_DLOPEN
FF_A_ALWAYS_INLINE void(lua_settop)(lua_State* L, int idx) {
return luaData.fflua_settop(L, idx);
}
FF_A_ALWAYS_INLINE int(luaL_loadbufferx)(lua_State* L, const char* buff, size_t sz, const char* name, const char* mode) {
return luaData.ffluaL_loadbufferx(L, buff, sz, name, mode);
}
FF_A_ALWAYS_INLINE const char*(lua_tolstring) (lua_State * L, int idx, size_t* len) {
return luaData.fflua_tolstring(L, idx, len);
}
FF_A_ALWAYS_INLINE void(lua_createtable)(lua_State* L, int narr, int nrec) {
return luaData.fflua_createtable(L, narr, nrec);
}
FF_A_ALWAYS_INLINE void(lua_pushinteger)(lua_State* L, lua_Integer n) {
return luaData.fflua_pushinteger(L, n);
}
FF_A_ALWAYS_INLINE void(lua_pushnumber)(lua_State* L, lua_Number n) {
return luaData.fflua_pushnumber(L, n);
}
FF_A_ALWAYS_INLINE void(lua_pushboolean)(lua_State* L, int b) {
return luaData.fflua_pushboolean(L, b);
}
FF_A_ALWAYS_INLINE const char*(lua_pushlstring) (lua_State * L, const char* s, size_t len) {
return luaData.fflua_pushlstring(L, s, len);
}
FF_A_ALWAYS_INLINE void(lua_pushvalue)(lua_State* L, int idx) {
return luaData.fflua_pushvalue(L, idx);
}
FF_A_ALWAYS_INLINE void(lua_seti)(lua_State* L, int idx, lua_Integer n) {
return luaData.fflua_seti(L, idx, n);
}
FF_A_ALWAYS_INLINE void(lua_pushnil)(lua_State* L) {
return luaData.fflua_pushnil(L);
}
FF_A_ALWAYS_INLINE void(lua_setfield)(lua_State* L, int idx, const char* k) {
return luaData.fflua_setfield(L, idx, k);
}
FF_A_ALWAYS_INLINE int(lua_pcallk)(lua_State* L, int nargs, int nresults, int errfunc, lua_KContext ctx, lua_KFunction k) {
return luaData.fflua_pcallk(L, nargs, nresults, errfunc, ctx, k);
}
FF_A_ALWAYS_INLINE int(lua_gettop)(lua_State* L) {
return luaData.fflua_gettop(L);
}
FF_A_ALWAYS_INLINE const char*(luaL_tolstring) (lua_State * L, int idx, size_t* len) {
return luaData.ffluaL_tolstring(L, idx, len);
}
FF_A_ALWAYS_INLINE int(lua_error)(lua_State* L) {
return luaData.fflua_error(L);
}
FF_A_ALWAYS_INLINE void(lua_pushcclosure)(lua_State* L, lua_CFunction fn, int n) {
return luaData.fflua_pushcclosure(L, fn, n);
}
FF_A_ALWAYS_INLINE void(luaL_checkany)(lua_State* L, int idx) {
return luaData.ffluaL_checkany(L, idx);
}
FF_A_ALWAYS_INLINE void(lua_callk)(lua_State* L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k) {
return luaData.fflua_callk(L, nargs, nresults, ctx, k);
}
FF_A_ALWAYS_INLINE int(lua_isinteger)(lua_State* L, int idx) {
return luaData.fflua_isinteger(L, idx);
}
FF_A_ALWAYS_INLINE int(lua_next)(lua_State* L, int idx) {
return luaData.fflua_next(L, idx);
}
FF_A_ALWAYS_INLINE int(lua_rawgeti)(lua_State* L, int idx, lua_Integer n) {
return luaData.fflua_rawgeti(L, idx, n);
}
FF_A_ALWAYS_INLINE
#if LUA_VERSION_NUM > 503
lua_Unsigned
#else
size_t
#endif
(lua_rawlen)(lua_State* L, int idx) {
return luaData.fflua_rawlen(L, idx);
}
FF_A_ALWAYS_INLINE void(lua_setglobal)(lua_State* L, const char* name) {
return luaData.fflua_setglobal(L, name);
}
FF_A_ALWAYS_INLINE int(lua_toboolean)(lua_State* L, int idx) {
return luaData.fflua_toboolean(L, idx);
}
FF_A_ALWAYS_INLINE lua_Integer(lua_tointegerx)(lua_State* L, int idx, int* isnum) {
return luaData.fflua_tointegerx(L, idx, isnum);
}
FF_A_ALWAYS_INLINE lua_Number(lua_tonumberx)(lua_State* L, int idx, int* isnum) {
return luaData.fflua_tonumberx(L, idx, isnum);
}
FF_A_ALWAYS_INLINE int(lua_type)(lua_State* L, int idx) {
return luaData.fflua_type(L, idx);
}
#endif
const char* ffLuaLoadState(void);
#endif
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include "common/FFstrbuf.h"
#include "common/stringUtils.h"
#include "common/strutil.h"
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result);
static inline bool ffIsAbsolutePath(const char* path) {
+1 -1
View File
@@ -13,7 +13,7 @@ typedef enum FF_A_PACKED FFPrintType {
} FFPrintType;
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType);
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
bool ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, arguments) \
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (sizeof(arguments) / sizeof(*arguments)), (arguments));
FF_A_PRINTF(5, 6) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
+10
View File
@@ -30,6 +30,16 @@ FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* pro
int ffSettingsGetSQLite3Int(const char* dbPath, const char* query);
bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result);
typedef struct {
char* theme;
char* icon_theme;
bool use_e_cursor;
int cursor_size;
char* desktop_default_background;
char* font;
} ffEnlightenmentSettings;
bool ffSettingsGetEnlightenmentProperty(ffEnlightenmentSettings* result);
#ifdef __ANDROID__
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
#elif defined(__FreeBSD__)
@@ -5,6 +5,14 @@
#include <string.h>
#include <ctype.h>
#include "common/wcwidth.h"
#ifdef _WIN32
// #include <shlwapi.h>
__stdcall char* StrStrIA(const char* lpFirst, const char* lpSrch);
#define strcasestr StrStrIA
#endif
static inline bool ffStrSet(const char* str) {
if (str == NULL) {
return false;
@@ -71,6 +79,13 @@ static inline bool ffCharIsDigit(char c) {
return '0' <= c && c <= '9';
}
// Parse one UTF-8 character, returning consumed byte count and display width.
// Invalid / incomplete sequence falls back to one-byte width=1.
// If the Unicode codepoint is non-printable, width becomes 0.
uint8_t ffUtf8CharLenWidth(const char* str, uint32_t length, uint8_t* width);
uint32_t ffUtf8StrWidth(const char* str, uint32_t length);
static inline bool ffCharIsHexDigit(char c) {
return ffCharIsDigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
}
+1 -1
View File
@@ -11,7 +11,7 @@
#include <OS.h>
#endif
#include "common/arrayUtils.h"
#include "common/arrutil.h"
static inline double ffTimeGetTick(void) // In msec
{
+6 -10
View File
@@ -2,15 +2,11 @@
#include <stdint.h>
#ifdef FF_HAVE_WCWIDTH
#include <wchar.h>
// Should be char32_t but it's not defined on macOS
static_assert(sizeof(wchar_t) == sizeof(uint32_t), "wcwidth implementation requires wchar_t to be 32 bits");
static inline int mk_wcwidth(uint32_t ucs) {
return wcwidth((wchar_t) ucs);
}
#else
#if FF_ENABLE_WCWIDTH
int mk_wcwidth(uint32_t wc);
#else
static inline int mk_wcwidth(uint32_t wc) {
(void) wc;
return 1;
}
#endif
+67
View File
@@ -0,0 +1,67 @@
#include "com.h"
#include <stdlib.h>
#if FF_HAVE_WINRT
#include <roapi.h>
static void RoUninitializeWrap(void) {
RoUninitialize();
}
static const char* doInitCom() {
HRESULT res = RoInitialize(RO_INIT_MULTITHREADED);
if (FAILED(res)) {
switch (res) {
case E_INVALIDARG:
return "RoInitialize() failed: invalid argument";
case E_OUTOFMEMORY:
return "RoInitialize() failed: out of memory";
case E_UNEXPECTED:
return "RoInitialize() failed: unexpected error";
case RPC_E_CHANGED_MODE:
// COM was already initialized with a different concurrency model
return NULL;
default:
return "RoInitialize() failed: unknown error";
}
}
atexit(RoUninitializeWrap);
return NULL;
}
#else
#include <combaseapi.h>
static void CoUninitializeWrap(void) {
CoUninitialize();
}
static const char* doInitCom() {
HRESULT res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(res)) {
switch (res) {
case E_INVALIDARG:
return "CoInitializeEx() failed: invalid argument";
case E_OUTOFMEMORY:
return "CoInitializeEx() failed: out of memory";
case RPC_E_CHANGED_MODE:
// COM was already initialized with a different concurrency model
return NULL;
default:
return "CoInitializeEx() failed: unknown error";
}
}
atexit(CoUninitializeWrap);
return NULL;
}
#endif
const char* ffInitCom(void) {
static const char* error = "";
if (error && error[0] == '\0') {
error = doInitCom();
}
return error;
}
-47
View File
@@ -1,47 +0,0 @@
#include "com.hpp"
#include "fastfetch.h"
#include <stdlib.h>
// https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--getting-wmi-data-from-the-local-computer
// https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/computer-system-hardware-classes
static void CoUninitializeWrap(void) {
CoUninitialize();
}
static const char* doInitCom() {
// Initialize COM
if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) {
return "CoInitializeEx() failed";
}
// Set general COM security levels
HRESULT hRes = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
if (FAILED(hRes) && hRes != RPC_E_TOO_LATE /* Has been set by a random dll */) {
CoUninitialize();
return "CoInitializeSecurity() failed";
}
atexit(CoUninitializeWrap);
return NULL;
}
const char* ffInitCom(void) {
static const char* error = "";
if (error && error[0] == '\0') {
error = doInitCom();
}
return error;
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "common/attributes.h"
#include <assert.h>
#include <unknwn.h>
// Initialize COM & WinRT
const char* ffInitCom(void);
static inline void ffReleaseComObject(void* ppUnknown) {
assert(ppUnknown);
IUnknown* pUnknown = *(IUnknown**) ppUnknown;
if (pUnknown) {
#ifdef __cplusplus
pUnknown->Release();
#else
pUnknown->lpVtbl->Release(pUnknown);
#endif
*(IUnknown**) ppUnknown = NULL;
}
}
#define FF_AUTO_RELEASE_COM_OBJECT FF_A_CLEANUP(ffReleaseComObject)
-21
View File
@@ -1,21 +0,0 @@
#pragma once
#ifdef __cplusplus
#include <unknwn.h>
const char* ffInitCom(void);
static inline void ffReleaseComObject(void* ppUnknown) {
IUnknown* pUnknown = *(IUnknown**) ppUnknown;
if (pUnknown) {
pUnknown->Release();
}
}
#define FF_AUTO_RELEASE_COM_OBJECT FF_A_CLEANUP(ffReleaseComObject)
#else
// Win32 COM headers requires C++ compiler
#error Must be included in C++ source file
#endif

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