mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 823f2ef028 | |||
| 11cfdba5cb | |||
| 5b78b2e897 | |||
| 773b8db337 | |||
| d15d4c621c | |||
| 788cad3cbe | |||
| f6ccbf7711 | |||
| e6fb545d1d | |||
| ce7ecd3863 | |||
| c8d85e09d7 | |||
| 34bc662065 | |||
| a54cbee79a | |||
| df873a19e1 | |||
| b5695b50c2 | |||
| f22b8ede02 | |||
| 893b3a6bff | |||
| e199a2fb79 | |||
| b4aac9d7d7 | |||
| cf9bd0f373 | |||
| 17deaf963e | |||
| e66a83a4cf | |||
| 96905012a4 | |||
| 591dba8829 | |||
| d10dd2095a | |||
| 22e25d0c78 | |||
| 1c8375908c | |||
| 099a390f2f | |||
| dd2d343630 | |||
| 543eed9a53 | |||
| 4860bc35d6 | |||
| 8559ab2dcd | |||
| 811485661f | |||
| 31ead528f1 | |||
| 8641442c3f | |||
| 418902512d | |||
| fbfe2b2d1a | |||
| f71c4f6d5a | |||
| b46d9d8b8e | |||
| 9d27106964 | |||
| bbb873c27b | |||
| da50a48dd5 | |||
| c8e4de9831 | |||
| e0d733f030 | |||
| ff8e0e72d2 | |||
| 63971fd245 | |||
| 6b6827b915 | |||
| 7447a95299 | |||
| bfdcab5b57 | |||
| 01c202bd93 | |||
| 0c2953ac66 | |||
| c0774b89d6 | |||
| 030f34d405 | |||
| cedc93fe7b | |||
| e155767289 | |||
| 4e41223b81 | |||
| 2ee4d7daac | |||
| a6a0a03b44 | |||
| 4b3241a286 | |||
| d37bf7252d | |||
| dd66626165 | |||
| fe7e684e85 | |||
| 2281caaff8 | |||
| 96c838d3f3 | |||
| c6e1677369 | |||
| ea18d93a40 | |||
| f6e1e5c96b | |||
| 0b85fc74eb | |||
| 946eb0eacd | |||
| a11ec589f0 | |||
| a89955b080 | |||
| df4350666a | |||
| 55b1603b83 | |||
| fb1c727641 | |||
| 87d964c7ca | |||
| bdb0a9262c | |||
| e42dfe63c3 | |||
| e8932895e8 | |||
| 4091d33c56 |
@@ -422,7 +422,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 libelf glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd v4l_compat
|
||||
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm libelf glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
|
||||
@@ -1,3 +1,50 @@
|
||||
# 2.22.0
|
||||
|
||||
Features:
|
||||
* Small performance improvements (Terminal, Editor)
|
||||
* Improve arm32 and loongarch support (CPU, Linux)
|
||||
* Ignore the parent process if env `$FFTS_IGNORE_PARENT` is set to `1` (Shell)
|
||||
* Add code name of Apple M4 (CPU, Linux)
|
||||
* Add ethernet speed rate detection support (LocalIP)
|
||||
* Add zsh completion script
|
||||
* Add Linglong package manager detection support (Packages, Linux)
|
||||
|
||||
Bugfixes:
|
||||
* Fix building on macOS 10.14
|
||||
* Fix tmux in linux TTY (Colors)
|
||||
* Fix hang in WSL when custom format is used (Disk, Linux)
|
||||
* Fix `/proc/loadavg` parsing (Loadavg, Linux)
|
||||
* Disable use of `LC_NUMERIC` locale settings to fix parsing of decimal numbers
|
||||
* Fix possible segfault (DiskIO, Linux)
|
||||
* Honor `preciseRefreshRate` in custom format (Display)
|
||||
|
||||
Logos:
|
||||
* Add Lingmo OS
|
||||
* Add Sleeper OS
|
||||
|
||||
# 2.21.3
|
||||
|
||||
Bugfixes:
|
||||
* Fix bad Intel Arc GPU name detection, which was supposed to be fixed in the last version but the change was reverted accidentally (#1177, GPU, Linux)
|
||||
* Fix arm32 CPU name detection no longer work. Regression of 2.21.2 (CPU, Linux)
|
||||
|
||||
# 2.21.2
|
||||
|
||||
Features:
|
||||
* Support `--stat <num_in_ms>` to display long running modules in yellow or red
|
||||
|
||||
Bugfixes:
|
||||
* Fix bad Intel Arc GPU name and type detection (GPU, Linux)
|
||||
* Fix uninited struct fields (GPU, Linux)
|
||||
* Skip cpu model smbios detection on ARM platforms (CPU, Linux)
|
||||
* Always use `CurrentControlSet` instead of `ControlSet001` when querying registry (Windows)
|
||||
* Fix NVIDIA GPUs are missing in GPU detection sometimes (GPU, Windows)
|
||||
* Fixing detection of `pthread_timedjoin_np` (Linux)
|
||||
|
||||
Logos:
|
||||
* Add HyprOS
|
||||
* Add GoldenDog Linux
|
||||
|
||||
# 2.21.1
|
||||
|
||||
Hotfix for a regression that breaks WM detection when running `startx` from TTY (Regression from 2.21.0, #1172 / #1162)
|
||||
|
||||
+29
-12
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.21.1
|
||||
VERSION 2.22.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -69,7 +69,7 @@ cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||
@@ -401,6 +401,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/util/base64.c
|
||||
src/util/FFlist.c
|
||||
src/util/FFstrbuf.c
|
||||
src/util/path.c
|
||||
src/util/platform/FFPlatform.c
|
||||
src/util/smbiosHelper.c
|
||||
)
|
||||
@@ -481,7 +482,7 @@ if(LINUX)
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/linux/elf.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -543,6 +544,7 @@ elseif(ANDROID)
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
src/detection/camera/camera_android.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(FreeBSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -621,7 +623,7 @@ elseif(FreeBSD)
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/linux/elf.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -687,6 +689,7 @@ elseif(APPLE)
|
||||
src/util/apple/cf_helpers.c
|
||||
src/util/apple/osascript.m
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_apple.c
|
||||
)
|
||||
elseif(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -753,6 +756,7 @@ elseif(WIN32)
|
||||
src/util/windows/unicode.c
|
||||
src/util/windows/wmi.cpp
|
||||
src/util/platform/FFPlatform_windows.c
|
||||
src/util/binary_windows.c
|
||||
)
|
||||
elseif(SunOS)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -829,7 +833,7 @@ elseif(SunOS)
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/linux/elf.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -1135,6 +1139,7 @@ elseif(WIN32)
|
||||
PRIVATE "setupapi"
|
||||
PRIVATE "hid"
|
||||
PRIVATE "wtsapi32"
|
||||
PRIVATE "imagehlp"
|
||||
)
|
||||
elseif(FreeBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1210,13 +1215,19 @@ if(NOT WIN32)
|
||||
if(HAVE_WORDEXP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WORDEXP=1)
|
||||
endif()
|
||||
CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP)
|
||||
if(HAVE_PTHREAD_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_PTHREAD_NP=1)
|
||||
endif()
|
||||
check_function_exists("pthread_timedjoin_np" HAVE_TIMEDJOIN_NP)
|
||||
if(HAVE_TIMEDJOIN_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_TIMEDJOIN_NP=1)
|
||||
if(ENABLE_THREADS AND CMAKE_USE_PTHREADS_INIT)
|
||||
CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP)
|
||||
if(HAVE_PTHREAD_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_PTHREAD_NP=1)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} pthread_np.h)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} Threads::Threads)
|
||||
check_function_exists("pthread_timedjoin_np" HAVE_TIMEDJOIN_NP)
|
||||
if(HAVE_TIMEDJOIN_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_TIMEDJOIN_NP=1)
|
||||
else()
|
||||
message(WARNING "pthread_timedjoin_np was not found; networking timeout will not work")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1326,6 +1337,12 @@ install(
|
||||
RENAME "${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.zsh"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/zsh/site-functions"
|
||||
RENAME "_${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.fish"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/fish/vendor_completions.d"
|
||||
|
||||
@@ -30,17 +30,23 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
|
||||
Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version.
|
||||
|
||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||
* Debian: `sudo apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian: `apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
|
||||
* Arch Linux: `pacman -S fastfetch`
|
||||
* Fedora: `dnf install fastfetch`
|
||||
* Gentoo: `emerge --ask app-misc/fastfetch`
|
||||
* Alpine: `apk add --upgrade fastfetch`
|
||||
* NixOS: `nix-shell -p fastfetch`
|
||||
* openSUSE: `sudo zypper install fastfetch`
|
||||
* ALT Linux: `sudo apt-get install fastfetch`
|
||||
* openSUSE: `zypper install fastfetch`
|
||||
* ALT Linux: `apt-get install fastfetch`
|
||||
* Exherbo: `cave resolve --execute app-misc/fastfetch`
|
||||
* GNU Guix: `guix install fastfetch`
|
||||
* Solus: `eopkg install fastfetch`
|
||||
* Slackware: `sbopkg -i fastfetch`
|
||||
* Void Linux: `xbps-install fastfetch`
|
||||
* Venom Linux: `scratch install fastfetch`
|
||||
|
||||
Replace sudo with doas depending on what you use.
|
||||
You may need `sudo`, `doas` or `sup` to run these commands.
|
||||
|
||||
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging).
|
||||
|
||||
@@ -54,8 +60,9 @@ If fastfetch is not packaged for your distro or an outdated version is packaged,
|
||||
### Windows
|
||||
|
||||
* [scoop](https://scoop.sh/#/apps?q=fastfetch): `scoop install fastfetch`
|
||||
* [Chocolatey](https://community.chocolatey.org/packages/fastfetch): `choco install fastfetch`
|
||||
* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch`
|
||||
* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
* [MSYS2 MinGW](https://packages.msys2.org/base/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
|
||||
You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file.
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#compdef fastfetch
|
||||
|
||||
function _fastfetch() {
|
||||
local state
|
||||
|
||||
local -a opts
|
||||
opts=(${(f)"$(
|
||||
python <<EOF
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
data: dict[str, list[dict]] = json.loads(
|
||||
subprocess.check_output(["fastfetch", "--help-raw"])
|
||||
)
|
||||
|
||||
for key in data:
|
||||
for flag in data[key]:
|
||||
if flag.get("pseudo", False):
|
||||
continue
|
||||
|
||||
if "short" in flag:
|
||||
command_prefix = f"""-{flag["short"]}[{flag["desc"]}]"""
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
if "long" in flag:
|
||||
command_prefix = f"""--{flag["long"]}[{flag["desc"]}]"""
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
|
||||
def print_command(command_prefix: str, flag: dict):
|
||||
if "arg" in flag:
|
||||
type: str = flag["arg"]["type"]
|
||||
if type == "bool":
|
||||
print(f"{command_prefix}:bool:(true false)")
|
||||
elif type == "color":
|
||||
print(f"{command_prefix}:color:(black red green yellow blue magenta cyan white default)")
|
||||
elif type == "command":
|
||||
print(f"{command_prefix}:module:->modules")
|
||||
elif type == "config":
|
||||
print(f"{command_prefix}:presets:->presets")
|
||||
elif type == "enum":
|
||||
temp: str = " ".join(flag["arg"]["enum"])
|
||||
print(f'{command_prefix}:type:( {temp} )')
|
||||
elif type == "logo":
|
||||
print(f"{command_prefix}:logo:->logo")
|
||||
elif type == "structure":
|
||||
print(f"{command_prefix}:structure:->structure")
|
||||
elif type == "path":
|
||||
print(f"{command_prefix}:path:_files -/")
|
||||
else:
|
||||
print(f"{command_prefix}:")
|
||||
else:
|
||||
print(f"{command_prefix}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
EOF
|
||||
)"})
|
||||
|
||||
_arguments -C "$opts[@]"
|
||||
|
||||
case $state in
|
||||
modules)
|
||||
local -a modules=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
|
||||
modules=( ${(L)^modules%%:*}-format format color )
|
||||
_describe 'module' modules
|
||||
;;
|
||||
presets)
|
||||
local -a presets=(
|
||||
${$(fastfetch --list-presets autocompletion):#.*}
|
||||
"none:Disable loading config file"
|
||||
)
|
||||
_describe 'preset' presets
|
||||
;;
|
||||
structure)
|
||||
local -a structures=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
|
||||
_describe 'structure' structures
|
||||
;;
|
||||
logo)
|
||||
local -a logos=(
|
||||
$(fastfetch --list-logos autocompletion)
|
||||
"none:Don't print logo"
|
||||
"small:Print small ascii logo if available"
|
||||
)
|
||||
_describe 'logo' logos
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_fastfetch "$@"
|
||||
Vendored
+18
@@ -1,3 +1,21 @@
|
||||
fastfetch (2.21.3) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.3
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 15 Aug 2024 16:14:52 +0800
|
||||
|
||||
fastfetch (2.21.2) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.2
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 14 Aug 2024 14:42:07 +0800
|
||||
|
||||
fastfetch (2.21.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 09 Aug 2024 14:27:10 +0800
|
||||
|
||||
fastfetch (2.21.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.0
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.20.0_source.buildinfo universe/utils optional
|
||||
fastfetch_2.21.3_source.buildinfo universe/utils optional
|
||||
|
||||
+11
-3
@@ -357,9 +357,17 @@
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"stat": {
|
||||
"type": "boolean",
|
||||
"description": "Show time usage (in ms) for individual modules",
|
||||
"default": false
|
||||
"description": "Show time usage (in ms) for individual modules with optional threshold",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"pipe": {
|
||||
"type": "boolean",
|
||||
|
||||
@@ -11,45 +11,51 @@
|
||||
},
|
||||
"separator": ""
|
||||
},
|
||||
"modules": [
|
||||
"modules": [
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "Vanilla ",
|
||||
"key": "[_Kernel___> ",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"outputColor": "white",
|
||||
"key": " [_Packages_> ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"outputColor": "white",
|
||||
"key": " [_Local_IP_> ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": " [_CPU______> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"format": "[{3}] {1} / {2}",
|
||||
"key": " [_RAM______> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"format": "[{3}] {1} / {2}",
|
||||
"key": " [_SWAP_____> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"format": "[{3}] {1} / {2} {9}",
|
||||
"key": " [_Disk_____> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"format": "[{4}] {5}",
|
||||
"key": " [_Battery__> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type":"colors",
|
||||
"type": "colors",
|
||||
"paddingLeft": 9,
|
||||
"symbol": "circle"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "commandoption.h"
|
||||
#include "common/color.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/time.h"
|
||||
#include "common/jsonconfig.h"
|
||||
@@ -105,32 +106,35 @@ static void parseStructureCommand(
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
//Parse the structure and call the modules
|
||||
int32_t thres = instance.config.display.stat;
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < data->structure.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
|
||||
data->structure.chars[colonIndex] = '\0';
|
||||
|
||||
uint64_t ms = 0;
|
||||
if(instance.config.display.stat)
|
||||
double ms = 0;
|
||||
if(thres >= 0)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, genJsonResult, jsonDoc);
|
||||
|
||||
if(instance.config.display.stat)
|
||||
if(thres >= 0)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
yyjson_mut_obj_add_real(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
char str[64];
|
||||
int len = snprintf(str, sizeof str, "%.3fms", ms);
|
||||
if (thres > 0)
|
||||
snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
|
||||
printf("\e[s\e[1A\e[9999999C\e[%dD%s\e[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,10 +54,6 @@ void ffInitInstance(void)
|
||||
#else
|
||||
// Never use `setlocale(LC_ALL, "")`
|
||||
setlocale(LC_TIME, "");
|
||||
setlocale(LC_NUMERIC, "");
|
||||
#ifdef LC_MESSAGES
|
||||
setlocale(LC_MESSAGES, "");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
initState(&instance.state);
|
||||
|
||||
+11
-7
@@ -1,4 +1,5 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/color.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/io/io.h"
|
||||
@@ -181,12 +182,13 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
if (!modules) return NULL;
|
||||
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
|
||||
|
||||
int32_t thres = instance.config.display.stat;
|
||||
yyjson_val* item;
|
||||
size_t idx, max;
|
||||
yyjson_arr_foreach(modules, idx, max, item)
|
||||
{
|
||||
uint64_t ms = 0;
|
||||
if(!prepare && instance.config.display.stat)
|
||||
double ms = 0;
|
||||
if(!prepare && thres >= 0)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
yyjson_val* module = item;
|
||||
@@ -208,19 +210,21 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
else if(!parseModuleJsonObject(type, module, jsonDoc))
|
||||
return "Unknown module type";
|
||||
|
||||
if(!prepare && instance.config.display.stat)
|
||||
if(!prepare && thres >= 0)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
yyjson_mut_obj_add_real(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
char str[64];
|
||||
int len = snprintf(str, sizeof str, "%.3fms", ms);
|
||||
if (thres > 0)
|
||||
snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
|
||||
printf("\e[s\e[1A\e[9999999C\e[%dD%s\e[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -9,22 +9,22 @@
|
||||
#include <sysinfoapi.h>
|
||||
#endif
|
||||
|
||||
static inline uint64_t ffTimeGetTick() //In msec
|
||||
static inline double ffTimeGetTick(void) //In msec
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
LARGE_INTEGER start;
|
||||
QueryPerformanceCounter(&start);
|
||||
return (uint64_t)(start.QuadPart * 1000 / frequency.QuadPart);
|
||||
return (double) start.QuadPart * 1000 / (double) frequency.QuadPart;
|
||||
#else
|
||||
struct timespec timeNow;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||
return (uint64_t)(((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
|
||||
return (double) timeNow.tv_sec * 1000. + (double) timeNow.tv_nsec / 1000000.;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t ffTimeGetNow()
|
||||
static inline uint64_t ffTimeGetNow(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
uint64_t timeNow;
|
||||
|
||||
@@ -46,7 +46,7 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||
ffEfiFillLoadOption((FFEfiLoadOption *)buffer, result);
|
||||
|
||||
DWORD uefiSecureBootEnabled = 0, bufSize = 0;
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SYSTEM\\ControlSet001\\Control\\SecureBoot\\State", L"UEFISecureBootEnabled", RRF_RT_REG_DWORD, NULL, &uefiSecureBootEnabled, &bufSize) == ERROR_SUCCESS)
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\State", L"UEFISecureBootEnabled", RRF_RT_REG_DWORD, NULL, &uefiSecureBootEnabled, &bufSize) == ERROR_SUCCESS)
|
||||
result->secureBoot = !!uefiSecureBootEnabled;
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -36,6 +36,7 @@ const char* ffCPUAppleCodeToName(uint32_t code)
|
||||
case 6030: return "Apple M3 Pro";
|
||||
case 6031:
|
||||
case 6034: return "Apple M3 Max";
|
||||
case 8132: return "Apple M4";
|
||||
default: return "Apple Silicon";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,3 +30,30 @@ typedef struct FFCPUResult
|
||||
|
||||
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
|
||||
const char* ffCPUAppleCodeToName(uint32_t code);
|
||||
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
// WARNING: CPUID may report frequencies of efficient cores
|
||||
inline static const char* ffCPUDetectSpeedByCpuid(FFCPUResult* cpu)
|
||||
{
|
||||
uint32_t base = 0, max = 0, bus = 0, unused = 0;
|
||||
if (!__get_cpuid(0x16, &base, &max, &bus, &unused))
|
||||
return "Unsupported instruction";
|
||||
|
||||
// cpuid returns 0 MHz when hyper-v is enabled
|
||||
if (base) cpu->frequencyBase = base;
|
||||
if (max) cpu->frequencyMax = max;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline static const char* ffCPUDetectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
|
||||
{
|
||||
return "Unsupported platform";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
// https://github.com/util-linux/util-linux/blob/master/sys-utils/lscpu-arm.c
|
||||
// We use the util-linux's data but not its code. Call me if it violates util-linux's GPL license.
|
||||
|
||||
static const char* hwImplId2Vendor(uint32_t implId)
|
||||
{
|
||||
switch (implId)
|
||||
{
|
||||
case 0x41: return "ARM";
|
||||
case 0x42: return "Broadcom";
|
||||
case 0x43: return "Cavium";
|
||||
case 0x44: return "DEC";
|
||||
case 0x46: return "FUJITSU";
|
||||
case 0x48: return "HiSilicon";
|
||||
case 0x49: return "Infineon";
|
||||
case 0x4d: return "Motorola";
|
||||
case 0x4e: return "NVIDIA";
|
||||
case 0x50: return "APM";
|
||||
case 0x51: return "Qualcomm";
|
||||
case 0x53: return "Samsung";
|
||||
case 0x56: return "Marvell";
|
||||
case 0x61: return "Apple";
|
||||
case 0x66: return "Faraday";
|
||||
case 0x69: return "Intel";
|
||||
case 0x6D: return "Microsoft";
|
||||
case 0x70: return "Phytium";
|
||||
case 0xc0: return "Ampere";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* armPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x810: return "ARM810";
|
||||
case 0x920: return "ARM920";
|
||||
case 0x922: return "ARM922";
|
||||
case 0x926: return "ARM926";
|
||||
case 0x940: return "ARM940";
|
||||
case 0x946: return "ARM946";
|
||||
case 0x966: return "ARM966";
|
||||
case 0xa20: return "ARM1020";
|
||||
case 0xa22: return "ARM1022";
|
||||
case 0xa26: return "ARM1026";
|
||||
case 0xb02: return "ARM11 MPCore";
|
||||
case 0xb36: return "ARM1136";
|
||||
case 0xb56: return "ARM1156";
|
||||
case 0xb76: return "ARM1176";
|
||||
case 0xc05: return "Cortex-A5";
|
||||
case 0xc07: return "Cortex-A7";
|
||||
case 0xc08: return "Cortex-A8";
|
||||
case 0xc09: return "Cortex-A9";
|
||||
case 0xc0d: return "Cortex-A17"; /* Originally A12 */
|
||||
case 0xc0f: return "Cortex-A15";
|
||||
case 0xc0e: return "Cortex-A17";
|
||||
case 0xc14: return "Cortex-R4";
|
||||
case 0xc15: return "Cortex-R5";
|
||||
case 0xc17: return "Cortex-R7";
|
||||
case 0xc18: return "Cortex-R8";
|
||||
case 0xc20: return "Cortex-M0";
|
||||
case 0xc21: return "Cortex-M1";
|
||||
case 0xc23: return "Cortex-M3";
|
||||
case 0xc24: return "Cortex-M4";
|
||||
case 0xc27: return "Cortex-M7";
|
||||
case 0xc60: return "Cortex-M0+";
|
||||
case 0xd01: return "Cortex-A32";
|
||||
case 0xd02: return "Cortex-A34";
|
||||
case 0xd03: return "Cortex-A53";
|
||||
case 0xd04: return "Cortex-A35";
|
||||
case 0xd05: return "Cortex-A55";
|
||||
case 0xd06: return "Cortex-A65";
|
||||
case 0xd07: return "Cortex-A57";
|
||||
case 0xd08: return "Cortex-A72";
|
||||
case 0xd09: return "Cortex-A73";
|
||||
case 0xd0a: return "Cortex-A75";
|
||||
case 0xd0b: return "Cortex-A76";
|
||||
case 0xd0c: return "Neoverse-N1";
|
||||
case 0xd0d: return "Cortex-A77";
|
||||
case 0xd0e: return "Cortex-A76AE";
|
||||
case 0xd13: return "Cortex-R52";
|
||||
case 0xd15: return "Cortex-R82";
|
||||
case 0xd16: return "Cortex-R52+";
|
||||
case 0xd20: return "Cortex-M23";
|
||||
case 0xd21: return "Cortex-M33";
|
||||
case 0xd22: return "Cortex-M55";
|
||||
case 0xd23: return "Cortex-M85";
|
||||
case 0xd40: return "Neoverse-V1";
|
||||
case 0xd41: return "Cortex-A78";
|
||||
case 0xd42: return "Cortex-A78AE";
|
||||
case 0xd43: return "Cortex-A65AE";
|
||||
case 0xd44: return "Cortex-X1";
|
||||
case 0xd46: return "Cortex-A510";
|
||||
case 0xd47: return "Cortex-A710";
|
||||
case 0xd48: return "Cortex-X2";
|
||||
case 0xd49: return "Neoverse-N2";
|
||||
case 0xd4a: return "Neoverse-E1";
|
||||
case 0xd4b: return "Cortex-A78C";
|
||||
case 0xd4c: return "Cortex-X1C";
|
||||
case 0xd4d: return "Cortex-A715";
|
||||
case 0xd4e: return "Cortex-X3";
|
||||
case 0xd4f: return "Neoverse-V2";
|
||||
case 0xd80: return "Cortex-A520";
|
||||
case 0xd81: return "Cortex-A720";
|
||||
case 0xd82: return "Cortex-X4";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* brcmPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x0f: return "Brahma-B15";
|
||||
case 0x100: return "Brahma-B53";
|
||||
case 0x516: return "ThunderX2";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* decPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xa10: return "SA110";
|
||||
case 0xa11: return "SA1100";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* caviumPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x0a0: return "ThunderX";
|
||||
case 0x0a1: return "ThunderX-88XX";
|
||||
case 0x0a2: return "ThunderX-81XX";
|
||||
case 0x0a3: return "ThunderX-83XX";
|
||||
case 0x0af: return "ThunderX2-99xx";
|
||||
case 0x0b0: return "OcteonTX2";
|
||||
case 0x0b1: return "OcteonTX2-98XX";
|
||||
case 0x0b2: return "OcteonTX2-96XX";
|
||||
case 0x0b3: return "OcteonTX2-95XX";
|
||||
case 0x0b4: return "OcteonTX2-95XXN";
|
||||
case 0x0b5: return "OcteonTX2-95XXMM";
|
||||
case 0x0b6: return "OcteonTX2-95XXO";
|
||||
case 0x0b8: return "ThunderX3-T110";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* apmPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x000: return "X-Gene";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* qcomPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x001: return "Oryon";
|
||||
case 0x00f: return "Scorpion";
|
||||
case 0x02d: return "Scorpion";
|
||||
case 0x04d: return "Krait";
|
||||
case 0x06f: return "Krait";
|
||||
case 0x201: return "Kryo";
|
||||
case 0x205: return "Kryo";
|
||||
case 0x211: return "Kryo";
|
||||
case 0x800: return "Falkor-V1/Kryo";
|
||||
case 0x801: return "Kryo-V2";
|
||||
case 0x802: return "Kryo-3XX-Gold";
|
||||
case 0x803: return "Kryo-3XX-Silver";
|
||||
case 0x804: return "Kryo-4XX-Gold";
|
||||
case 0x805: return "Kryo-4XX-Silver";
|
||||
case 0xc00: return "Falkor";
|
||||
case 0xc01: return "Saphira";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* samsungPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x001: return "Exynos-M1";
|
||||
case 0x002: return "Exynos-M3";
|
||||
case 0x003: return "Exynos-M4";
|
||||
case 0x004: return "Exynos-M5";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* nvidiaPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x000: return "Denver";
|
||||
case 0x003: return "Denver 2";
|
||||
case 0x004: return "Carmel";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* marvellPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x131: return "Feroceon-88FR131";
|
||||
case 0x581: return "PJ4/PJ4b";
|
||||
case 0x584: return "PJ4B-MP";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* applePartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x000: return "Swift";
|
||||
case 0x001: return "Cyclone";
|
||||
case 0x002: return "Typhoon";
|
||||
case 0x003: return "Typhoon/Capri";
|
||||
case 0x004: return "Twister";
|
||||
case 0x005: return "Twister/Elba/Malta";
|
||||
case 0x006: return "Hurricane";
|
||||
case 0x007: return "Hurricane/Myst";
|
||||
case 0x008: return "Monsoon";
|
||||
case 0x009: return "Mistral";
|
||||
case 0x00b: return "Vortex";
|
||||
case 0x00c: return "Tempest";
|
||||
case 0x00f: return "Tempest-M9";
|
||||
case 0x010: return "Vortex/Aruba";
|
||||
case 0x011: return "Tempest/Aruba";
|
||||
case 0x012: return "Lightning";
|
||||
case 0x013: return "Thunder";
|
||||
case 0x020: return "Icestorm-A14";
|
||||
case 0x021: return "Firestorm-A14";
|
||||
case 0x022: return "Icestorm-M1";
|
||||
case 0x023: return "Firestorm-M1";
|
||||
case 0x024: return "Icestorm-M1-Pro";
|
||||
case 0x025: return "Firestorm-M1-Pro";
|
||||
case 0x026: return "Thunder-M10";
|
||||
case 0x028: return "Icestorm-M1-Max";
|
||||
case 0x029: return "Firestorm-M1-Max";
|
||||
case 0x030: return "Blizzard-A15";
|
||||
case 0x031: return "Avalanche-A15";
|
||||
case 0x032: return "Blizzard-M2";
|
||||
case 0x033: return "Avalanche-M2";
|
||||
case 0x034: return "Blizzard-M2-Pro";
|
||||
case 0x035: return "Avalanche-M2-Pro";
|
||||
case 0x036: return "Sawtooth-A16";
|
||||
case 0x037: return "Everest-A16";
|
||||
case 0x038: return "Blizzard-M2-Max";
|
||||
case 0x039: return "Avalanche-M2-Max";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* faradayPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x526: return "FA526";
|
||||
case 0x626: return "FA626";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* intelPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x200: return "i80200";
|
||||
case 0x210: return "PXA250A";
|
||||
case 0x212: return "PXA210A";
|
||||
case 0x242: return "i80321-400";
|
||||
case 0x243: return "i80321-600";
|
||||
case 0x290: return "PXA250B/PXA26x";
|
||||
case 0x292: return "PXA210B";
|
||||
case 0x2c2: return "i80321-400-B0";
|
||||
case 0x2c3: return "i80321-600-B0";
|
||||
case 0x2d0: return "PXA250C/PXA255/PXA26x";
|
||||
case 0x2d2: return "PXA210C";
|
||||
case 0x411: return "PXA27x";
|
||||
case 0x41c: return "IPX425-533";
|
||||
case 0x41d: return "IPX425-400";
|
||||
case 0x41f: return "IPX425-266";
|
||||
case 0x682: return "PXA32x";
|
||||
case 0x683: return "PXA930/PXA935";
|
||||
case 0x688: return "PXA30x";
|
||||
case 0x689: return "PXA31x";
|
||||
case 0xb11: return "SA1110";
|
||||
case 0xc12: return "IPX1200";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* fujitsuPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x001: return "A64FX";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* hisiPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xd01: return "TaiShan-v110"; /* used in Kunpeng-920 SoC */
|
||||
case 0xd02: return "TaiShan-v120"; /* used in Kirin 990A and 9000S SoCs */
|
||||
case 0xd40: return "Cortex-A76"; /* HiSilicon uses this ID though advertises A76 */
|
||||
case 0xd41: return "Cortex-A77"; /* HiSilicon uses this ID though advertises A77 */
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* amperePartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xac3: return "Ampere-1";
|
||||
case 0xac4: return "Ampere-1a";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* ftPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x303: return "FTC310";
|
||||
case 0x660: return "FTC660";
|
||||
case 0x661: return "FTC661";
|
||||
case 0x662: return "FTC662";
|
||||
case 0x663: return "FTC663";
|
||||
case 0x664: return "FTC664";
|
||||
case 0x862: return "FTC862";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* msPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xd49: return "Azure-Cobalt-100";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
}
|
||||
}
|
||||
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
|
||||
for (uint16_t i = 0; i < cpu->coresLogical; ++i)
|
||||
{
|
||||
ffStrbufClear(&buffer);
|
||||
|
||||
+124
-122
@@ -74,62 +74,120 @@ static void detectAndroid(FFCPUResult* cpu)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
if(cpuinfo == NULL)
|
||||
return "fopen(\"/proc/cpuinfo\", \"r\") failed";
|
||||
#if __arm__ || __aarch64__
|
||||
#include "cpu_arm.h"
|
||||
|
||||
static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
|
||||
{
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
rewind(cpuinfo);
|
||||
size_t len = 0;
|
||||
uint32_t lastPartId = UINT32_MAX;
|
||||
uint32_t num = 0;
|
||||
while(getline(&line, &len, cpuinfo) != -1)
|
||||
{
|
||||
if (!ffStrStartsWith(line, "CPU part\t: ")) continue;
|
||||
uint32_t partId = (uint32_t) strtoul(line + strlen("CPU part\t: "), NULL, 16);
|
||||
const char* name = NULL;
|
||||
if (partId > 0) // Linux reports 0 for unknown CPUs
|
||||
{
|
||||
switch (implId)
|
||||
{
|
||||
case 0x41: name = armPartId2name(partId); break;
|
||||
case 0x42: name = brcmPartId2name(partId); break;
|
||||
case 0x43: name = caviumPartId2name(partId); break;
|
||||
case 0x44: name = decPartId2name(partId); break;
|
||||
case 0x46: name = fujitsuPartId2name(partId); break;
|
||||
case 0x48: name = hisiPartId2name(partId); break;
|
||||
case 0x4e: name = nvidiaPartId2name(partId); break;
|
||||
case 0x50: name = apmPartId2name(partId); break;
|
||||
case 0x51: name = qcomPartId2name(partId); break;
|
||||
case 0x53: name = samsungPartId2name(partId); break;
|
||||
case 0x56: name = marvellPartId2name(partId); break;
|
||||
case 0x61: name = applePartId2name(partId); break;
|
||||
case 0x66: name = faradayPartId2name(partId); break;
|
||||
case 0x69: name = intelPartId2name(partId); break;
|
||||
case 0x6d: name = msPartId2name(partId); break;
|
||||
case 0x70: name = ftPartId2name(partId); break;
|
||||
case 0xc0: name = amperePartId2name(partId); break;
|
||||
}
|
||||
}
|
||||
if (lastPartId != partId)
|
||||
{
|
||||
if (lastPartId != UINT32_MAX)
|
||||
{
|
||||
if (num > 1)
|
||||
ffStrbufAppendF(&cpu->name, "*%u", num);
|
||||
ffStrbufAppendS(&cpu->name, " + ");
|
||||
}
|
||||
if (name)
|
||||
ffStrbufAppendS(&cpu->name, name);
|
||||
else if (partId)
|
||||
ffStrbufAppendF(&cpu->name, "%s-%X", cpu->vendor.chars, partId);
|
||||
else
|
||||
ffStrbufAppend(&cpu->name, &cpu->vendor);
|
||||
lastPartId = partId;
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
++num;
|
||||
}
|
||||
if (num > 1)
|
||||
ffStrbufAppendF(&cpu->name, "*%u", num);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* parseCpuInfo(
|
||||
FF_MAYBE_UNUSED FILE* cpuinfo,
|
||||
FF_MAYBE_UNUSED FFCPUResult* cpu,
|
||||
FF_MAYBE_UNUSED FFstrbuf* physicalCoresBuffer,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuMHz,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuIsa,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuUarch,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuImplementer)
|
||||
{
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
#ifdef __aarch64__
|
||||
FF_STRBUF_AUTO_DESTROY implementer = ffStrbufCreate();
|
||||
#endif
|
||||
|
||||
while(getline(&line, &len, cpuinfo) != -1)
|
||||
{
|
||||
//Stop after the first CPU
|
||||
if(*line == '\0' || *line == '\n')
|
||||
//Stop after reasonable information is acquired
|
||||
if((*line == '\0' || *line == '\n')
|
||||
#if __arm__ || __loongarch__
|
||||
&& cpu->name.length > 0 // #1202 #1204
|
||||
#endif
|
||||
)
|
||||
break;
|
||||
|
||||
(void)(
|
||||
ffParsePropLine(line, "model name :", &cpu->name) ||
|
||||
ffParsePropLine(line, "vendor_id :", &cpu->vendor) ||
|
||||
ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) ||
|
||||
ffParsePropLine(line, "cpu MHz :", cpuMHz) ||
|
||||
ffParsePropLine(line, "isa :", cpuIsa) ||
|
||||
ffParsePropLine(line, "uarch :", cpuUarch) ||
|
||||
|
||||
#ifdef __aarch64__
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "CPU implementer :", &implementer)) ||
|
||||
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
|
||||
// "Hardware" should always be used in this case
|
||||
#if !(__arm__ || __aarch64__)
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) ||
|
||||
(physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) ||
|
||||
#endif
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
|
||||
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
|
||||
#endif
|
||||
|
||||
#if __arm__ || __aarch64__
|
||||
(cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) //For MIPS
|
||||
#endif
|
||||
#if __powerpc__ || __powerpc
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
#endif
|
||||
#if __mips__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS
|
||||
#endif
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
// https://github.com/util-linux/util-linux/blob/2cd89de14549d2b2c079a4f8b73f75500d229fee/sys-utils/lscpu-arm.c#L286
|
||||
if (cpu->vendor.length == 0 && implementer.length > 2 /* 0xX */)
|
||||
{
|
||||
uint32_t implId = (uint32_t) strtoul(implementer.chars, NULL, 16);
|
||||
switch (implId)
|
||||
{
|
||||
case 0x41: ffStrbufSetStatic(&cpu->vendor, "ARM"); break;
|
||||
case 0x42: ffStrbufSetStatic(&cpu->vendor, "Broadcom"); break;
|
||||
case 0x48: ffStrbufSetStatic(&cpu->vendor, "HiSilicon"); break;
|
||||
case 0x4e: ffStrbufSetStatic(&cpu->vendor, "Nvidia"); break;
|
||||
case 0x51: ffStrbufSetStatic(&cpu->vendor, "Qualcomm"); break;
|
||||
case 0x53: ffStrbufSetStatic(&cpu->vendor, "Samsung"); break;
|
||||
case 0x61: ffStrbufSetStatic(&cpu->vendor, "Apple"); break;
|
||||
case 0x69: ffStrbufSetStatic(&cpu->vendor, "Intel"); break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -223,16 +281,19 @@ static double detectCPUTemp(void)
|
||||
{
|
||||
if(
|
||||
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
|
||||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
|
||||
ffStrbufCompS(&value->name, "coretemp") == 0
|
||||
ffStrbufEqualS(&value->name, "k10temp") ||
|
||||
ffStrbufEqualS(&value->name, "coretemp")
|
||||
) return value->value;
|
||||
}
|
||||
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
static void parseIsa(FFstrbuf* cpuIsa)
|
||||
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
|
||||
{
|
||||
// Always use the last part of the ISA string. Ref: #590 #1204
|
||||
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||
|
||||
if(ffStrbufStartsWithS(cpuIsa, "rv"))
|
||||
{
|
||||
// RISC-V ISA string example: "rv64imafdch_zicsr_zifencei".
|
||||
@@ -248,13 +309,9 @@ static void parseIsa(FFstrbuf* cpuIsa)
|
||||
}
|
||||
// The final ISA output of the above example is "rv64gch".
|
||||
}
|
||||
if(ffStrbufStartsWithS(cpuIsa, "mips"))
|
||||
{
|
||||
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
void detectAsahi(FFCPUResult* cpu)
|
||||
FF_MAYBE_UNUSED static void detectAsahi(FFCPUResult* cpu)
|
||||
{
|
||||
// In Asahi Linux, reading /proc/device-tree/compatible gives
|
||||
// information on the device model. It consists of 3 NUL terminated
|
||||
@@ -279,23 +336,31 @@ void detectAsahi(FFCPUResult* cpu)
|
||||
|
||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
if(cpuinfo == NULL)
|
||||
return "fopen(\"/proc/cpuinfo\", \"r\") failed";
|
||||
|
||||
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
|
||||
|
||||
const char* error = parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch);
|
||||
const char* error = parseCpuInfo(cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
|
||||
if (error) return error;
|
||||
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
|
||||
|
||||
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
if(cpuUarch.length > 0)
|
||||
{
|
||||
if(cpu->name.length > 0)
|
||||
@@ -310,84 +375,21 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
ffStrbufAppendC(&cpu->name, ' ');
|
||||
ffStrbufAppend(&cpu->name, &cpuIsa);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(__aarch64__)
|
||||
#if __arm__ || __aarch64__
|
||||
uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16);
|
||||
ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer));
|
||||
|
||||
#if __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#elif __aarch64__
|
||||
detectAsahi(cpu);
|
||||
#endif
|
||||
|
||||
if (cpu->name.length == 0)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
if (ffProcessAppendStdOut(&buffer, (char *const[]) { "lscpu", NULL }) == NULL)
|
||||
{
|
||||
char* pstart = buffer.chars;
|
||||
|
||||
if (cpu->vendor.length == 0)
|
||||
{
|
||||
pstart = strstr(pstart, "Vendor ID:");
|
||||
if (pstart)
|
||||
{
|
||||
pstart += strlen("Vendor ID:");
|
||||
while (isspace(*pstart)) ++pstart;
|
||||
if (*pstart)
|
||||
{
|
||||
char* pend = strchr(pstart, '\n');
|
||||
if (pend != NULL)
|
||||
ffStrbufAppendNS(&cpu->vendor, (uint32_t) (pend - pstart), pstart);
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&cpu->vendor, pstart);
|
||||
}
|
||||
pstart = pend + 1;
|
||||
if (pstart >= buffer.chars + buffer.length)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pstart = buffer.chars;
|
||||
}
|
||||
}
|
||||
|
||||
while ((pstart = strstr(pstart, "Model name:")))
|
||||
{
|
||||
pstart += strlen("Model name:");
|
||||
while (isspace(*pstart)) ++pstart;
|
||||
if (*pstart == '\0')
|
||||
break;
|
||||
|
||||
if (cpu->name.length > 0)
|
||||
ffStrbufAppendS(&cpu->name, " + ");
|
||||
|
||||
if (*pstart == '-')
|
||||
{
|
||||
if (cpu->vendor.length > 0)
|
||||
ffStrbufAppend(&cpu->name, &cpu->vendor);
|
||||
else
|
||||
ffStrbufAppendS(&cpu->name, "Unknown");
|
||||
++pstart;
|
||||
continue;
|
||||
}
|
||||
|
||||
char* pend = strchr(pstart, '\n');
|
||||
if (pend != NULL)
|
||||
ffStrbufAppendNS(&cpu->name, (uint32_t) (pend - pstart), pstart);
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&cpu->name, pstart);
|
||||
break;
|
||||
}
|
||||
|
||||
pstart = pend + 1;
|
||||
if (pstart >= buffer.chars + buffer.length)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
detectArmName(cpuinfo, cpu, cpuImplementer);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id");
|
||||
ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
if (kn->value.ui32 > cpu->frequencyBase)
|
||||
cpu->frequencyBase = kn->value.ui32;
|
||||
}
|
||||
|
||||
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
||||
if (ks && kstat_read(kc, ks, NULL) >= 0)
|
||||
|
||||
@@ -54,31 +54,6 @@ typedef struct FFSmbiosProcessorInfo
|
||||
static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30,
|
||||
"FFSmbiosProcessorInfo: Wrong struct alignment");
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
inline static const char* detectSpeedByCpuid(FFCPUResult* cpu)
|
||||
{
|
||||
uint32_t base = 0, max = 0, bus = 0, unused = 0;
|
||||
if (!__get_cpuid(0x16, &base, &max, &bus, &unused))
|
||||
return "Unsupported instruction";
|
||||
|
||||
// cpuid returns 0 MHz when hyper-v is enabled
|
||||
if (base) cpu->frequencyBase = base;
|
||||
if (max) cpu->frequencyMax = max;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
|
||||
{
|
||||
return "Unsupported platform";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
@@ -193,7 +168,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
detectSpeedByCpuid(cpu);
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (options->showPeCoreCount) detectCoreTypes(cpu);
|
||||
|
||||
if (cpu->frequencyMax == 0)
|
||||
|
||||
@@ -72,7 +72,7 @@ static bool isPhysicalDevice(const struct mntent* device)
|
||||
) return false;
|
||||
|
||||
// https://source.android.com/docs/core/ota/apex?hl=zh-cn
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
return false;
|
||||
|
||||
#endif // __ANDROID__
|
||||
@@ -240,8 +240,16 @@ static void detectStats(FFDisk* disk)
|
||||
disk->bytesAvailable = fs.f_bavail * fs.f_frsize;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
if (fs.f_files >= fs.f_ffree)
|
||||
{
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Windows filesystem in WSL
|
||||
disk->filesTotal = disk->filesUsed = 0;
|
||||
}
|
||||
|
||||
if(fs.f_flag & ST_RDONLY)
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
|
||||
@@ -37,24 +37,23 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInit(&device->name);
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
|
||||
if (ffAppendFileBuffer(pathSysBlock, &device->name))
|
||||
if (ffAppendFileBuffer(pathSysBlock, &name))
|
||||
{
|
||||
ffStrbufTrimRightSpace(&device->name);
|
||||
if (device->name.length > 0)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
ffStrbufTrimRightSpace(&name);
|
||||
if (name.length > 0)
|
||||
ffStrbufAppendC(&name, ' ');
|
||||
}
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
|
||||
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||
ffStrbufTrimRightSpace(&device->name);
|
||||
ffAppendFileBuffer(pathSysBlock, &name);
|
||||
ffStrbufTrimRightSpace(&name);
|
||||
|
||||
if (device->name.length == 0)
|
||||
ffStrbufSetS(&device->name, devName);
|
||||
if (name.length == 0)
|
||||
ffStrbufSetS(&name, devName);
|
||||
else if (ffStrStartsWith(devName, "nvme"))
|
||||
{
|
||||
int devid, nsid;
|
||||
@@ -69,17 +68,13 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (multiNs)
|
||||
{
|
||||
// In Asahi Linux, there are multiple namespaces for the same NVMe drive.
|
||||
ffStrbufAppendF(&device->name, " - %d", nsid);
|
||||
ffStrbufAppendF(&name, " - %d", nsid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// I/Os merges sectors ticks ...
|
||||
@@ -94,6 +89,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
continue;
|
||||
}
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
|
||||
device->bytesRead = sectorRead * 512;
|
||||
device->bytesWritten = sectorWritten * 512;
|
||||
|
||||
@@ -34,7 +34,6 @@ FFDisplayResult* ffdsAppendDisplay(
|
||||
|
||||
display->bitDepth = 0;
|
||||
display->hdrEnabled = false;
|
||||
display->wcgEnabled = false;
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ typedef struct FFDisplayResult
|
||||
bool primary;
|
||||
uint8_t bitDepth;
|
||||
bool hdrEnabled;
|
||||
bool wcgEnabled;
|
||||
} FFDisplayResult;
|
||||
|
||||
typedef struct FFDisplayServerResult
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
#include <CoreGraphics/CGDirectDisplay.h>
|
||||
#include <CoreVideo/CVDisplayLink.h>
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
|
||||
#ifndef MAC_OS_X_VERSION_10_15
|
||||
#import <IOKit/graphics/IOGraphicsLib.h>
|
||||
extern CFDictionaryRef CoreDisplay_IODisplayCreateInfoDictionary(io_service_t framebuffer, IOOptionBits options) __attribute__((weak_import));
|
||||
extern Boolean CoreDisplay_Display_IsHDRModeEnabled(CGDirectDisplayID display) __attribute__((weak_import));
|
||||
#else
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#endif
|
||||
|
||||
static void detectDisplays(FFDisplayServerResult* ds)
|
||||
@@ -43,30 +44,22 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = NULL;
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
if(CoreDisplay_DisplayCreateInfoDictionary)
|
||||
{
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen);
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
|
||||
}
|
||||
}
|
||||
displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen);
|
||||
#else
|
||||
if(CoreDisplay_IODisplayCreateInfoDictionary)
|
||||
{
|
||||
io_service_t servicePort = CGDisplayIOServicePort(screen);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
|
||||
}
|
||||
displayInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
}
|
||||
#endif
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
|
||||
}
|
||||
|
||||
CGSize size = CGDisplayScreenSize(screen);
|
||||
|
||||
@@ -95,6 +88,13 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
ffCfDictGetInt(dict, kCGDisplayBitsPerSample, &bitDepth);
|
||||
display->bitDepth = (uint8_t) bitDepth;
|
||||
}
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
if (CoreDisplay_Display_IsHDRModeEnabled)
|
||||
{
|
||||
display->hdrEnabled = CoreDisplay_Display_IsHDRModeEnabled(screen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
CGDisplayModeRelease(mode);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,6 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
|
||||
{
|
||||
display->hdrEnabled = !!advColorInfo.advancedColorEnabled;
|
||||
display->wcgEnabled = !!advColorInfo.wideColorEnforced;
|
||||
display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,12 +119,6 @@ static void waylandKdeHdrListener(void *data, FF_MAYBE_UNUSED struct kde_output_
|
||||
display->hdrEnabled = !!hdr_enabled;
|
||||
}
|
||||
|
||||
static void waylandKdeWcgListener(void *data, FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, uint32_t wcg_enabled)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
display->wcgEnabled = !!wcg_enabled;
|
||||
}
|
||||
|
||||
static struct kde_output_device_v2_listener outputListener = {
|
||||
.geometry = waylandKdeGeometryListener,
|
||||
.current_mode = waylandKdeCurrentModeListener,
|
||||
@@ -143,7 +137,7 @@ static struct kde_output_device_v2_listener outputListener = {
|
||||
.name = waylandKdeNameListener,
|
||||
.high_dynamic_range = waylandKdeHdrListener,
|
||||
.sdr_brightness = (void*) stubListener,
|
||||
.wide_color_gamut = waylandKdeWcgListener,
|
||||
.wide_color_gamut = (void*) stubListener,
|
||||
.auto_rotate_policy = (void*) stubListener,
|
||||
.icc_profile_path = (void*) stubListener,
|
||||
.brightness_metadata = (void*) stubListener,
|
||||
@@ -202,7 +196,6 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
|
||||
if (item)
|
||||
{
|
||||
item->hdrEnabled = display.hdrEnabled;
|
||||
item->wcgEnabled = display.wcgEnabled;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
|
||||
@@ -47,7 +47,6 @@ typedef struct WaylandDisplay
|
||||
FFstrbuf edidName;
|
||||
uint64_t id;
|
||||
bool hdrEnabled;
|
||||
bool wcgEnabled;
|
||||
void* internal;
|
||||
} WaylandDisplay;
|
||||
|
||||
|
||||
@@ -1,17 +1,44 @@
|
||||
#include "editor.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/library.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/path.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
static inline char* realpath(const char* restrict file_name, char* restrict resolved_name)
|
||||
{
|
||||
return _fullpath(resolved_name, file_name, _MAX_PATH);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool extractNvimVersionFromBinary(const char* str, uint32_t len, void* userdata)
|
||||
{
|
||||
if (len < strlen("NVIM v0.0.0")) return true;
|
||||
if (!ffStrStartsWith(str, "NVIM v")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool extractVimVersionFromBinary(const char* str, uint32_t len, void* userdata)
|
||||
{
|
||||
if (len < strlen("VIM - Vi IMproved 0.0")) return true;
|
||||
if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved "));
|
||||
ffStrbufSubstrBeforeFirstC(userdata, ' ');
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool extractNanoVersionFromBinary(const char* str, uint32_t len, void* userdata)
|
||||
{
|
||||
if (len < strlen("GNU nano 0.0")) return true;
|
||||
if (!ffStrStartsWith(str, "GNU nano ")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* ffDetectEditor(FFEditorResult* result)
|
||||
{
|
||||
ffStrbufSetS(&result->name, getenv("VISUAL"));
|
||||
@@ -26,41 +53,26 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
return "$VISUAL or $EDITOR not set";
|
||||
}
|
||||
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
if (result->name.chars[0] != '/')
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->path, (char* const[]){
|
||||
FASTFETCH_TARGET_DIR_USR "/bin/which",
|
||||
result->name.chars,
|
||||
NULL,
|
||||
}) != NULL || result->path.length == 0)
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (!(result->name.length > 3 && ffCharIsEnglishAlphabet(result->name.chars[0]) && result->name.chars[1] == ':' && result->name.chars[2] == '\\'))
|
||||
{
|
||||
char buf[32];
|
||||
uint32_t len = GetSystemDirectoryA(buf, sizeof(buf));
|
||||
if (len < strlen("C:\\WINDOWS\\system32")) return NULL;
|
||||
strncpy(buf + len, "\\where.exe", sizeof(buf) - len);
|
||||
if (ffProcessAppendStdOut(&result->path, (char* const[]){
|
||||
buf,
|
||||
result->name.chars,
|
||||
NULL,
|
||||
}) != NULL || result->path.length == 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
if (ffIsAbsolutePath(result->name.chars))
|
||||
ffStrbufSet(&result->path, &result->name);
|
||||
else
|
||||
{
|
||||
const char* error = ffFindExecutableInPath(result->name.chars, &result->path);
|
||||
if (error) return NULL;
|
||||
}
|
||||
|
||||
char buf[PATH_MAX + 1];
|
||||
if (!realpath(result->path.chars, buf))
|
||||
return NULL;
|
||||
{
|
||||
char buf[PATH_MAX + 1];
|
||||
if (!realpath(result->path.chars, buf))
|
||||
return NULL;
|
||||
|
||||
ffStrbufSetS(&result->path, buf);
|
||||
// WIN32: Should we handle scoop shim exe here?
|
||||
|
||||
#ifdef __linux__
|
||||
if (!ffStrEndsWith(buf, "/snap"))
|
||||
#endif
|
||||
ffStrbufSetS(&result->path, buf);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t index = ffStrbufLastIndexC(&result->path,
|
||||
@@ -82,6 +94,17 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
if (ffStrbufEqualS(&result->exe, "nvim"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version);
|
||||
else if (ffStrbufEqualS(&result->exe, "vim"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version);
|
||||
else if (ffStrbufEqualS(&result->exe, "nano"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version);
|
||||
|
||||
if (result->version.length > 0) return NULL;
|
||||
|
||||
const char* param = NULL;
|
||||
if (
|
||||
ffStrbufEqualS(&result->exe, "nano") ||
|
||||
|
||||
@@ -33,11 +33,11 @@ typedef struct FFGPUResult
|
||||
FFstrbuf driver;
|
||||
FFstrbuf platformApi;
|
||||
double temperature;
|
||||
double coreUsage;
|
||||
int32_t coreCount;
|
||||
uint32_t frequency; // Maximum time clock frequency in MHz
|
||||
FFGPUMemory dedicated;
|
||||
FFGPUMemory shared;
|
||||
double coreUsage;
|
||||
uint64_t deviceId; // Used internally, may be uninitialized
|
||||
} FFGPUResult;
|
||||
|
||||
@@ -47,5 +47,5 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
|
||||
const char* ffGetGPUVendorString(unsigned vendorId);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName);
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <sys/pciio.h>
|
||||
@@ -70,11 +71,12 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY coreName = ffStrbufCreate();
|
||||
if (gpu->name.length == 0)
|
||||
{
|
||||
if (pciids.length == 0)
|
||||
loadPciIds(&pciids);
|
||||
ffGPUParsePciIds(&pciids, pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
|
||||
ffGPUParsePciIds(&pciids, pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu, &coreName);
|
||||
}
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific))
|
||||
@@ -114,7 +116,12 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
}
|
||||
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
|
||||
{
|
||||
gpu->type = ffStrbufStartsWithIgnCaseS(&gpu->name, "Arc ") ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
if ((coreName.chars[0] == 'D' || coreName.chars[0] == 'S') &&
|
||||
coreName.chars[1] == 'G' &&
|
||||
ffCharIsDigit(coreName.chars[2]))
|
||||
gpu->type = FF_GPU_TYPE_DISCRETE; // DG1 / DG2 / SG1
|
||||
else
|
||||
gpu->type = FF_GPU_TYPE_INTEGRATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,14 +199,17 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
|
||||
}
|
||||
}
|
||||
|
||||
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
|
||||
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const FFstrbuf* coreName)
|
||||
{
|
||||
// Works for Intel GPUs
|
||||
// https://patchwork.kernel.org/project/intel-gfx/patch/1422039866-11572-3-git-send-email-ville.syrjala@linux.intel.com/
|
||||
|
||||
if (ffStrbufStartsWithS(&gpu->name, "Intel "))
|
||||
ffStrbufSubstrAfter(&gpu->name, (uint32_t) strlen("Intel "));
|
||||
gpu->type = ffStrbufStartsWithIgnCaseS(&gpu->name, "Arc ") ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
if ((coreName->chars[0] == 'D' || coreName->chars[0] == 'S') &&
|
||||
coreName->chars[1] == 'G' &&
|
||||
ffCharIsDigit(coreName->chars[2]))
|
||||
gpu->type = FF_GPU_TYPE_DISCRETE; // DG1 / DG2 / SG1
|
||||
else
|
||||
gpu->type = FF_GPU_TYPE_INTEGRATED;
|
||||
|
||||
if (ffStrbufEqualS(&gpu->driver, "xe"))
|
||||
{
|
||||
@@ -293,6 +296,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
@@ -322,6 +326,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY coreName = ffStrbufCreate();
|
||||
if (gpu->name.length == 0)
|
||||
{
|
||||
static FFstrbuf pciids;
|
||||
@@ -330,7 +335,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufInit(&pciids);
|
||||
loadPciIds(&pciids);
|
||||
}
|
||||
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
||||
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu, &coreName);
|
||||
}
|
||||
|
||||
pciDetectDriver(gpu, deviceDir, buffer, drmKey);
|
||||
@@ -343,7 +348,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
}
|
||||
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
|
||||
{
|
||||
pciDetectIntelSpecific(gpu, deviceDir, buffer);
|
||||
pciDetectIntelSpecific(gpu, deviceDir, buffer, &coreName);
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "gpu.h"
|
||||
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName)
|
||||
{
|
||||
if (content->length)
|
||||
{
|
||||
@@ -44,13 +44,20 @@ void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint
|
||||
if (!end)
|
||||
end = content->chars + content->length;
|
||||
|
||||
char* openingBracket = memchr(start, '[', (uint32_t) (end - start));
|
||||
if (openingBracket)
|
||||
char* closingBracket = end - 1;
|
||||
if (*closingBracket == ']')
|
||||
{
|
||||
openingBracket++;
|
||||
char* closingBracket = memchr(openingBracket, ']', (uint32_t) (end - openingBracket));
|
||||
if (closingBracket)
|
||||
char* openingBracket = memrchr(start, '[', (size_t) (closingBracket - start));
|
||||
if (openingBracket)
|
||||
{
|
||||
openingBracket++;
|
||||
ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket);
|
||||
if (coreName)
|
||||
{
|
||||
ffStrbufSetNS(coreName, (uint32_t) (openingBracket - start) - 1, start);
|
||||
ffStrbufTrimRight(coreName, ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!gpu->name.length)
|
||||
ffStrbufSetNS(&gpu->name, (uint32_t) (end - start), start);
|
||||
|
||||
@@ -76,7 +76,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
{
|
||||
if (pciids.length == 0)
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
|
||||
ffGPUParsePciIds(&pciids, (uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
||||
ffGPUParsePciIds(&pciids, (uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,12 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
||||
}
|
||||
|
||||
#define FF_EMPTY_GUID_STR L"{00000000-0000-0000-0000-000000000000}"
|
||||
#define FF_GUID_STRLEN (sizeof(FF_EMPTY_GUID_STR) / sizeof(wchar_t) - 1)
|
||||
enum { FF_GUID_STRLEN = sizeof(FF_EMPTY_GUID_STR) / sizeof(wchar_t) - 1 };
|
||||
|
||||
wchar_t regDirectxKey[] = L"SOFTWARE\\Microsoft\\DirectX\\" FF_EMPTY_GUID_STR;
|
||||
const uint32_t regDirectxKeyPrefixLength = (uint32_t) __builtin_strlen("SOFTWARE\\Microsoft\\DirectX\\");
|
||||
wchar_t regDriverKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\" FF_EMPTY_GUID_STR L"\\0000";
|
||||
const uint32_t regDriverKeyPrefixLength = (uint32_t) __builtin_strlen("SYSTEM\\CurrentControlSet\\Control\\Class\\");
|
||||
|
||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
@@ -25,39 +30,14 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
if(hdev == INVALID_HANDLE_VALUE)
|
||||
return "SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY) failed";
|
||||
|
||||
wchar_t regDirectxKey[] = L"SOFTWARE\\Microsoft\\DirectX\\" FF_EMPTY_GUID_STR;
|
||||
const uint32_t regDirectxKeyPrefixLength = (uint32_t) strlen("SOFTWARE\\Microsoft\\DirectX\\");
|
||||
wchar_t regControlVideoKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\" FF_EMPTY_GUID_STR L"\\0000";
|
||||
const uint32_t regControlVideoKeyPrefixLength = (uint32_t) strlen("SYSTEM\\CurrentControlSet\\Control\\Video\\");
|
||||
|
||||
SP_DEVINFO_DATA did = { .cbSize = sizeof(did) };
|
||||
for (DWORD idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); ++idev)
|
||||
{
|
||||
wchar_t hardwareId[256];
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_HARDWAREID, NULL, (PBYTE) hardwareId, sizeof(hardwareId), NULL))
|
||||
continue;
|
||||
|
||||
wchar_t videoId[39];
|
||||
{
|
||||
FF_HKEY_AUTO_DESTROY hKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
|
||||
if (!hKey) continue;
|
||||
DWORD videoIdLength = sizeof(videoId);
|
||||
if (RegGetValueW(hKey, NULL, L"VideoID", RRF_RT_REG_SZ, NULL, videoId, &videoIdLength) != ERROR_SUCCESS || videoIdLength != (FF_GUID_STRLEN + 1) * sizeof(wchar_t))
|
||||
continue;
|
||||
}
|
||||
|
||||
wmemcpy(regControlVideoKey + regControlVideoKeyPrefixLength, videoId, FF_GUID_STRLEN);
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regControlVideoKey, &hKey, NULL)) continue;
|
||||
|
||||
unsigned vendorId = 0, deviceId = 0, subSystemId = 0, revId = 0;
|
||||
swscanf(hardwareId, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", &vendorId, &deviceId, &subSystemId, &revId);
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "Direct3D");
|
||||
ffStrbufInitStatic(&gpu->platformApi, "SetupAPI");
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
@@ -66,55 +46,77 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
gpu->deviceId = 0;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
|
||||
if (!ffRegReadStrbuf(hKey, L"DriverDesc", &gpu->name, NULL)) // faster, for some reason
|
||||
{
|
||||
wchar_t name[256];
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) name, sizeof(name), NULL))
|
||||
ffStrbufSetWS(&gpu->name, name);
|
||||
}
|
||||
ffRegReadStrbuf(hKey, L"DriverVersion", &gpu->driver, NULL);
|
||||
wchar_t buffer[256];
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
|
||||
ffStrbufSetWS(&gpu->name, buffer);
|
||||
|
||||
wmemcpy(regDirectxKey + regDirectxKeyPrefixLength, videoId, FF_GUID_STRLEN);
|
||||
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
|
||||
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
|
||||
FF_HKEY_AUTO_DESTROY hVideoIdKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
|
||||
if (!hVideoIdKey) continue;
|
||||
DWORD bufferLen = sizeof(buffer);
|
||||
if (RegGetValueW(hVideoIdKey, NULL, L"VideoID", RRF_RT_REG_SZ, NULL, buffer, &bufferLen) == ERROR_SUCCESS &&
|
||||
bufferLen == (FF_GUID_STRLEN + 1) * sizeof(wchar_t))
|
||||
{
|
||||
uint64_t dedicatedVideoMemory = 0;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, NULL))
|
||||
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
|
||||
uint64_t dedicatedSystemMemory, sharedSystemMemory;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
|
||||
ffRegReadUint64(hDirectxKey, L"SharedSystemMemory", &sharedSystemMemory, NULL))
|
||||
wmemcpy(regDirectxKey + regDirectxKeyPrefixLength, buffer, FF_GUID_STRLEN);
|
||||
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
|
||||
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
|
||||
{
|
||||
gpu->dedicated.total = dedicatedVideoMemory + dedicatedSystemMemory;
|
||||
gpu->shared.total = sharedSystemMemory;
|
||||
uint64_t dedicatedVideoMemory = 0;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, NULL))
|
||||
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
|
||||
uint64_t dedicatedSystemMemory, sharedSystemMemory;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
|
||||
ffRegReadUint64(hDirectxKey, L"SharedSystemMemory", &sharedSystemMemory, NULL))
|
||||
{
|
||||
gpu->dedicated.total = dedicatedVideoMemory + dedicatedSystemMemory;
|
||||
gpu->shared.total = sharedSystemMemory;
|
||||
}
|
||||
|
||||
ffRegReadUint64(hDirectxKey, L"AdapterLuid", &gpu->deviceId, NULL);
|
||||
|
||||
uint32_t featureLevel = 0;
|
||||
if(ffRegReadUint(hDirectxKey, L"MaxD3D12FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 12.%u", (featureLevel & 0x0F00) >> 8);
|
||||
else if(ffRegReadUint(hDirectxKey, L"MaxD3D11FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 11.%u", (featureLevel & 0x0F00) >> 8);
|
||||
|
||||
uint64_t driverVersion = 0;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DriverVersion", &driverVersion, NULL) && driverVersion)
|
||||
{
|
||||
ffStrbufSetF(&gpu->driver, "%u.%u.%u.%u",
|
||||
(unsigned) (driverVersion >> 48) & 0xFFFF,
|
||||
(unsigned) (driverVersion >> 32) & 0xFFFF,
|
||||
(unsigned) (driverVersion >> 16) & 0xFFFF,
|
||||
(unsigned) (driverVersion >> 0) & 0xFFFF
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t vendorId = 0;
|
||||
if(ffRegReadUint(hDirectxKey, L"VendorId", &vendorId, NULL) && vendorId)
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
}
|
||||
|
||||
ffRegReadUint64(hDirectxKey, L"AdapterLuid", &gpu->deviceId, NULL);
|
||||
|
||||
uint32_t featureLevel = 0;
|
||||
if(ffRegReadUint(hDirectxKey, L"MaxD3D12FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 12.%u", (featureLevel & 0x0F00) >> 8);
|
||||
else if(ffRegReadUint(hDirectxKey, L"MaxD3D11FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 11.%u", (featureLevel & 0x0F00) >> 8);
|
||||
}
|
||||
else if (!ffRegReadUint64(hKey, L"HardwareInformation.qwMemorySize", &gpu->dedicated.total, NULL))
|
||||
{
|
||||
uint32_t vmem = 0;
|
||||
if (ffRegReadUint(hKey, L"HardwareInformation.MemorySize", &vmem, NULL))
|
||||
gpu->dedicated.total = vmem;
|
||||
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
}
|
||||
|
||||
if (gpu->vendor.length == 0)
|
||||
{
|
||||
ffRegReadStrbuf(hKey, L"ProviderName", &gpu->vendor, NULL);
|
||||
if (ffStrbufContainS(&gpu->vendor, "Intel"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||
bufferLen = sizeof(buffer);
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DRIVER, NULL, (PBYTE) buffer, sizeof(buffer), &bufferLen) && bufferLen == (FF_GUID_STRLEN + strlen("\\0000") + 1) * 2)
|
||||
{
|
||||
wmemcpy(regDriverKey + regDriverKeyPrefixLength, buffer, FF_GUID_STRLEN + strlen("\\0000"));
|
||||
FF_HKEY_AUTO_DESTROY hRegDriverKey = NULL;
|
||||
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDriverKey, &hRegDriverKey, NULL))
|
||||
{
|
||||
if (ffRegReadStrbuf(hRegDriverKey, L"ProviderName", &gpu->vendor, NULL))
|
||||
{
|
||||
if (ffStrbufContainS(&gpu->vendor, "Intel"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__typeof__(&ffDetectNvidiaGpuInfo) detectFn;
|
||||
@@ -122,6 +124,13 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
|
||||
if (getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName) && (options->temp || options->driverSpecific))
|
||||
{
|
||||
unsigned vendorId = 0, deviceId = 0, subSystemId = 0, revId = 0;
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_HARDWAREID, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
|
||||
{
|
||||
swscanf(buffer, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", &vendorId, &deviceId, &subSystemId, &revId);
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
}
|
||||
|
||||
uint32_t pciBus, pciAddr;
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_BUSNUMBER, NULL, (PBYTE) &pciBus, sizeof(pciBus), NULL) &&
|
||||
SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_ADDRESS, NULL, (PBYTE) &pciAddr, sizeof(pciAddr), NULL))
|
||||
@@ -133,7 +142,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
&(FFGpuDriverCondition) {
|
||||
.type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID
|
||||
| (gpu->deviceId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_LUID : 0)
|
||||
| FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID,
|
||||
| (vendorId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0),
|
||||
.pciDeviceId = {
|
||||
.deviceId = deviceId,
|
||||
.vendorId = vendorId,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "initsystem.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/linux/elf.h"
|
||||
#include "util/binary.h"
|
||||
#include <unistd.h>
|
||||
|
||||
FF_MAYBE_UNUSED static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* data)
|
||||
@@ -49,7 +49,7 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
#if __linux__ && !__ANDROID__
|
||||
if (ffStrbufEqualS(&result->name, "systemd"))
|
||||
{
|
||||
ffElfExtractStrings(result->exe.chars, elfExtractStringsCallBack, &result->version);
|
||||
ffBinaryExtractStrings(result->exe.chars, elfExtractStringsCallBack, &result->version);
|
||||
if (result->version.length == 0)
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
|
||||
@@ -9,12 +9,12 @@ const char* ffDetectLoadavg(double result[3])
|
||||
|
||||
// Don't use syscall for container compatibility. #620
|
||||
char buf[64];
|
||||
ssize_t nRead = ffReadFileData("/proc/uptime", sizeof(buf) - 1, buf);
|
||||
ssize_t nRead = ffReadFileData("/proc/loadavg", sizeof(buf) - 1, buf);
|
||||
if (nRead > 0)
|
||||
{
|
||||
buf[nRead] = '\0';
|
||||
|
||||
if (sscanf(buf, "%lf %lf %lf", &result[0], &result[1], &result[2]) == 3)
|
||||
if (sscanf(buf, "%lf%lf%lf", &result[0], &result[1], &result[2]) == 3)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,19 +8,9 @@ void ffDetectLocale(FFstrbuf* result)
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
ffStrbufAppendS(result, getenv("LC_MESSAGES"));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
ffStrbufAppendS(result, getenv("LANG"));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
#ifdef LC_MESSAGES
|
||||
ffStrbufAppendS(result, setlocale(LC_MESSAGES, NULL));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
ffStrbufAppendS(result, setlocale(LC_TIME, NULL));
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ typedef struct FFLocalIpResult
|
||||
FFstrbuf ipv6;
|
||||
FFstrbuf mac;
|
||||
int32_t mtu;
|
||||
int32_t speed;
|
||||
bool defaultRoute;
|
||||
} FFLocalIpResult;
|
||||
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/sockios.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
#include <netpacket/packet.h>
|
||||
@@ -40,6 +46,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->mtu = -1;
|
||||
ip->speed = -1;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
@@ -172,9 +179,388 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, iface->name.chars, IFNAMSIZ - 1);
|
||||
|
||||
if (ioctl(sockfd, SIOCGIFMTU, &ifr) == 0)
|
||||
iface->mtu = (int32_t) ifr.ifr_mtu;
|
||||
|
||||
#ifdef __linux__
|
||||
struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET };
|
||||
ifr.ifr_data = (void*) &edata;
|
||||
if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0)
|
||||
iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android
|
||||
#elif __FreeBSD__ || __APPLE__
|
||||
struct ifmediareq ifmr = {};
|
||||
strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1);
|
||||
if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0)
|
||||
{
|
||||
switch (IFM_SUBTYPE(ifmr.ifm_active))
|
||||
{
|
||||
#ifdef IFM_HPNA_1
|
||||
case IFM_HPNA_1:
|
||||
#endif
|
||||
iface->speed = 1; break;
|
||||
#ifdef IFM_1000_CX
|
||||
case IFM_1000_CX:
|
||||
#endif
|
||||
#ifdef IFM_1000_CX_SGMII
|
||||
case IFM_1000_CX_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_1000_KX
|
||||
case IFM_1000_KX:
|
||||
#endif
|
||||
#ifdef IFM_1000_LX
|
||||
case IFM_1000_LX:
|
||||
#endif
|
||||
#ifdef IFM_1000_SGMII
|
||||
case IFM_1000_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_1000_SX
|
||||
case IFM_1000_SX:
|
||||
#endif
|
||||
#ifdef IFM_1000_T
|
||||
case IFM_1000_T:
|
||||
#endif
|
||||
iface->speed = 1000; break;
|
||||
#ifdef IFM_100G_AUI2
|
||||
case IFM_100G_AUI2:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI2_AC
|
||||
case IFM_100G_AUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI4
|
||||
case IFM_100G_AUI4:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI4_AC
|
||||
case IFM_100G_AUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI2
|
||||
case IFM_100G_CAUI2:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI2_AC
|
||||
case IFM_100G_CAUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI4
|
||||
case IFM_100G_CAUI4:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI4_AC
|
||||
case IFM_100G_CAUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CP2
|
||||
case IFM_100G_CP2:
|
||||
#endif
|
||||
#ifdef IFM_100G_CR4
|
||||
case IFM_100G_CR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_CR_PAM4
|
||||
case IFM_100G_CR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_DR
|
||||
case IFM_100G_DR:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR2_PAM4
|
||||
case IFM_100G_KR2_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR4
|
||||
case IFM_100G_KR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR_PAM4
|
||||
case IFM_100G_KR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_LR4
|
||||
case IFM_100G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_SR2
|
||||
case IFM_100G_SR2:
|
||||
#endif
|
||||
#ifdef IFM_100G_SR4
|
||||
case IFM_100G_SR4:
|
||||
#endif
|
||||
iface->speed = 100000; break;
|
||||
#ifdef IFM_100_FX
|
||||
case IFM_100_FX:
|
||||
#endif
|
||||
#ifdef IFM_100_SGMII
|
||||
case IFM_100_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_100_T
|
||||
case IFM_100_T:
|
||||
#endif
|
||||
#ifdef IFM_100_T2
|
||||
case IFM_100_T2:
|
||||
#endif
|
||||
#ifdef IFM_100_T4
|
||||
case IFM_100_T4:
|
||||
#endif
|
||||
#ifdef IFM_100_TX
|
||||
case IFM_100_TX:
|
||||
#endif
|
||||
#ifdef IFM_100_VG
|
||||
case IFM_100_VG:
|
||||
#endif
|
||||
iface->speed = 100; break;
|
||||
#ifdef IFM_10G_AOC
|
||||
case IFM_10G_AOC:
|
||||
#endif
|
||||
#ifdef IFM_10G_CR1
|
||||
case IFM_10G_CR1:
|
||||
#endif
|
||||
#ifdef IFM_10G_CX4
|
||||
case IFM_10G_CX4:
|
||||
#endif
|
||||
#ifdef IFM_10G_ER
|
||||
case IFM_10G_ER:
|
||||
#endif
|
||||
#ifdef IFM_10G_KR
|
||||
case IFM_10G_KR:
|
||||
#endif
|
||||
#ifdef IFM_10G_KX4
|
||||
case IFM_10G_KX4:
|
||||
#endif
|
||||
#ifdef IFM_10G_LR
|
||||
case IFM_10G_LR:
|
||||
#endif
|
||||
#ifdef IFM_10G_LRM
|
||||
case IFM_10G_LRM:
|
||||
#endif
|
||||
#ifdef IFM_10G_SFI
|
||||
case IFM_10G_SFI:
|
||||
#endif
|
||||
#ifdef IFM_10G_SR
|
||||
case IFM_10G_SR:
|
||||
#endif
|
||||
#ifdef IFM_10G_T
|
||||
case IFM_10G_T:
|
||||
#endif
|
||||
#ifdef IFM_10G_TWINAX
|
||||
case IFM_10G_TWINAX:
|
||||
#endif
|
||||
#ifdef IFM_10G_TWINAX_LONG
|
||||
case IFM_10G_TWINAX_LONG:
|
||||
#endif
|
||||
iface->speed = 10000; break;
|
||||
#ifdef IFM_10_2
|
||||
case IFM_10_2:
|
||||
#endif
|
||||
#ifdef IFM_10_5
|
||||
case IFM_10_5:
|
||||
#endif
|
||||
#ifdef IFM_10_FL
|
||||
case IFM_10_FL:
|
||||
#endif
|
||||
#ifdef IFM_10_STP
|
||||
case IFM_10_STP:
|
||||
#endif
|
||||
#ifdef IFM_10_T
|
||||
case IFM_10_T:
|
||||
#endif
|
||||
iface->speed = 10; break;
|
||||
#ifdef IFM_200G_AUI4
|
||||
case IFM_200G_AUI4:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI4_AC
|
||||
case IFM_200G_AUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI8
|
||||
case IFM_200G_AUI8:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI8_AC
|
||||
case IFM_200G_AUI8_AC:
|
||||
#endif
|
||||
#ifdef IFM_200G_CR4_PAM4
|
||||
case IFM_200G_CR4_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_200G_DR4
|
||||
case IFM_200G_DR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_FR4
|
||||
case IFM_200G_FR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_KR4_PAM4
|
||||
case IFM_200G_KR4_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_200G_LR4
|
||||
case IFM_200G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_SR4
|
||||
case IFM_200G_SR4:
|
||||
#endif
|
||||
iface->speed = 200000; break;
|
||||
#ifdef IFM_20G_KR2
|
||||
case IFM_20G_KR2:
|
||||
#endif
|
||||
iface->speed = 20000; break;
|
||||
#ifdef IFM_2500_KX
|
||||
case IFM_2500_KX:
|
||||
#endif
|
||||
#ifdef IFM_2500_SX
|
||||
case IFM_2500_SX:
|
||||
#endif
|
||||
#ifdef IFM_2500_T
|
||||
case IFM_2500_T:
|
||||
#endif
|
||||
#ifdef IFM_2500_X
|
||||
case IFM_2500_X:
|
||||
#endif
|
||||
iface->speed = 2500; break;
|
||||
#ifdef IFM_25G_ACC
|
||||
case IFM_25G_ACC:
|
||||
#endif
|
||||
#ifdef IFM_25G_AOC
|
||||
case IFM_25G_AOC:
|
||||
#endif
|
||||
#ifdef IFM_25G_AUI
|
||||
case IFM_25G_AUI:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR
|
||||
case IFM_25G_CR:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR1
|
||||
case IFM_25G_CR1:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR_S
|
||||
case IFM_25G_CR_S:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR
|
||||
case IFM_25G_KR:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR1
|
||||
case IFM_25G_KR1:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR_S
|
||||
case IFM_25G_KR_S:
|
||||
#endif
|
||||
#ifdef IFM_25G_LR
|
||||
case IFM_25G_LR:
|
||||
#endif
|
||||
#ifdef IFM_25G_PCIE
|
||||
case IFM_25G_PCIE:
|
||||
#endif
|
||||
#ifdef IFM_25G_SR
|
||||
case IFM_25G_SR:
|
||||
#endif
|
||||
#ifdef IFM_25G_T
|
||||
case IFM_25G_T:
|
||||
#endif
|
||||
iface->speed = 25000; break;
|
||||
#ifdef IFM_400G_AUI8
|
||||
case IFM_400G_AUI8:
|
||||
#endif
|
||||
#ifdef IFM_400G_AUI8_AC
|
||||
case IFM_400G_AUI8_AC:
|
||||
#endif
|
||||
#ifdef IFM_400G_DR4
|
||||
case IFM_400G_DR4:
|
||||
#endif
|
||||
#ifdef IFM_400G_FR8
|
||||
case IFM_400G_FR8:
|
||||
#endif
|
||||
#ifdef IFM_400G_LR8
|
||||
case IFM_400G_LR8:
|
||||
#endif
|
||||
iface->speed = 400000; break;
|
||||
#ifdef IFM_40G_CR4
|
||||
case IFM_40G_CR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_ER4
|
||||
case IFM_40G_ER4:
|
||||
#endif
|
||||
#ifdef IFM_40G_KR4
|
||||
case IFM_40G_KR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_LR4
|
||||
case IFM_40G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_SR4
|
||||
case IFM_40G_SR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLAUI
|
||||
case IFM_40G_XLAUI:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLAUI_AC
|
||||
case IFM_40G_XLAUI_AC:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLPPI
|
||||
case IFM_40G_XLPPI:
|
||||
#endif
|
||||
#ifdef IFM_40G_LM4
|
||||
case IFM_40G_LM4:
|
||||
#endif
|
||||
iface->speed = 40000; break;
|
||||
#ifdef IFM_5000_KR
|
||||
case IFM_5000_KR:
|
||||
#endif
|
||||
#ifdef IFM_5000_KR1
|
||||
case IFM_5000_KR1:
|
||||
#endif
|
||||
#ifdef IFM_5000_KR_S
|
||||
case IFM_5000_KR_S:
|
||||
#endif
|
||||
#ifdef IFM_5000_T
|
||||
case IFM_5000_T:
|
||||
#endif
|
||||
iface->speed = 5000; break;
|
||||
#ifdef IFM_50G_AUI1
|
||||
case IFM_50G_AUI1:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI1_AC
|
||||
case IFM_50G_AUI1_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI2
|
||||
case IFM_50G_AUI2:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI2_AC
|
||||
case IFM_50G_AUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_CP
|
||||
case IFM_50G_CP:
|
||||
#endif
|
||||
#ifdef IFM_50G_CR2
|
||||
case IFM_50G_CR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_FR
|
||||
case IFM_50G_FR:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR2
|
||||
case IFM_50G_KR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR_PAM4
|
||||
case IFM_50G_KR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_50G_LAUI2
|
||||
case IFM_50G_LAUI2:
|
||||
#endif
|
||||
#ifdef IFM_50G_LAUI2_AC
|
||||
case IFM_50G_LAUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_LR
|
||||
case IFM_50G_LR:
|
||||
#endif
|
||||
#ifdef IFM_50G_LR2
|
||||
case IFM_50G_LR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_PCIE
|
||||
case IFM_50G_PCIE:
|
||||
#endif
|
||||
#ifdef IFM_50G_SR
|
||||
case IFM_50G_SR:
|
||||
#endif
|
||||
#ifdef IFM_50G_SR2
|
||||
case IFM_50G_SR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR4
|
||||
case IFM_50G_KR4:
|
||||
#endif
|
||||
iface->speed = 50000; break;
|
||||
#ifdef IFM_56G_R4
|
||||
case IFM_56G_R4:
|
||||
#endif
|
||||
iface->speed = 56000; break;
|
||||
default:
|
||||
iface->speed = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __sun
|
||||
if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->ipv6);
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->speed = -1;
|
||||
ip->mtu = -1;
|
||||
}
|
||||
else
|
||||
@@ -150,7 +151,11 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
}
|
||||
|
||||
if (!newIp)
|
||||
FF_LIST_GET(FFLocalIpResult, *results, results->length - 1)->mtu = (int32_t) adapter->Mtu;
|
||||
{
|
||||
FFLocalIpResult* result = FF_LIST_GET(FFLocalIpResult, *results, results->length - 1);
|
||||
result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000);
|
||||
result->mtu = (int32_t) adapter->Mtu;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_15
|
||||
#import <IOKit/graphics/IOGraphicsLib.h>
|
||||
extern CFDictionaryRef CoreDisplay_IODisplayCreateInfoDictionary(io_service_t framebuffer, IOOptionBits options) __attribute__((weak_import));
|
||||
#else
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#endif
|
||||
|
||||
static bool detectHdrSupportWithNSScreen(FFDisplayResult* display)
|
||||
@@ -57,7 +56,7 @@ const char* ffDetectMonitor(FFlist* results)
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id);
|
||||
#else
|
||||
io_service_t servicePort = CGDisplayIOServicePort((CGDirectDisplayID) display->id);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
#endif
|
||||
if(!displayInfo) continue;
|
||||
|
||||
@@ -67,7 +66,7 @@ const char* ffDetectMonitor(FFlist* results)
|
||||
|
||||
uint8_t edidData[128] = {};
|
||||
uint32_t edidLength = 0;
|
||||
if (ffCfDictGetData(displayInfo, CFSTR("IODisplayEDID"), 0, sizeof(edidData), edidData, &edidLength) == NULL)
|
||||
if (ffCfDictGetData(displayInfo, CFSTR(kIODisplayEDIDKey), 0, sizeof(edidData), edidData, &edidLength) == NULL)
|
||||
{
|
||||
uint32_t width, height;
|
||||
ffEdidGetPhysicalResolution(edidData, &width, &height);
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef struct FFPackagesResult
|
||||
uint32_t guixHome;
|
||||
uint32_t guixSystem;
|
||||
uint32_t guixUser;
|
||||
uint32_t linglong;
|
||||
uint32_t lpkg;
|
||||
uint32_t lpkgbuild;
|
||||
uint32_t nixDefault;
|
||||
|
||||
@@ -471,6 +471,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
|
||||
{
|
||||
packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile");
|
||||
}
|
||||
if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", DT_DIR);
|
||||
}
|
||||
|
||||
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/linux/elf.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
static const char* getSystemMonospaceFont(void)
|
||||
{
|
||||
@@ -315,7 +315,7 @@ static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult*
|
||||
{
|
||||
ffStrbufClear(&font);
|
||||
|
||||
const char* error = ffElfExtractStrings(terminal->exePath.chars, elfExtractStringsCallBack, &font);
|
||||
const char* error = ffBinaryExtractStrings(terminal->exePath.chars, elfExtractStringsCallBack, &font);
|
||||
if (error)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, error);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "common/processing.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef __FreeBSD__
|
||||
@@ -250,8 +251,24 @@ FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version)
|
||||
return version->length > 0;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
|
||||
static bool extractGnomeTerminalVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
if (!ffCharIsDigit(str[0])) return true;
|
||||
int count = 0;
|
||||
sscanf(str, "%*d.%*d.%*d%n", &count);
|
||||
if (count == 0) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str);
|
||||
return false;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
if (exe->chars[0] == '/')
|
||||
{
|
||||
ffBinaryExtractStrings(exe->chars, extractGnomeTerminalVersion, version);
|
||||
if (version->length) return true;
|
||||
}
|
||||
|
||||
if(ffProcessAppendStdOut(version, (char* const[]){
|
||||
"gnome-terminal",
|
||||
"--version",
|
||||
@@ -590,7 +607,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(processName, "gnome-terminal"))
|
||||
return getTerminalVersionGnome(version);
|
||||
return getTerminalVersionGnome(exe, version);
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(processName, "konsole"))
|
||||
return getTerminalVersionKonsole(exe, version);
|
||||
|
||||
@@ -384,6 +384,14 @@ const FFShellResult* ffDetectShell()
|
||||
result.tty = -1;
|
||||
|
||||
pid_t ppid = getppid();
|
||||
|
||||
const char* ignoreParent = getenv("FFTS_IGNORE_PARENT");
|
||||
if (ignoreParent && ffStrEquals(ignoreParent, "1"))
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY _ = ffStrbufCreate();
|
||||
ffProcessGetBasicInfoLinux(ppid, &_, &ppid, NULL);
|
||||
}
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
getUserShellFromEnv(&result);
|
||||
setShellInfoDetails(&result);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
@@ -345,6 +346,10 @@ const FFShellResult* ffDetectShell(void)
|
||||
if(!ffProcessGetInfoWindows(0, &ppid, NULL, NULL, NULL, NULL, NULL))
|
||||
return &result;
|
||||
|
||||
const char* ignoreParent = getenv("FFTS_IGNORE_PARENT");
|
||||
if (ignoreParent && ffStrEquals(ignoreParent, "1"))
|
||||
ffProcessGetInfoWindows(ppid, &ppid, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
|
||||
if (result.processName.length > 0)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "version.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64)
|
||||
#if defined(__x86_64__)
|
||||
#define FF_ARCHITECTURE "x86_64"
|
||||
#elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(__i586__) || defined(__i586) || defined(__i686__) || defined(__i686)
|
||||
#elif defined(__i386__)
|
||||
#define FF_ARCHITECTURE "i386"
|
||||
#elif defined(__aarch64__)
|
||||
#define FF_ARCHITECTURE "aarch64"
|
||||
@@ -16,6 +16,8 @@
|
||||
#define FF_ARCHITECTURE "riscv"
|
||||
#elif defined(__s390x__)
|
||||
#define FF_ARCHITECTURE "s390x"
|
||||
#elif defined(__loongarch__)
|
||||
#define FF_ARCHITECTURE "loongarch"
|
||||
#else
|
||||
#define FF_ARCHITECTURE "unknown"
|
||||
#endif
|
||||
|
||||
@@ -13,4 +13,4 @@ ${c1} ///////${c3}\\\\\\\\\\//
|
||||
/\\\/${c1}\\/
|
||||
/\\\\//
|
||||
//////
|
||||
/// ${c3}\\\\\
|
||||
/// ${c3}\\\\\
|
||||
@@ -18,4 +18,4 @@ oOO OOo
|
||||
oO OOo
|
||||
oOO OOo
|
||||
oOO OOo
|
||||
ooo OOO OOO ooo
|
||||
ooo OOO OOO ooo
|
||||
@@ -12,4 +12,4 @@ ${c1}g@@@@M" ${c2}"VP`${c3}.L! ${c4}<@JJJJ`
|
||||
${c3}.@FJJJF`${c4},@LFFFF`
|
||||
${c3}_@FFFFF ${c4}VLLLP`
|
||||
${c3}J@@LL@" ${c4}`"
|
||||
${c3}V@@"
|
||||
${c3}V@@"
|
||||
@@ -3,4 +3,4 @@ ${c1} /\\ /\\
|
||||
/${c2}// ${c1}\\ \\
|
||||
/${c2}// ${c1}\\ \\
|
||||
${c2}// ${c1}\\ \\
|
||||
\\
|
||||
\\
|
||||
@@ -17,4 +17,4 @@
|
||||
@~:~~: ~:~~:~:(zltlltlO a,wwwwww
|
||||
8~~:~~:~~~~:~~~~_1ltltu ,www
|
||||
5~~:~~:~~:~~:~~:~~~_1ltq N,,
|
||||
g~:~~:~~~:~~:~~:~:~~~~1q N,
|
||||
g~:~~:~~~:~~:~~:~:~~~~1q N,
|
||||
@@ -19,4 +19,4 @@
|
||||
#####$2##%:$3######$2:############$1##
|
||||
##$2+##*$3########$2############$1
|
||||
$2###$3#########$2##########$1
|
||||
$3########$2######
|
||||
$3########$2######
|
||||
@@ -16,4 +16,4 @@ dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd
|
||||
dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd
|
||||
.:+ydNMMMMMMMMMMMh yMMMMMMMMMMMNdy+:.
|
||||
`.:+shNMMMMMh yMMMMMNhs+:``
|
||||
`-+shy shs+:`
|
||||
`-+shy shs+:`
|
||||
@@ -7,4 +7,4 @@
|
||||
~~~ /
|
||||
~~._. _/
|
||||
_/ _/
|
||||
_/m/'
|
||||
_/m/'
|
||||
@@ -16,4 +16,4 @@ ${c1} ___________
|
||||
| / ____/ |
|
||||
\_________/ / |
|
||||
\ __/
|
||||
\_______/
|
||||
\_______/
|
||||
@@ -25,4 +25,4 @@
|
||||
${c2}.${c1} ${c2}.:+++${c1}.
|
||||
${c2}.:${c1}:
|
||||
${c2}..${c1}
|
||||
${c2}..${c1}
|
||||
${c2}..${c1}
|
||||
@@ -16,4 +16,4 @@ dmmmdddddddhhhyso${c1}++++++${c2}shhhhhddddddmmmmh
|
||||
-dmmmdddddddhhys${c1}o++++o${c2}shhhhdddddddmmmmd-
|
||||
.smmmmddddddddhhhhhhhhhdddddddddmmmms.
|
||||
`+ydmmmdddddddddddddddddddmmmmdy/.
|
||||
`.:+ooyyddddddddddddyyso+:.`
|
||||
`.:+ooyyddddddddddddyyso+:.`
|
||||
@@ -9,4 +9,4 @@
|
||||
\,_/\_/ | |_/|_/|_/_/ \,
|
||||
, / ,\
|
||||
, / , ' \
|
||||
' - , _ _ _ , '
|
||||
' - , _ _ _ , '
|
||||
@@ -14,4 +14,4 @@ ${c4}^MMM@@@@@@@@@@@MP" ${c3},ggppww__
|
||||
${c3}_gBNNNNNNNNNNNNNNNNNP"
|
||||
${c3}_wNNNNNNNNNNNNNNNNNNNM^
|
||||
${c3}""Y^^MNNNNNNNNNNNNP`
|
||||
${c3}`"""""""
|
||||
${c3}`"""""""
|
||||
@@ -17,4 +17,4 @@
|
||||
+NMMMMMms/.` mMMMMMMMMMMMN+
|
||||
`+mMMMMMMMMNmddMMMMMMMMMMm+`
|
||||
.ohNMMMMMMMMMMMMMMNho.
|
||||
.:+syhhhhys+:.
|
||||
.:+syhhhhys+:.
|
||||
@@ -15,4 +15,4 @@ ${c2} .........
|
||||
${c3}................ ${c4}***********
|
||||
${c3}................ ${c4}###########
|
||||
${c3}****************
|
||||
${c3}################
|
||||
${c3}################
|
||||
@@ -6,4 +6,4 @@ ${c2} _____ ${c1}_____${c2}
|
||||
\\ / _____ \\${c4}___
|
||||
${c3}|${c2}/_/ ${c3}| ${c4}| |
|
||||
${c3}| | ${c4}|___|
|
||||
${c3}|_____|
|
||||
${c3}|_____|
|
||||
@@ -17,4 +17,4 @@
|
||||
=XMMM@MM@MM#H;,-+HMM@M+ /MMMX=
|
||||
=%@M@M#@S-.=S@MM@@@M; %M%=
|
||||
,:+S+-,/H#MMMMMMM@= =,
|
||||
=++%%%%+/:-.
|
||||
=++%%%%+/:-.
|
||||
@@ -15,4 +15,4 @@ MMMMMM/`.-/ohmNMMMMMMy-
|
||||
MMMMMMNmNNMMMMMMMMmo.
|
||||
MMMMMMMMMMMMMMMms:`
|
||||
MMMMMMMMMMNds/.
|
||||
dhhyys+/-`
|
||||
dhhyys+/-`
|
||||
@@ -16,4 +16,4 @@ $2 .oossssso-````/ossssss+`
|
||||
`/ossssso+/:- -:/+osssso+-
|
||||
`+sso+:-` `.-/+oso:
|
||||
`++:. `-/+/
|
||||
.` `/
|
||||
.` `/
|
||||
@@ -16,4 +16,4 @@ $2 ▟█████████▛▀▀▜████████▙
|
||||
▟██████████▛ ▜█████████▙
|
||||
▟██████▀▀▀ ▀▀██████▙
|
||||
▟███▀▘ ▝▀███▙
|
||||
▟▛▀ ▀▜▙
|
||||
▟▛▀ ▀▜▙
|
||||
@@ -16,4 +16,4 @@ $2 / ,.-+-.. \
|
||||
/ __,--+" "+--.__ \
|
||||
/ _,+'" "'+._ \
|
||||
/,-' `-.\
|
||||
' '
|
||||
' '
|
||||
@@ -4,4 +4,4 @@
|
||||
/ \
|
||||
$2 / ,, \
|
||||
/ | | \
|
||||
/_-'' ''-_\
|
||||
/_-'' ''-_\
|
||||
@@ -16,4 +16,4 @@
|
||||
/:::+`hhhhoos` `hhhhhhhhhhhhhhhhhs+`
|
||||
`--/:` /: `hhhhhhhhhhhho/-
|
||||
-/:. `hhhhhhs+:-`
|
||||
::::/ho/-`
|
||||
::::/ho/-`
|
||||
@@ -17,4 +17,4 @@ ${c4}⠄⠄⠄⠄${c1}⢀⣾⣿⣿⣿⣿⣿⣿⣷⣤⡀${c4}⠄⠄⠄${c1}⠻⣿
|
||||
${c5}⠄⠄⠄${c1}⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏${c5}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⢿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀${c5}⠄⠄⠄
|
||||
${c6}⠄⠄${c1}⢠⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⠁${c6}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠙⠻⣿⣿⣿⣿⣿⣿⣿⣿⡄${c6}⠄⠄
|
||||
${c1}⠄${c1}⣠⣿⣿⣿⣿⠿⠛⠋⠁${c1}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠻⢿⣿⣿⣿⣿⣆${c1}⠄
|
||||
${c1}⡰⠟⠛⠉⠁${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠛⠿⢆
|
||||
${c1}⡰⠟⠛⠉⠁${c2}⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄${c1}⠉⠙⠛⠿⢆
|
||||
@@ -17,4 +17,4 @@
|
||||
+ooooooooos. .=sooooooo+-
|
||||
.+osossos+-` `-+osososs+.
|
||||
:sss+=-:` `:-=+ssss:
|
||||
:=-:` `-=+:
|
||||
:=-:` `-=+:
|
||||
@@ -18,4 +18,4 @@
|
||||
'xKXXXXK0kdl:. $2.ok; $1.cdk0KKXXXKx'
|
||||
'xKK0koc,.. $2'c, $1 ..,cok0KKk,
|
||||
,xko:'. $2.. $1 .':okx;
|
||||
.,'. .',.
|
||||
.,'. .',.
|
||||
@@ -14,4 +14,4 @@ ${c1} *
|
||||
****${c2}/${c1}**** ${c2}/////${c1}***${c2}/${c1}****
|
||||
******${c2}/${c1}*** ${c2}//// ${c1}**${c2}/${c1}******
|
||||
********${c2}/${c1}* ${c2}/// ${c1}*${c2}/${c1}********
|
||||
,****** ${c2}// ______ / ${c1}******,
|
||||
,****** ${c2}// ______ / ${c1}******,
|
||||
@@ -8,4 +8,4 @@
|
||||
ooooo ooooo
|
||||
ooooo ${c2}<oooooooo>${c1}
|
||||
ooooo ${c2}<oooooo>${c1}
|
||||
ooooo ${c2}<oooo>
|
||||
ooooo ${c2}<oooo>
|
||||
@@ -20,4 +20,4 @@ $2.-==+++***++*$3*#########$1=:::.
|
||||
$2.-=++++*++++**$3#######%%###$1=
|
||||
$2.:==++++++**$3#############$1:
|
||||
$2.$1-+*++*+++==$3###$1+
|
||||
-$3*+$1:
|
||||
-$3*+$1:
|
||||
@@ -19,4 +19,4 @@ l**c)tttttttttttttttttttttttt(z**,
|
||||
'I)$2))(\()($1tt$2))|\()($1{;'
|
||||
$2.~~~~~~~|)~~~~~~~<$1
|
||||
'$2[)))))1$1|($2)))))))$1?
|
||||
$2",,," ",,,^
|
||||
$2",,," ",,,^
|
||||
@@ -11,4 +11,4 @@
|
||||
▄▄██ ██ ██ ██▄▄
|
||||
▄▄██ ██▄▄
|
||||
███████████████████████
|
||||
█ █ █ █ █ █ █ █ █ █ █
|
||||
█ █ █ █ █ █ █ █ █ █ █
|
||||
@@ -12,4 +12,4 @@
|
||||
⢸⣿⠀⠀⠀⠀⠀⣤⣤⣴⣶⣾⠿⠟⣿⡏⠙⠛⠛⠛⠋⠉⢀⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⣿⡄⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⢸⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⠇⠀⠀⠀⠀⠀⠀⠘⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
@@ -10,4 +10,4 @@
|
||||
'ookxxkoo'` .'oo'
|
||||
'ooxoo'` .:ooxxo'
|
||||
'io'` `'oo'
|
||||
'` `'
|
||||
'` `'
|
||||
@@ -12,4 +12,4 @@ ${c1} +yyyyyys :yyyyyy/${c2}-yyyyyy+
|
||||
${c1} .oyyyyyyo. :yyyyyy/${c2}-yyyyyy+ ---------
|
||||
${c1} .syyyyyy+` :yyyyyy/${c2}-yyyyy+-+syyyyyyyy
|
||||
${c1} -syyyyyy/ :yyyyyy/${c2}-yyys:.syyyyyyyyyy
|
||||
${c1}:syyyyyy/ :yyyyyy/${c2}-yyo.:syyyyyyyyyyy
|
||||
${c1}:syyyyyy/ :yyyyyy/${c2}-yyo.:syyyyyyyyyyy
|
||||
@@ -15,4 +15,4 @@ $3((((((((((((((((((((($5@@@$6&%&$5@@@%$4,..........
|
||||
$3/(((((((((((($5@@@@@@/$4.../&&
|
||||
$3.((((((((($5@@@@($4....
|
||||
$3/((((($5@@#$4...
|
||||
$3.(($4&,
|
||||
$3.(($4&,
|
||||
@@ -15,4 +15,4 @@ $4_MMMMMMMMMMMMMMMMMMMM$5MMMM$7M0$5MMMW$6MMMMMMMMMM_
|
||||
$4~MMMMMMMMMM$5MMMMM$60MMM~~
|
||||
$4~MMMMMM$5MMM$60MM~
|
||||
$4~MM$5M$6@~
|
||||
$4M
|
||||
$4M
|
||||
@@ -15,4 +15,4 @@ cMM; dMMW'
|
||||
OMMc ...
|
||||
xMMx
|
||||
;XMN:
|
||||
,.
|
||||
,.
|
||||
@@ -14,4 +14,4 @@ ${c3} /######## ########
|
||||
${c4} #######%#######
|
||||
${c4} (#%%%%%%%#
|
||||
${c4} %%%%%
|
||||
${c4} %%%
|
||||
${c4} %%%
|
||||
@@ -20,4 +20,4 @@ uURF$##Bv nKWB$%ABc aM@3R@D@b
|
||||
8 M @ O # %
|
||||
% & G U @ @
|
||||
& @ # % % #
|
||||
!HGN@MNCf t&S9#%HQr ?@G#6S@QP
|
||||
!HGN@MNCf t&S9#%HQr ?@G#6S@QP
|
||||
@@ -19,4 +19,4 @@ ${c1} aA${c2}/${c1}a${c2}\\\\\\${c1}Aa${c2}\\/${c1}AA${c2}\\\\\\\\\\${c1}A
|
||||
${c1} aA${c2}/${c1}aA${c2}\\\\/${c1}aAa aAa${c2}\\\\\\${c1}Aa${c2}\\${c1}Aa
|
||||
${c1} aA${c2}/\\${c1}A${c2}\\/${c1}Aa aA${c2}\\\\${c1}A${c2}\\\\${c1}Aa
|
||||
${c1} A${c2}|/${c1}aaAa aAaa${c2}\\|${c1}A
|
||||
${c1} aAaa aaAa
|
||||
${c1} aAaa aaAa
|
||||
@@ -21,4 +21,4 @@ ${c1} ###### ${c2}########${c1} #
|
||||
${c1} ### ${c2}#######${c1}
|
||||
${c1} ${c2}######${c1}
|
||||
${c1} ${c2}####${c1}
|
||||
${c1} ${c2}##${c1}
|
||||
${c1} ${c2}##${c1}
|
||||
@@ -14,4 +14,4 @@ ${c1}//////// ///////// ${c2} &(((((((( @((((((((
|
||||
${c1}//////// ////// ${c2} @(((( @((((((((
|
||||
${c1}//////// ${c2} @((((((((
|
||||
${c1}//////// ${c2} @((((((((
|
||||
${c1} ///// ${c2} (((((
|
||||
${c1} ///// ${c2} (((((
|
||||
@@ -16,4 +16,4 @@ ${c3} .X. oMMMMW. l.
|
||||
dMk:..;xWMMMMW,
|
||||
kMMMMMMMMMMX.
|
||||
:XMMMMMMK:
|
||||
':MM:" Made in Brazil
|
||||
':MM:" Made in Brazil
|
||||
@@ -14,4 +14,4 @@
|
||||
:NMMMNmmmmmMMh
|
||||
/MN/-------oNN:
|
||||
hMd. .dMh
|
||||
sm/ /ms
|
||||
sm/ /ms
|
||||
@@ -18,4 +18,4 @@ ${c2} .oossssso-`${c3}//${c1}`/ossssss+`
|
||||
`/ossssso+/:- ${c3}//${c1} -:/+osssso+-
|
||||
`+sso+:-` ${c3}//${c1} `.-/+oso:
|
||||
`++:. ${c3}//${c1} `-/+/
|
||||
.` ${c3}/${c1} `/
|
||||
.` ${c3}/${c1} `/
|
||||
@@ -17,4 +17,4 @@ H@: :HHHHHHHHHHHHHHHHHHX, =@H
|
||||
=X@@@@@@@@@@@@@@@@@@@@@@@@@@@X=
|
||||
:$$@@@@@@@@@@@@@@@@@@M@@@@$$:
|
||||
\$$@@@@@@@@@@@@@@@@@@X/-
|
||||
.-;+$$XXHHHHHX$$+;-.
|
||||
.-;+$$XXHHHHHX$$+;-.
|
||||
@@ -20,4 +20,4 @@ ${c3} ........
|
||||
`╙▀█▄@»»»;`▀███▌¿ ,▄▀Ñ"`
|
||||
`"╨▀█▄▄▄░`▐█████▄, ,▄▄▀▀░`
|
||||
`"╙╩▀▀▀▀████████▓▌▌▌▀▀▀╨"``
|
||||
``""░╚╨╝╝╝╝╨╨░""``
|
||||
``""░╚╨╝╝╝╝╨╨░""``
|
||||
@@ -14,4 +14,4 @@
|
||||
.NMMMMMNd. `':ldko
|
||||
OMMMK:
|
||||
oWk,
|
||||
;:
|
||||
;:
|
||||
@@ -14,4 +14,4 @@ ${c2} +MMMMMMMNho:.` `.:ohNMMMMMMNo ${c1}`yyyyys
|
||||
${c2} -hMMMMMMMMNNNmmNNNMMMMMMMMh- ${c1}`yyyyys
|
||||
${c2} :yNMMMMMMMMMMMMMMMMMMNy:` ${c1}`yyyyys
|
||||
${c2} .:sdNMMMMMMMMMMNds/. ${c1}`yyyyyo
|
||||
${c2} `.:/++++/:.` ${c1}:oys+.
|
||||
${c2} `.:/++++/:.` ${c1}:oys+.
|
||||
@@ -16,4 +16,4 @@
|
||||
./oyyyyyyyyyo......${c1}+mMMMMMMMM${c2}
|
||||
omdyyyyyyo....${c1}+mMMMMMMMMMM${c2}
|
||||
${c1}oMMM${c2}mdhyyo..${c1}+mMMMMMMMMMMMM
|
||||
oNNNNNNm${c2}dso${c1}mMMMMMMMMMMMMMM
|
||||
oNNNNNNm${c2}dso${c1}mMMMMMMMMMMMMMM
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user