Merge pull request #1050 from fastfetch-cli/dev

Release: v2.17.0
This commit is contained in:
Carter Li
2024-06-28 11:31:00 +08:00
committed by GitHub
50 changed files with 948 additions and 395 deletions
+12 -6
View File
@@ -494,7 +494,7 @@ jobs:
with:
msystem: CLANG64
update: true
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-cppwinrt
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt
- name: print msys version
run: uname -a
@@ -508,6 +508,9 @@ jobs:
- name: copy necessary dlls
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
- name: download amd_ags
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x64.dll
- name: list features
run: ./fastfetch --list-features
@@ -527,10 +530,10 @@ jobs:
run: ctest
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip *.dll fastfetch.exe flashfetch.exe presets
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-amd64.7z *.dll fastfetch.exe flashfetch.exe presets
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-amd64.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v4
@@ -556,7 +559,7 @@ jobs:
with:
msystem: CLANG32
update: true
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-opencl-headers
- name: print msys version
run: uname -a
@@ -578,6 +581,9 @@ jobs:
- name: copy necessary dlls
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
- name: download amd_ags
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x86.dll
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc
@@ -594,10 +600,10 @@ jobs:
run: ctest
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip *.dll fastfetch.exe flashfetch.exe presets
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z *.dll fastfetch.exe flashfetch.exe presets
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v4
+43
View File
@@ -1,3 +1,46 @@
# 2.17.0
Changes:
* CMake option `ENABLE_PROPRIETARY_GPU_DRIVER_API` is removed. The GPU driver APIs are now enabled by default.
* The option was introduced to reduce the license concerns. Since all non MIT proprietary code has been rewritten manually from scratch, it is no longer necessary.
* See <https://github.com/fastfetch-cli/fastfetch/issues/533#issuecomment-2122830958> for detail
* Option `--logo-separate true` is changed to `--logo-position top` for better readability
* Builtin ascii logos can be positioned on the right side now with`--logo-position right`
Features:
* Add support for `--gpu-detection-method opencl` which uses OpenCL to detect GPUs.
* Support detecting CPU cache size by using SMBIOS as fallback (CPUCache)
* Support GPU detection (SunOS)
* Support GPU type detection with AMD GPU driver (GPU, Windows)
* Add fast path of version and font detection for kitty (Terminal / TerminalFont)
* Make sure `stdin` and `stdout` are TTYs when querying terminal
* So modules like `TerminalSize` should work when `stdin` or `stdout` is redirected
* Support argument truncation in `--<module>-format` (#1043)
* See `fastfetch --help format` for detail
* Improve Qt theme detection (#1047, Theme, Linux)
* Add new JSON config option `general.preRun`, which is executed before fastfetch prints output.
* It can be used to generate a temp logo file. For example
```jsonc
{
"general": {
"preRun": "kitten icat --align=left /path/to/image > /tmp/logo.kitty"
},
"logo": {
"source": "/tmp/logo.kitty",
"type": "raw"
}
}
```
Bugfixes:
* Fix invalid path (#1031, LM, Linux)
* Fix VMEM detection for Nvidia GPU (requires `--gpu-driver-specific`) (GPU)
* Fix AMD `--gpu-driver-specific` for AMD cards (#1032, GPU, Windows)
* Use Coordinated Universal Time rather than timezone-varying local date (#1046)
Logo:
* Fix colors of Asahi Linux
# 2.16.0
This release added basic support for SunOS (Solaris, illumos). The binaries provided in the release lack a few useful features (such as Display detection). People who use SunOS should consider building fastfetch themselves.
+19 -20
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.16.0
VERSION 2.17.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -64,7 +64,7 @@ cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENAB
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_LIBNM "Enable libnm" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
@@ -74,7 +74,6 @@ cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND"
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
option(ENABLE_PROPRIETARY_GPU_DRIVER_API "Enable proprietary GPU driver API (NVML, IGCL and AGS)" ON)
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
@@ -256,7 +255,7 @@ if(APPLE)
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
endif()
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y")
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC)
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
####################
@@ -549,7 +548,7 @@ elseif(BSD)
src/detection/brightness/brightness_bsd.c
src/detection/chassis/chassis_bsd.c
src/detection/cpu/cpu_bsd.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpucache/cpucache_shared.c
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
@@ -749,7 +748,7 @@ elseif(SunOS)
src/detection/brightness/brightness_nosupport.c
src/detection/chassis/chassis_windows.c
src/detection/cpu/cpu_sunos.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpucache/cpucache_shared.c
src/detection/cpuusage/cpuusage_sunos.c
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_nosupport.c
@@ -813,15 +812,13 @@ if(ENABLE_DIRECTX_HEADERS)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_wsl.cpp)
endif()
if(ENABLE_PROPRIETARY_GPU_DRIVER_API AND (LINUX OR BSD OR WIN32))
message(STATUS "Enabling proprietary GPU driver API")
if(LINUX OR BSD OR WIN32)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
endif()
if(WIN32)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
endif()
# Proprietary GPU driver APIs
if(LINUX OR BSD OR WIN32)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
endif()
if(WIN32)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
endif()
include(CheckFunctionExists)
@@ -850,10 +847,6 @@ add_library(libfastfetch OBJECT
${LIBFASTFETCH_SRC}
)
if(ENABLE_PROPRIETARY_GPU_DRIVER_API AND (LINUX OR BSD OR WIN32))
target_compile_definitions(libfastfetch PRIVATE FF_USE_PROPRIETARY_GPU_DRIVER_API)
endif()
if(yyjson_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_USE_SYSTEM_YYJSON)
target_link_libraries(libfastfetch PRIVATE yyjson::yyjson)
@@ -1082,7 +1075,6 @@ if(LINUX)
)
elseif(APPLE)
target_link_libraries(libfastfetch
PRIVATE "resolv"
PRIVATE "-framework AVFoundation"
PRIVATE "-framework Cocoa"
PRIVATE "-framework CoreFoundation"
@@ -1267,6 +1259,13 @@ install(
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
if (TARGET ffwinrt)
install(
TARGETS ffwinrt
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
install(
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.bash"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions"
+2 -1
View File
@@ -11,7 +11,7 @@
[![latest packaged version(s)](https://repology.org/badge/latest-versions/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
[![Packaging status](https://repology.org/badge/tiny-repos/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, macOS, SunOS and Windows 7+ are supported.
<img src="screenshots/example1.png" width="49%" align="left" />
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
@@ -30,6 +30,7 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
Some distros packaged an outdated fastfetch version. Older version is not supported, please always ensure that the latest version is used.
* 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 / 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`
+1
View File
@@ -347,6 +347,7 @@ __fastfetch_completion()
"--users-key"
"--users-format"
"--users-key-color"
"--users-myself-only"
"--bluetooth-key"
"--bluetooth-format"
"--bluetooth-key-color"
+6
View File
@@ -1,3 +1,9 @@
fastfetch (2.16.0) jammy; urgency=medium
* Update to 2.16.0
-- Carter Li <zhangsongcui@live.cn> Wed, 19 Jun 2024 14:53:43 +0800
fastfetch (2.15.0) jammy; urgency=medium
* Update to 2.15.0
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.15.0_source.buildinfo universe/utils optional
fastfetch_2.16.0_source.buildinfo universe/utils optional
+19 -6
View File
@@ -23,7 +23,7 @@
"default": 0
},
"format": {
"description": "Output format of the module. See `-h &lt;module&gt;-format` for detail",
"description": "Output format of the module. See `-h <module>-format` for detail. I.e: fastfetch -h disk-format",
"type": "string"
},
"outputColor": {
@@ -89,10 +89,12 @@
"default": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"
},
"logo": {
"description": "Fastfetch logo configurations\nSee also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
"oneOf": [
{
"description": "Disable logo",
"type": "null"
"type": "null",
"const": null
},
{
"description": "Set the source file of the logo",
@@ -217,10 +219,15 @@
"description": "If true, regenerate image logo cache",
"default": false
},
"separate": {
"type": "boolean",
"description": "If true, print modules at bottom of the logo",
"default": false
"position": {
"type": "string",
"description": "Set the position of the logo should be displayed",
"enum": [
"left",
"top",
"right"
],
"default": "left"
},
"chafa": {
"type": "object",
@@ -327,6 +334,11 @@
"type": "integer",
"description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
"default": 1000
},
"preRun": {
"type": "string",
"description": "Set the command to be executed before printing logos",
"default": ""
}
}
},
@@ -1523,6 +1535,7 @@
"auto",
"pci",
"vulkan",
"opencl",
"opengl"
],
"default": "auto"
+47 -34
View File
@@ -52,24 +52,28 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
* @param placeholderValue the string to parse
* @return uint32_t the parsed value
*/
static uint32_t getArgumentIndex(const FFstrbuf* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
static uint32_t getArgumentIndex(const char* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
{
char firstChar = placeholderValue->chars[0];
char firstChar = placeholderValue[0];
if (firstChar == '\0')
return 0; // use arg counter
if(firstChar >= '1' && firstChar <= '9')
if (firstChar >= '0' && firstChar <= '9')
{
char* pEnd = NULL;
unsigned long result = strtoul(placeholderValue->chars, &pEnd, 10);
if (pEnd != placeholderValue->chars + placeholderValue->length || result > numArgs)
uint32_t result = (uint32_t) strtoul(placeholderValue, &pEnd, 10);
if (result > numArgs)
return UINT32_MAX;
return (uint32_t) result;
if (*pEnd != '\0')
return UINT32_MAX;
return result;
}
else if (ffCharIsEnglishAlphabet(firstChar))
{
for (uint32_t i = 0; i < numArgs; ++i)
{
const FFformatarg* arg = &arguments[i];
if(arg->name && ffStrbufIgnCaseEqualS(placeholderValue, arg->name))
if (arg->name && strcasecmp(placeholderValue, arg->name) == 0)
return i + 1;
}
}
@@ -86,16 +90,6 @@ static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start,
ffStrbufAppendC(buffer, '}');
}
static inline void appendEmptyPlaceholder(FFstrbuf* buffer, const char* placeholder, uint32_t* argCounter, uint32_t numArgs, const FFformatarg* arguments)
{
if(*argCounter >= numArgs)
ffStrbufAppendS(buffer, placeholder);
else
ffFormatAppendFormatArg(buffer, arguments + *argCounter);
(*argCounter)++;
}
static inline bool formatArgSet(const FFformatarg* arg)
{
return arg->value != NULL && (
@@ -128,13 +122,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
// if we have an { at the end handle it as {}
if(i == formatstr->length - 1)
{
appendEmptyPlaceholder(buffer, "{", &argCounter, numArgs, arguments);
continue;
}
// jump to next char, the start of the placeholder value
++i;
@@ -145,13 +132,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
// placeholder is {}
if(formatstr->chars[i] == '}')
{
appendEmptyPlaceholder(buffer, "{}", &argCounter, numArgs, arguments);
continue;
}
ffStrbufClear(&placeholderValue);
{
@@ -205,7 +185,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
{
ffStrbufSubstrAfter(&placeholderValue, 0);
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// testing for an invalid index
if (index > numArgs)
@@ -231,7 +211,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
{
ffStrbufSubstrAfter(&placeholderValue, 0);
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// testing for an invalid index
if (index > numArgs)
@@ -264,16 +244,49 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
int32_t truncLength = INT32_MAX;
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
if (pColon != NULL)
{
char* pEnd = NULL;
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
if (*pEnd != '\0')
{
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
*pColon = '\0';
}
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
// test for invalid index
if (index == 0)
index = ++argCounter;
if (index > numArgs)
{
if (pColon) *pColon = ':';
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
bool ellipsis = false;
if (truncLength < 0)
{
ellipsis = true;
truncLength = -truncLength;
}
uint32_t oldLength = buffer->length;
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
if (buffer->length - oldLength > (uint32_t) truncLength)
{
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
ffStrbufTrimRightSpace(buffer);
if (ellipsis)
ffStrbufAppendS(buffer, "…");
}
}
if (!instance.config.display.pipe)
-3
View File
@@ -254,9 +254,6 @@ void ffListFeatures(void)
#ifdef FF_HAVE_DIRECTX_HEADERS
"Directx Headers\n"
#endif
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
"Proprietary GPU driver API\n"
#endif
#ifdef FF_USE_SYSTEM_YYJSON
"System yyjson\n"
#endif
+26 -14
View File
@@ -133,32 +133,44 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
{
if (instance.config.display.pipe)
return "Not supported in --pipe mode";
int fin = STDIN_FILENO, fout = STDOUT_FILENO;
FF_AUTO_CLOSE_FD int ftty = -1;
struct termios oldTerm, newTerm;
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
if (!isatty(STDIN_FILENO))
{
if (ftty < 0)
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
fin = ftty;
}
if (!isatty(STDOUT_FILENO))
{
if (ftty < 0)
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
fout = ftty;
}
struct termios oldTerm;
if(tcgetattr(fin, &oldTerm) == -1)
return "tcgetattr(STDIN_FILENO, &oldTerm) failed";
newTerm = oldTerm;
struct termios newTerm = oldTerm;
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1)
return "tcsetattr(STDIN_FILENO, TCSANOW, &newTerm)";
if(tcsetattr(fin, TCSAFLUSH, &newTerm) == -1)
return "tcsetattr(STDIN_FILENO, TCSAFLUSH, &newTerm)";
fputs(request, stdout);
fflush(stdout);
ffWriteFDData(fout, strlen(request), request);
//Give the terminal 35ms to respond
if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
//Give the terminal some time to respond
if(poll(&(struct pollfd) { .fd = fin, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
{
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
tcsetattr(fin, TCSANOW, &oldTerm);
return "poll() timeout or failed";
}
char buffer[512];
ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
ssize_t bytesRead = read(fin, buffer, sizeof(buffer) - 1);
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
tcsetattr(fin, TCSANOW, &oldTerm);
if(bytesRead <= 0)
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
+57 -12
View File
@@ -114,8 +114,40 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out)
bool ffSuppressIO(bool suppress)
{
(void) suppress; //Not implemented.
return false;
static bool init = false;
static HANDLE hOrigOut = INVALID_HANDLE_VALUE;
static HANDLE hOrigErr = INVALID_HANDLE_VALUE;
static HANDLE hNullFile = INVALID_HANDLE_VALUE;
static int fOrigOut = -1;
static int fOrigErr = -1;
static int fNullFile = -1;
if (!init)
{
if(!suppress)
return true;
hOrigOut = GetStdHandle(STD_OUTPUT_HANDLE);
hOrigErr = GetStdHandle(STD_ERROR_HANDLE);
hNullFile = CreateFileW(L"NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
fOrigOut = _dup(STDOUT_FILENO);
fOrigErr = _dup(STDERR_FILENO);
fNullFile = _open_osfhandle((intptr_t) hNullFile, 0);
init = true;
}
if (hNullFile == INVALID_HANDLE_VALUE || fNullFile == -1)
return false;
fflush(stdout);
fflush(stderr);
SetStdHandle(STD_OUTPUT_HANDLE, suppress ? hNullFile : hOrigOut);
SetStdHandle(STD_ERROR_HANDLE, suppress ? hNullFile : hOrigErr);
_dup2(suppress ? fNullFile : fOrigOut, STDOUT_FILENO);
_dup2(suppress ? fNullFile : fOrigErr, STDERR_FILENO);
return true;
}
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
@@ -175,24 +207,37 @@ void ffListFilesRecursively(const char* path, bool pretty)
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
{
if (instance.config.display.pipe)
return "Not supported in --pipe mode";
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
DWORD prev_mode;
GetConsoleMode(hInput, &prev_mode);
FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE;
DWORD inputMode;
if (!GetConsoleMode(hInput, &inputMode))
{
hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL);
hInput = hConin;
}
SetConsoleMode(hInput, 0);
FlushConsoleInputBuffer(hInput);
DWORD bytes = 0;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), request, (DWORD) strlen(request), &bytes, NULL);
{
DWORD bytes = 0;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
DWORD outputMode;
if (!GetConsoleMode(hOutput, &outputMode))
{
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
hOutput = hConout;
}
WriteFile(hOutput, "TEST\n", 5, &bytes, NULL);
WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, NULL);
}
while (true)
{
if (WaitForSingleObjectEx(hInput, FF_IO_TERM_RESP_WAIT_MS, TRUE) != WAIT_OBJECT_0)
{
SetConsoleMode(hInput, prev_mode);
SetConsoleMode(hInput, inputMode);
return "WaitForSingleObject() failed or timeout";
}
@@ -213,10 +258,10 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
}
char buffer[512];
bytes = 0;
DWORD bytes = 0;
ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL);
SetConsoleMode(hInput, prev_mode);
SetConsoleMode(hInput, inputMode);
if(bytes <= 0)
return "ReadFile() failed";
+1 -1
View File
@@ -5,7 +5,7 @@
typedef enum FFPrintType {
FF_PRINT_TYPE_DEFAULT = 0,
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0,
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0, // key has been formatted outside
FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1,
FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH = 1 << 2,
FF_PRINT_TYPE_NO_CUSTOM_OUTPUT_FORMAT = 1 << 3, // reserved
+10 -6
View File
@@ -257,12 +257,15 @@
}
},
{
"long": "logo-separate",
"desc": "If true, print modules at bottom of the logo",
"long": "logo-position",
"desc": "Set the position of the logo should be displayed",
"arg": {
"type": "bool",
"optional": true,
"default": false
"type": "enum",
"enum": {
"left": "Left",
"top": "Top",
"right": "Right"
}
}
},
{
@@ -1251,7 +1254,8 @@
"enum": {
"auto": "Query platform specific graphic APIs. Requires proper GPU drivers installed. Not supported on FreeBSD",
"pci": "Search PCI devices, which do not requires GPU driver installed. Not supported on Windows and macOS",
"vulkan": "Use Vulkan API. Slow and requires vulkan driver installed. Used for Android",
"vulkan": "Use Vulkan API. Slow and requires proper vulkan driver installed. Used for Android",
"opencl": "Use OpenCL API. Slow and requires proper OpenCL driver installed",
"opengl": "Use OpenGL API. Slow and only detects one GPU"
},
"default": "auto"
+5
View File
@@ -8,6 +8,11 @@ In 2.14.0 or newer, the value indices can be meaningful named tags.
For example: "--title-format '{user-name-colored}{at-symbol-colored}{host-name-colored}'" is equivalent to "--title-format '{6}{7}{8}'"
See "fastfetch -h title-format" for all supported tags.
In 2.17.0 or newer, a truncation length can be specified using syntax '<arg>:<trunc-length>`
For example: "--title-format '{user-name:5}'" will truncate user name into 5-length string.
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
+1 -1
View File
@@ -172,7 +172,7 @@ typedef struct FFSmbiosPortableBattery
static_assert(offsetof(FFSmbiosPortableBattery, OEMSpecific) == 0x16,
"FFSmbiosPortableBattery: Wrong struct alignment");
const char* detectBySmbios(FFBatteryResult* battery)
static const char* detectBySmbios(FFBatteryResult* battery)
{
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
+75
View File
@@ -0,0 +1,75 @@
#include "cpucache.h"
#include "util/smbiosHelper.h"
#include "util/stringUtils.h"
typedef struct FFSmbiosCacheInfo
{
FFSmbiosHeader Header;
uint8_t SocketDesignation; // string
uint16_t CacheConfiguration; // varies
uint16_t MaximumCacheSize; // varies
uint16_t InstalledSize; // varies
uint16_t SupportedSramType; // bit field
uint16_t CurrentSramType; // bit field
// 2.1+
uint8_t CacheSpeed; // varies
uint8_t ErrorCorrectionType; // enum
uint8_t SystemCacheType; // enum
uint8_t Associativity; // enum
// 3.1+
uint32_t MaximumCacheSize2; // bit field
uint32_t InstalledCacheSize2; // bit field
} __attribute__((__packed__)) FFSmbiosCacheInfo;
static_assert(offsetof(FFSmbiosCacheInfo, InstalledCacheSize2) == 0x17,
"FFSmbiosCacheInfo: Wrong struct alignment");
const char* ffDetectCPUCache(FFCPUCacheResult* result)
{
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
if (!smbiosTable)
return "Failed to get SMBIOS data";
const FFSmbiosCacheInfo* data = (const FFSmbiosCacheInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_CACHE_INFO];
if (!data)
return "Cache information is not found in SMBIOS data";
for (; data->Header.Type == FF_SMBIOS_TYPE_CACHE_INFO;
data = (const FFSmbiosCacheInfo*) ffSmbiosNextEntry(&data->Header))
{
bool enabled = !!(data->CacheConfiguration & (1 << 7));
if (!enabled)
continue;
uint32_t size = data->InstalledSize;
if (size == 0)
continue;
if (data->InstalledSize != 0xFFFF)
{
size *= (size >> 15 ? 64 : 1) * 1024u;
}
else if (data->Header.Length > offsetof(FFSmbiosCacheInfo, InstalledCacheSize2))
{
size = data->InstalledCacheSize2;
size *= (size >> 31 ? 64 : 1) * 1024u;
}
uint32_t level = (data->CacheConfiguration & 0b111u) + 1;
FFCPUCacheType type;
switch (data->SystemCacheType)
{
case 3: type = FF_CPU_CACHE_TYPE_INSTRUCTION; break;
case 4: type = FF_CPU_CACHE_TYPE_DATA; break;
default: type = FF_CPU_CACHE_TYPE_UNIFIED; break;
}
ffCPUCacheAddItem(result, level, size, 0, type);
}
return NULL;
}
+11
View File
@@ -1,5 +1,6 @@
#include "gpu.h"
#include "detection/vulkan/vulkan.h"
#include "detection/opencl/opencl.h"
#include "detection/opengl/opengl.h"
const char* FF_GPU_VENDOR_NAME_APPLE = "Apple";
@@ -94,6 +95,16 @@ const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result)
return NULL;
}
}
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENCL)
{
FFOpenCLResult* opencl = ffDetectOpenCL();
if (!opencl->error && opencl->gpus.length > 0)
{
ffListDestroy(result);
ffListInitMove(result, &opencl->gpus);
return NULL;
}
}
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENGL)
{
if (detectByOpenGL(result) == NULL)
+4 -2
View File
@@ -19,13 +19,12 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
inited = true;
FF_LIBRARY_LOAD(libags, NULL, "dlopen amd_ags failed", soName , 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsInitialize)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsDeInitialize)
struct AGSContext* apiHandle;
if (ffagsInitialize(AGS_CURRENT_VERSION, NULL, &apiHandle, &gpuInfo) != AGS_SUCCESS)
return "loading ags library failed";
ffagsDeInitialize(apiHandle);
// agsDeInitialize will free pointers allocated in gpuInfo. Just leak them.
}
if (gpuInfo.numDevices == 0)
@@ -63,5 +62,8 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
if (result.frequency)
*result.frequency = device->coreClock / 1000.; // Maximum frequency
if (result.type)
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
return NULL;
}
-2
View File
@@ -76,7 +76,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
ffGPUParsePciIds(&pciids, pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
}
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific))
{
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
@@ -98,7 +97,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
gpu->type = gpu->dedicated.total > (uint64_t)1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
}
return NULL;
+1 -6
View File
@@ -2,14 +2,11 @@
#include "detection/vulkan/vulkan.h"
#include "detection/temps/temps_linux.h"
#include "detection/cpu/cpu.h"
#include "detection/gpu/gpu_driver_specific.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "util/stringUtils.h"
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
#include "detection/gpu/gpu_driver_specific.h"
#endif
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
@@ -261,7 +258,6 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
{
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
if (options->temp || options->driverSpecific)
{
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
@@ -280,7 +276,6 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
.frequency = &gpu->frequency,
}, "libnvidia-ml.so");
}
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
{
+6 -6
View File
@@ -17,12 +17,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
if (error)
return error;
if (!ffStrbufStartsWithS(&buffer, "\npci domain 0x"))
if (!ffStrbufStartsWithS(&buffer, "\npci "))
return "Invalid scanpci result";
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
// pci domain 0x354b bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
// Device unknown
// CardVendor 0x0000 card 0x0000 (Card unknown)
// STATUS 0x0010 COMMAND 0x0007
@@ -42,9 +42,9 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
pstart = memrchr(buffer.chars, '\n', (size_t) (pstart - buffer.chars - 1));
++pstart;
uint32_t pciDomain, pciBus, pciDev, pciFunc, vendorId, deviceId;
if (sscanf(pstart, "pci domain %x bus %x cardnum %x function %x: vendor %x device %x",
&pciDomain, &pciBus, &pciDev, &pciFunc, &vendorId, &deviceId) != 6)
uint32_t vendorId, deviceId;
if (sscanf(pstart, "pci %*[^:]: vendor %x device %x",
&vendorId, &deviceId) != 2)
return "PCI info not found, invalid scanpci result";
pclass += strlen("\n CLASS 0x03 ");
@@ -61,7 +61,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
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;
gpu->deviceId = ((uint64_t) pciDomain << 6) | ((uint64_t) pciBus << 4) | (pciDev << 2) | pciFunc;
gpu->deviceId = 0;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
+2 -9
View File
@@ -1,11 +1,8 @@
#include "gpu.h"
#include "detection/gpu/gpu_driver_specific.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
#include "detection/gpu/gpu_driver_specific.h"
#endif
#include <inttypes.h>
static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
@@ -13,7 +10,6 @@ static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
return ffStrbufEqual(&gpu->name, name);
}
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&ffDetectNvidiaGpuInfo)* pDetectFn, const char** pDllName)
{
if (vendor == FF_GPU_VENDOR_NAME_NVIDIA)
@@ -48,7 +44,6 @@ static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&
return true;
}
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
{
@@ -144,13 +139,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
}
}
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
__typeof__(&ffDetectNvidiaGpuInfo) detectFn;
const char* dllName;
if (getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName) && (options->temp || options->driverSpecific))
{
if (vendorId && deviceId && subSystemId && revId)
if (vendorId && deviceId && subSystemId)
{
detectFn(
&(FFGpuDriverCondition) {
@@ -174,7 +168,6 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
);
}
}
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
}
return NULL;
-2
View File
@@ -104,7 +104,6 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
ffStrbufSetStatic(&gpu->vendor, vendorStr);
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA && (options->driverSpecific || options->temp))
{
FFGpuDriverCondition cond = {
@@ -124,7 +123,6 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
.frequency = &gpu->frequency,
}, "/usr/lib/wsl/lib/libnvidia-ml.so");
}
#endif
}
}
+2 -1
View File
@@ -52,7 +52,8 @@ typedef struct {
// Allocated device memory (in bytes)
unsigned long long used;
} nvmlMemory_v2_t;
enum { nvmlMemory_v2 = 2 };
// https://github.com/NVIDIA/nvidia-settings/issues/78#issuecomment-1012837988
enum { nvmlMemory_v2 = (unsigned int)(sizeof(nvmlMemory_v2_t) | (2 << 24U)) };
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64
// Clock types
+32
View File
@@ -135,6 +135,29 @@ static void detectLXQt(FFQtResult* result)
ffParsePropFileConfig("pcmanfm-qt/lxqt/settings.conf", "Wallpaper=", &result->wallpaper);
}
static void detectQtCt(char qver, FFQtResult* result)
{
// qt5ct and qt6ct are technically separate applications, but they're both
// by the same author and qt6ct understands qt5ct in qt6 applications as well.
char file[] = "qtXct/qtXct.conf";
file[2] = file[8] = qver;
ffParsePropFileConfigValues(file, 3, (FFpropquery[]) {
{"style=", &result->widgetStyle},
{"icon_theme=", &result->icons},
// FIXME: on older versions this was hex-encoded binary format
// (See QVariant notes on https://doc.qt.io/qt-5/qsettings.html)
// Thankfully, newer versions use the more common font encoding.
{"general=", &result->font}
});
}
static void detectKvantum(FFQtResult* result)
{
ffParsePropFileConfigValues("Kvantum/kvantum.kvconfig", 1, (FFpropquery[]) {
{"theme=", &result->widgetStyle},
});
}
const FFQtResult* ffDetectQt(void)
{
static FFQtResult result;
@@ -151,11 +174,20 @@ const FFQtResult* ffDetectQt(void)
ffStrbufInit(&result.wallpaper);
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
const char *qplatformtheme = getenv("QT_QPA_PLATFORMTHEME");
if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA))
detectPlasma(&result);
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT))
detectLXQt(&result);
else if(ffStrSet(qplatformtheme) && (ffStrEquals(qplatformtheme, "qt5ct") || ffStrEquals(qplatformtheme, "qt6ct")))
detectQtCt(qplatformtheme[2], &result);
if(ffStrbufEqualS(&result.widgetStyle, "kvantum") || ffStrbufEqualS(&result.widgetStyle, "kvantum-dark"))
{
ffStrbufClear(&result.widgetStyle);
detectKvantum(&result);
}
return &result;
}
+4 -5
View File
@@ -6,7 +6,7 @@
#include <unistd.h>
#define FF_SYSTEMD_SESSIONS_PATH "/var/run/systemd/sessions/"
#define FF_SYSTEMD_SESSIONS_PATH "/run/systemd/sessions/"
#define FF_SYSTEMD_USERS_PATH "/run/systemd/users/"
static const char* getGdmVersion(FFstrbuf* version)
@@ -143,7 +143,7 @@ const char* ffDetectLM(FFLMResult* result)
{
// On some incorrectly configured systems, $XDG_SESSION_ID is not set. Try finding it ourself
// WARNING: This is private data. Do not parse
ffStrbufAppendF(&path, "/run/systemd/users/%d", getuid());
ffStrbufSetF(&path, FF_SYSTEMD_USERS_PATH "%d", getuid());
// This is actually buggy, and assumes current user is using DE
// `sd_pid_get_session` can be a better option, but we need to find a pid to use
@@ -151,10 +151,9 @@ const char* ffDetectLM(FFLMResult* result)
{"DISPLAY=", &sessionId},
}))
return "Failed to get $XDG_SESSION_ID";
ffStrbufClear(&path);
}
ffStrbufAppendS(&path, "/var/run/systemd/sessions/");
ffStrbufSetS(&path, FF_SYSTEMD_SESSIONS_PATH);
ffStrbufAppend(&path, &sessionId);
// WARNING: This is private data. Do not parse
@@ -162,7 +161,7 @@ const char* ffDetectLM(FFLMResult* result)
{"SERVICE=", &result->service},
{"TYPE=", &result->type},
}))
return "Failed to parse /run/systemd/sessions/$XDG_SESSION_ID";
return "Failed to parse " FF_SYSTEMD_SESSIONS_PATH "$XDG_SESSION_ID";
if (ffStrbufStartsWithS(&result->service, "gdm"))
getGdmVersion(&result->version);
+137 -50
View File
@@ -1,21 +1,19 @@
#include "detection/opencl/opencl.h"
#include "detection/gpu/gpu.h"
#ifdef __APPLE__
#include <AvailabilityMacros.h>
#if (MAC_OS_X_VERSION_MIN_REQUIRED > 1050) && !defined(__ppc__)
#define MACOS_HAS_OPENCL
#endif
#if !defined(FF_HAVE_OPENCL) && defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_15)
#define FF_HAVE_OPENCL 1
#endif
#if defined(FF_HAVE_OPENCL) || defined(MACOS_HAS_OPENCL)
#ifdef FF_HAVE_OPENCL
#include "common/library.h"
#include "common/parsing.h"
#include "util/stringUtils.h"
#include <string.h>
#define CL_TARGET_OPENCL_VERSION 100
#ifdef FF_HAVE_OPENCL
#define CL_TARGET_OPENCL_VERSION 110
#ifndef __APPLE__
#include <CL/cl.h>
#else
#include <OpenCL/cl.h>
@@ -24,86 +22,175 @@
typedef struct OpenCLData
{
FF_LIBRARY_SYMBOL(clGetPlatformIDs)
FF_LIBRARY_SYMBOL(clGetDeviceIDs)
FF_LIBRARY_SYMBOL(clGetPlatformInfo)
FF_LIBRARY_SYMBOL(clGetDeviceInfo)
FF_LIBRARY_SYMBOL(clGetDeviceIDs)
} OpenCLData;
static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
{
cl_platform_id platformID = NULL;
cl_platform_id platforms[32];
cl_uint numPlatforms = 0;
data->ffclGetPlatformIDs(1, &platformID, &numPlatforms);
if (data->ffclGetPlatformIDs(sizeof(platforms) / sizeof(platforms[0]), platforms, &numPlatforms) != CL_SUCCESS)
return "clGetPlatformIDs() failed";
if(numPlatforms == 0)
if (numPlatforms == 0)
return "clGetPlatformIDs returned 0 platforms";
cl_device_id deviceID = NULL;
cl_uint numDevices = 0;
data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_GPU, 1, &deviceID, &numDevices);
char buffer[1024];
for (cl_uint iplat = 0; iplat < numPlatforms; ++iplat)
{
if (data->ffclGetPlatformInfo(platforms[iplat], CL_PLATFORM_VERSION, sizeof(buffer), buffer, NULL) != CL_SUCCESS)
return "clGetPlatformInfo() failed";
if(numDevices == 0)
data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_ALL, 1, &deviceID, &numDevices);
// Use the newest supported OpenCL version
if (ffStrbufCompS(&result->version, buffer) < 0)
{
const char* versionPretty = buffer;
if(ffStrStartsWithIgnCase(buffer, "OpenCL "))
versionPretty = buffer + strlen("OpenCL ");
ffStrbufSetS(&result->version, versionPretty);
ffStrbufTrim(&result->version, ' ');
if(numDevices == 0)
return "clGetDeviceIDs returned 0 devices";
if (data->ffclGetPlatformInfo(platforms[iplat], CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
ffStrbufSetS(&result->name, buffer);
char version[64] = "";
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(version), version, NULL);
if(!ffStrSet(version))
return "clGetDeviceInfo returned NULL or empty string";
if (data->ffclGetPlatformInfo(platforms[iplat], CL_PLATFORM_VENDOR, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
ffStrbufSetS(&result->vendor, buffer);
}
const char* versionPretty = version;
if(ffStrStartsWithIgnCase(version, "OpenCL "))
versionPretty = version + strlen("OpenCL ");
ffStrbufSetS(&result->version, versionPretty);
ffStrbufTrim(&result->version, ' ');
cl_device_id deviceIDs[32];
cl_uint numDevices = (cl_uint) (sizeof(deviceIDs) / sizeof(deviceIDs[0]));
if (data->ffclGetDeviceIDs(platforms[iplat], CL_DEVICE_TYPE_GPU, numDevices, deviceIDs, &numDevices) != CL_SUCCESS)
continue;
ffStrbufEnsureFree(&result->device, 128);
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_NAME, result->device.allocated, result->device.chars, NULL);
ffStrbufRecalculateLength(&result->device);
ffStrbufTrim(&result->device, ' ');
for (cl_uint idev = 0; idev < numDevices; ++idev)
{
cl_device_id deviceID = deviceIDs[idev];
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_NAME, sizeof(buffer), buffer, NULL) != CL_SUCCESS)
continue;
ffStrbufEnsureFree(&result->vendor, 32);
data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR, result->vendor.allocated, result->vendor.chars, NULL);
ffStrbufRecalculateLength(&result->vendor);
ffStrbufTrim(&result->vendor, ' ');
FFGPUResult* gpu = ffListAdd(&result->gpus);
ffStrbufInitS(&gpu->name, buffer);
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->deviceId = (size_t) deviceID;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
{
ffStrbufSetS(&gpu->platformApi, buffer);
ffStrbufTrimRight(&gpu->platformApi, ' ');
}
else
ffStrbufSetStatic(&gpu->platformApi, "OpenCL");
{
cl_uint vendorId;
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR_ID, sizeof(vendorId), &vendorId, NULL) == CL_SUCCESS)
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
if (gpu->vendor.length == 0 && data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
ffStrbufSetS(&gpu->vendor, buffer);
}
if (data->ffclGetDeviceInfo(deviceID, CL_DRIVER_VERSION, sizeof(buffer), buffer, NULL) == CL_SUCCESS)
{
const char* versionPretty = strchr(buffer, ' ');
if (versionPretty && *versionPretty)
ffStrbufSetS(&gpu->driver, versionPretty + 1);
else
ffStrbufSetS(&gpu->driver, buffer);
}
{
cl_uint value;
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(value), &value, NULL) == CL_SUCCESS)
gpu->coreCount = (int32_t) value;
}
{
cl_uint value;
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(value), &value, NULL) == CL_SUCCESS)
gpu->frequency = value / 1000.;
}
{
cl_bool value;
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof(value), &value, NULL) == CL_SUCCESS)
{
gpu->type = value ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
cl_ulong memSize;
if (data->ffclGetDeviceInfo(deviceID, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(memSize), &memSize, NULL) == CL_SUCCESS)
{
if (gpu->type == FF_GPU_TYPE_INTEGRATED)
gpu->shared.total = memSize;
else
gpu->dedicated.total = memSize;
}
}
}
}
}
return NULL;
}
#endif // defined(FF_HAVE_OPENCL) || defined(MACOS_HAS_OPENCL)
const char* ffDetectOpenCL(FFOpenCLResult* result)
static const char* detectOpenCL(FFOpenCLResult* result)
{
#ifdef FF_HAVE_OPENCL
OpenCLData data;
FF_LIBRARY_LOAD(opencl, &instance.config.library.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed",
#ifndef __APPLE__
FF_LIBRARY_LOAD(opencl, &instance.config.library.libOpenCL, "dlopen libOpenCL" FF_LIBRARY_EXTENSION" failed",
#ifdef _WIN32
"OpenCL"FF_LIBRARY_EXTENSION, -1,
#endif
"libOpenCL"FF_LIBRARY_EXTENSION, 1
);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetPlatformIDs);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetPlatformInfo);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceIDs);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opencl, data, clGetDeviceInfo);
return openCLHandleData(&data, result);
#elif defined(MACOS_HAS_OPENCL) // FF_HAVE_OPENCL
#else
OpenCLData data;
data.ffclGetPlatformIDs = clGetPlatformIDs;
data.ffclGetPlatformInfo = clGetPlatformInfo;
data.ffclGetDeviceIDs = clGetDeviceIDs;
data.ffclGetDeviceInfo = clGetDeviceInfo;
return openCLHandleData(&data, result);
#else
FF_UNUSED(result);
return "Fastfetch was build without OpenCL support";
#endif // FF_HAVE_OPENCL
#endif
}
#endif // defined(FF_HAVE_OPENCL)
FFOpenCLResult* ffDetectOpenCL(void)
{
static FFOpenCLResult result;
if (result.gpus.elementSize == 0)
{
ffStrbufInit(&result.version);
ffStrbufInit(&result.name);
ffStrbufInit(&result.vendor);
ffListInit(&result.gpus, sizeof(FFGPUResult));
#ifdef FF_HAVE_OPENCL
result.error = detectOpenCL(&result);
#else
result.error = "fastfetch was compiled without OpenCL support";
#endif
}
return &result;
}
+4 -2
View File
@@ -5,8 +5,10 @@
typedef struct FFOpenCLResult
{
FFstrbuf version;
FFstrbuf device;
FFstrbuf name;
FFstrbuf vendor;
FFlist gpus; //List of FFGPUResult, see detection/gpu/gpu.h
const char* error;
} FFOpenCLResult;
const char* ffDetectOpenCL(FFOpenCLResult* result);
FFOpenCLResult* ffDetectOpenCL();
+14 -13
View File
@@ -54,18 +54,18 @@ static bool detectOSCodeName(FFOSResult* os)
case 14: ffStrbufSetStatic(&os->codename, "Mojave"); return true;
case 13: ffStrbufSetStatic(&os->codename, "High Sierra"); return true;
case 12: ffStrbufSetStatic(&os->codename, "Sierra"); return true;
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); return true;
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); return true;
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); return true;
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); return true;
case 7: ffStrbufSetStatic(&os->codename, "Lion"); return true;
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); return true;
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); return true;
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); return true;
case 3: ffStrbufSetStatic(&os->codename, "Panther"); return true;
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); return true;
case 1: ffStrbufSetStatic(&os->codename, "Puma"); return true;
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); return true;
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); ffStrbufSetStatic(&os->prettyName, "OS X"); return true;
case 7: ffStrbufSetStatic(&os->codename, "Lion"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
case 3: ffStrbufSetStatic(&os->codename, "Panther"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
case 1: ffStrbufSetStatic(&os->codename, "Puma"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); ffStrbufSetStatic(&os->prettyName, "Mac OS X"); return true;
}
}
}
@@ -106,7 +106,8 @@ void ffDetectOSImpl(FFOSResult* os)
if(os->buildID.length == 0)
ffSysctlGetString("kern.osversion", &os->buildID);
ffStrbufAppend(&os->prettyName, &os->name);
if(os->prettyName.length == 0)
ffStrbufSetStatic(&os->prettyName, "macOS");
ffStrbufAppend(&os->versionID, &os->version);
if(!detectOSCodeName(os))
+48 -23
View File
@@ -1,4 +1,5 @@
#include "terminalfont.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "common/processing.h"
#include "detection/terminalshell/terminalshell.h"
@@ -256,42 +257,66 @@ static void detectFromWindowsTerminal(const FFstrbuf* terminalExe, FFTerminalFon
}
}
#endif //defined(_WIN32) || defined(__linux__)
static bool queryKittyTerm(const char* query, FFstrbuf* res)
{
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
char buffer[64] = "";
if (ffGetTerminalResponse(
query, // kitty-query-font_family;kitty-query-font_size
"\eP1+r%*[^=]=%64[^\e]\e\\", buffer) == NULL && *buffer)
{
// decode hex string
for (const char* p = buffer; p[0] && p[1]; p += 2)
{
unsigned value;
if (sscanf(p, "%2x", &value) == 1)
ffStrbufAppendC(res, (char) value);
}
return true;
}
return false;
}
FF_MAYBE_UNUSED static bool detectKitty(const FFstrbuf* exe, FFTerminalFontResult* result)
{
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
if(!ffProcessAppendStdOut(&buf, (char* const[]){
exe->chars,
"+kitten",
"query-terminal",
NULL,
}))
{
ffParsePropLines(buf.chars, "font_family: ", &fontName);
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
}
// Kitty generates response independently even if we query font family and size in one query
// which may result in short read in `ffGetTerminalResponse`
if (queryKittyTerm("\eP+q6b697474792d71756572792d666f6e745f66616d696c79\e\\", &fontName)) // kitty-query-font_family
queryKittyTerm("\eP+q6b697474792d71756572792d666f6e745f73697a65\e\\", &fontSize); // kitty-query-font_size
else
{
FFpropquery fontQuery[] = {
{"font_family ", &fontName},
{"font_size ", &fontSize},
};
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
if(!ffProcessAppendStdOut(&buf, (char* const[]){
exe->chars,
"+kitten",
"query-terminal",
NULL,
}))
{
ffParsePropLines(buf.chars, "font_family: ", &fontName);
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
}
else
{
FFpropquery fontQuery[] = {
{"font_family ", &fontName},
{"font_size ", &fontSize},
};
ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery);
ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery);
if(fontName.length == 0)
ffStrbufSetS(&fontName, "monospace");
if(fontSize.length == 0)
ffStrbufSetS(&fontSize, "11.0");
if(fontName.length == 0)
ffStrbufSetS(&fontName, "monospace");
if(fontSize.length == 0)
ffStrbufSetS(&fontSize, "11.0");
}
}
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
return true;
+11 -23
View File
@@ -480,33 +480,21 @@ static bool getTerminalVersionZellij(FFstrbuf* exe, FFstrbuf* version)
#ifndef _WIN32
static bool getTerminalVersionKitty(FFstrbuf* exe, FFstrbuf* version)
{
#if defined(__linux__) || defined(__FreeBSD__)
// kitty is written in python. `kitty --version` can be expensive
char buffer[1024] = {};
if (
#ifdef __linux__
ffReadFileData(FASTFETCH_TARGET_DIR_USR "/lib64/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer) ||
ffReadFileData(FASTFETCH_TARGET_DIR_USR "/lib/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer)
#else
ffReadFileData(_PATH_LOCALBASE "/share/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer)
#endif
)
char versionHex[64] = "";
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
if (ffGetTerminalResponse(
"\eP+q6b697474792d71756572792d76657273696f6e\e\\", // kitty-query-version
"\eP1+r%*[^=]=%64[^\e]\e\\\\", versionHex) == NULL && *versionHex)
{
// Starts from version 0.17.0
// https://github.com/kovidgoyal/kitty/blob/master/kitty/constants.py#L25
const char* p = memmem(buffer, sizeof(buffer) - 1, "version: Version = Version(", strlen("version: Version = Version("));
if (p)
// decode hex string
for (const char* p = versionHex; p[0] && p[1]; p += 2)
{
p += strlen("version: Version = Version(");
int major, minor, patch;
if (sscanf(p, "%d,%d,%d", &major, &minor, &patch) == 3)
{
ffStrbufSetF(version, "%d.%d.%d", major, minor, patch);
return true;
}
unsigned value;
if (sscanf(p, "%2x", &value) == 1)
ffStrbufAppendC(version, (char) value);
}
return true;
}
#endif
//kitty 0.21.2 created by Kovid Goyal
return getExeVersionGeneral(exe, version);
@@ -5,9 +5,19 @@
bool ffDetectTerminalSize(FFTerminalSizeResult* result)
{
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
{
DWORD outputMode;
if (!GetConsoleMode(hOutput, &outputMode))
{
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
hOutput = hConout;
}
}
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
if (GetConsoleScreenBufferInfo(hOutput, &csbi))
{
result->columns = (uint16_t) (csbi.srWindow.Right - csbi.srWindow.Left + 1);
result->rows = (uint16_t) (csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
@@ -23,7 +33,7 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result)
{
CONSOLE_FONT_INFO cfi;
if(GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi)) // Only works for ConHost
if(GetCurrentConsoleFont(hOutput, FALSE, &cfi)) // Only works for ConHost
{
result->width = result->columns * (uint16_t) cfi.dwFontSize.X;
result->height = result->rows * (uint16_t) cfi.dwFontSize.Y;
+2 -2
View File
@@ -1,4 +1,4 @@
$1 ## $2**
## $2**
$1*####$2****.
$1###$2,
$3...,$1/#$3,,,..
@@ -15,4 +15,4 @@ $3((((((((((((((((((((($5@@@$6&%&$5@@@%$4,..........
$3/(((((((((((($5@@@@@@/$4.../&&
$3.((((((((($5@@@@($4....
$3/((((($5@@#$4...
$3.(($4&,
$3.(($4&,
+2 -2
View File
@@ -484,7 +484,7 @@ static const FFlogo A[] = {
FF_COLOR_FG_YELLOW,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_RED,
"38", //cyan
FF_COLOR_FG_LIGHT_BLACK,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_CYAN,
FF_COLOR_FG_BLUE,
@@ -1520,7 +1520,7 @@ static const FFlogo F[] = {
FF_COLOR_FG_YELLOW,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_RED,
"38", //cyan
FF_COLOR_FG_LIGHT_BLACK,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_CYAN,
FF_COLOR_FG_BLUE,
+101 -31
View File
@@ -10,6 +10,8 @@
#include <sys/syslimits.h>
#elif _WIN32
#include <windows.h>
#elif __linux__
#include <sys/sendfile.h>
#endif
// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145
@@ -72,25 +74,31 @@ static bool printImageIterm(bool printError)
if (!options->width || !options->height)
{
if (!options->separate)
if (options->position == FF_LOGO_POSITION_LEFT)
{
ffStrbufAppendF(&buf, "\e[2J\e[3J\e[%u;%uH",
(unsigned) options->paddingTop,
(unsigned) options->paddingLeft
);
}
else
else if (options->position == FF_LOGO_POSITION_TOP)
{
ffStrbufAppendNC(&buf, options->paddingTop, '\n');
ffStrbufAppendNC(&buf, options->paddingLeft, ' ');
}
else if (options->position == FF_LOGO_POSITION_RIGHT)
{
if (printError)
fputs("Logo (iterm): Must set logo width and height\n", stderr);
return false;
}
if (options->width)
ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u:%s\a", (unsigned) options->width, base64.chars);
else
ffStrbufAppendF(&buf, "\e]1337;File=inline=1:%s\a", base64.chars);
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf);
if (!options->separate)
if (options->position == FF_LOGO_POSITION_LEFT)
{
uint16_t X = 0, Y = 0;
const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X);
@@ -103,7 +111,7 @@ static bool printImageIterm(bool printError)
instance.state.logoHeight = Y;
fputs("\e[H", stdout);
}
else
else if (options->position == FF_LOGO_POSITION_TOP)
{
instance.state.logoWidth = instance.state.logoHeight = 0;
ffPrintCharTimes('\n', options->paddingRight);
@@ -112,7 +120,10 @@ static bool printImageIterm(bool printError)
else
{
ffStrbufAppendNC(&buf, options->paddingTop, '\n');
ffStrbufAppendNC(&buf, options->paddingLeft, ' ');
if (options->position == FF_LOGO_POSITION_RIGHT)
ffStrbufAppendF(&buf, "\e[9999999C\e[%uD", (unsigned) options->paddingRight + options->width);
else
ffStrbufAppendF(&buf, "\e[%uC", (unsigned) options->paddingLeft);
ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\n",
(unsigned) options->width,
(unsigned) options->height,
@@ -120,17 +131,22 @@ static bool printImageIterm(bool printError)
base64.chars
);
if (!options->separate)
if (options->position == FF_LOGO_POSITION_LEFT)
{
instance.state.logoWidth = options->width + options->paddingLeft + options->paddingRight;
instance.state.logoHeight = options->paddingTop + options->height;
ffStrbufAppendF(&buf, "\e[%uA", (unsigned) instance.state.logoHeight);
}
else
else if (options->position == FF_LOGO_POSITION_TOP)
{
instance.state.logoWidth = instance.state.logoHeight = 0;
ffStrbufAppendNC(&buf, options->paddingRight, '\n');
}
else if (options->position == FF_LOGO_POSITION_RIGHT)
{
instance.state.logoWidth = instance.state.logoHeight = 0;
ffStrbufAppendF(&buf, "\e[1G\e[%uA", (unsigned) options->height);
}
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf);
}
@@ -152,7 +168,7 @@ static bool printImageKittyDirect(bool printError)
if (!options->width || !options->height)
{
if (!options->separate)
if (options->position == FF_LOGO_POSITION_LEFT)
{
// We must clear the entre screen to make sure that terminal buffer won't scroll up
printf("\e[2J\e[3J\e[%u;%uH",
@@ -160,18 +176,24 @@ static bool printImageKittyDirect(bool printError)
(unsigned) options->paddingLeft
);
}
else
else if (options->position == FF_LOGO_POSITION_TOP)
{
ffPrintCharTimes('\n', options->paddingTop);
ffPrintCharTimes(' ', options->paddingLeft);
}
else if (options->position == FF_LOGO_POSITION_RIGHT)
{
if (printError)
fputs("Logo (iterm): Must set logo width and height\n", stderr);
return false;
}
if (options->width)
printf("\e_Ga=T,f=100,t=f,c=%u;%s\e\\", (unsigned) options->width, base64.chars);
else
printf("\e_Ga=T,f=100,t=f;%s\e\\", base64.chars);
fflush(stdout);
if (!options->separate)
if (options->position == FF_LOGO_POSITION_LEFT)
{
uint16_t X = 0, Y = 0;
const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X);
@@ -184,7 +206,7 @@ static bool printImageKittyDirect(bool printError)
instance.state.logoHeight = Y;
fputs("\e[H", stdout);
}
else
else if (options->position == FF_LOGO_POSITION_TOP)
{
instance.state.logoWidth = instance.state.logoHeight = 0;
ffPrintCharTimes('\n', options->paddingRight);
@@ -193,24 +215,32 @@ static bool printImageKittyDirect(bool printError)
else
{
ffPrintCharTimes('\n', options->paddingTop);
ffPrintCharTimes(' ', options->paddingLeft);
if (options->position == FF_LOGO_POSITION_RIGHT)
printf("\e[9999999C\e[%uD", (unsigned) options->paddingRight + options->width);
else
printf("\e[%uC", (unsigned) options->paddingLeft);
printf("\e_Ga=T,f=100,t=f,c=%u,r=%u;%s\e\\\n",
(unsigned) options->width,
(unsigned) options->height,
base64.chars
);
if (!options->separate)
if (options->position == FF_LOGO_POSITION_LEFT)
{
instance.state.logoWidth = options->width + options->paddingLeft + options->paddingRight;
instance.state.logoHeight = options->paddingTop + options->height;
printf("\e[%uA", (unsigned) instance.state.logoHeight);
}
else
else if (options->position == FF_LOGO_POSITION_TOP)
{
instance.state.logoWidth = instance.state.logoHeight = 0;
ffPrintCharTimes('\n', options->paddingRight);
}
else if (options->position == FF_LOGO_POSITION_RIGHT)
{
instance.state.logoWidth = instance.state.logoHeight = 0;
printf("\e[1G\e[%uA", (unsigned) options->height);
}
}
return true;
@@ -345,12 +375,21 @@ static void printImagePixels(FFLogoRequestData* requestData, const FFstrbuf* res
//Write result to stdout
ffPrintCharTimes('\n', options->paddingTop);
ffPrintCharTimes(' ', options->paddingLeft);
if (options->position == FF_LOGO_POSITION_RIGHT)
printf("\e[9999999C\e[%uD", (unsigned) options->paddingRight + requestData->logoCharacterWidth);
else
printf("\e[%uC", (unsigned) options->paddingLeft);
fflush(stdout);
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), result);
//Go to upper left corner
printf("\e[1G\e[%uA", instance.state.logoHeight);
if (options->position != FF_LOGO_POSITION_TOP)
{
//Go to upper left corner
printf("\e[1G\e[%uA", instance.state.logoHeight);
}
if (options->position != FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = instance.state.logoHeight = 0;
}
static bool printImageSixel(FFLogoRequestData* requestData, const ImageData* imageData)
@@ -683,7 +722,9 @@ static bool printCachedChars(FFLogoRequestData* requestData)
static bool printCachedPixel(FFLogoRequestData* requestData)
{
requestData->logoCharacterWidth = instance.config.logo.width;
FFOptionsLogo* options = &instance.config.logo;
requestData->logoCharacterWidth = options->width;
if(requestData->logoCharacterWidth == 0)
{
requestData->logoCharacterWidth = readCachedUint32(requestData, FF_CACHE_FILE_WIDTH);
@@ -691,7 +732,7 @@ static bool printCachedPixel(FFLogoRequestData* requestData)
return false;
}
requestData->logoCharacterHeight = instance.config.logo.height;
requestData->logoCharacterHeight = options->height;
if(requestData->logoCharacterHeight == 0)
{
requestData->logoCharacterHeight = readCachedUint32(requestData, FF_CACHE_FILE_HEIGHT);
@@ -699,7 +740,7 @@ static bool printCachedPixel(FFLogoRequestData* requestData)
return false;
}
int fd = -1;
FF_AUTO_CLOSE_FD int fd = -1;
if(requestData->type == FF_LOGO_TYPE_IMAGE_KITTY)
{
fd = getCacheFD(requestData, FF_CACHE_FILE_KITTY_COMPRESSED);
@@ -712,22 +753,51 @@ static bool printCachedPixel(FFLogoRequestData* requestData)
if(fd == -1)
return false;
ffPrintCharTimes('\n', instance.config.logo.paddingTop);
ffPrintCharTimes(' ', instance.config.logo.paddingLeft);
ffPrintCharTimes('\n', options->paddingTop);
if (options->position == FF_LOGO_POSITION_RIGHT)
printf("\e[9999999C\e[%uD", (unsigned) options->paddingRight + requestData->logoCharacterWidth);
else
printf("\e[%uC", (unsigned) options->paddingLeft);
fflush(stdout);
char buffer[32768];
ssize_t readBytes;
while((readBytes = ffReadFDData(FFUnixFD2NativeFD(fd), sizeof(buffer), buffer)) > 0)
ffWriteFDData(FFUnixFD2NativeFD(STDOUT_FILENO), (size_t) readBytes, buffer);
bool sent = false;
#ifdef __linux__
struct stat st;
if (fstat(fd, &st) >= 0)
{
while (st.st_size > 0)
{
ssize_t bytes = sendfile(STDOUT_FILENO, fd, NULL, (size_t) st.st_size);
if (bytes > 0)
{
sent = true;
st.st_size -= bytes;
}
else
break;
}
}
#endif
close(fd);
if (!sent)
{
char buffer[32768];
ssize_t readBytes;
while((readBytes = ffReadFDData(FFUnixFD2NativeFD(fd), sizeof(buffer), buffer)) > 0)
ffWriteFDData(FFUnixFD2NativeFD(STDOUT_FILENO), (size_t) readBytes, buffer);
}
instance.state.logoWidth = requestData->logoCharacterWidth + instance.config.logo.paddingLeft + instance.config.logo.paddingRight;
instance.state.logoHeight = requestData->logoCharacterHeight + instance.config.logo.paddingTop;
instance.state.logoWidth = requestData->logoCharacterWidth + options->paddingLeft + options->paddingRight;
instance.state.logoHeight = requestData->logoCharacterHeight + options->paddingTop;
//Go to upper left corner
printf("\e[1G\e[%uA", instance.state.logoHeight);
if (options->position != FF_LOGO_POSITION_TOP)
{
//Go to upper left corner
printf("\e[1G\e[%uA", instance.state.logoHeight);
}
if (options->position != FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = instance.state.logoHeight = 0;
return true;
}
+69 -35
View File
@@ -53,54 +53,54 @@ static void ffLogoPrintCharsRaw(const char* data, size_t length)
}
}
void ffLogoPrintChars(const char* data, bool doColorReplacement)
// If result is NULL, calculate logo width
// Returns logo height
static uint32_t logoAppendChars(const char* data, bool doColorReplacement, FFstrbuf* result)
{
FFOptionsLogo* options = &instance.config.logo;
uint32_t currentlineLength = 0;
uint32_t logoHeight = 0;
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(2048);
if (!instance.config.display.pipe && instance.config.display.brightColor)
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_BOLT);
ffStrbufAppendNC(&result, options->paddingTop, '\n');
ffStrbufAppendNC(&result, options->paddingLeft, ' ');
instance.state.logoHeight = options->paddingTop;
//Use logoColor[0] as the default color
if(doColorReplacement && !instance.config.display.pipe)
ffStrbufAppendF(&result, "\e[%sm", options->colors[0].chars);
if (result)
{
if (options->position != FF_LOGO_POSITION_RIGHT)
ffStrbufAppendNC(result, options->paddingLeft, ' ');
else
ffStrbufAppendF(result, "\e[9999999C\e[%dD", options->paddingRight + instance.state.logoWidth);
}
while(*data != '\0')
{
//We are at the end of a line. Print paddings and update max line length
if(*data == '\n' || (*data == '\r' && *(data + 1) == '\n'))
{
ffStrbufAppendNC(&result, options->paddingRight, ' ');
//We have \r\n, skip the \r
if(*data == '\r')
++data;
ffStrbufAppendC(&result, '\n');
if(result) ffStrbufAppendC(result, '\n');
++data;
ffStrbufAppendNC(&result, options->paddingLeft, ' ');
if (result)
{
if (options->position != FF_LOGO_POSITION_RIGHT)
ffStrbufAppendNC(result, options->paddingLeft, ' ');
else
ffStrbufAppendF(result, "\e[9999999C\e[%dD", options->paddingRight + instance.state.logoWidth);
}
if(currentlineLength > instance.state.logoWidth)
instance.state.logoWidth = currentlineLength;
currentlineLength = 0;
++instance.state.logoHeight;
++logoHeight;
continue;
}
//Always print tabs as 4 spaces, to have consistent spacing
if(*data == '\t')
{
ffStrbufAppendNC(&result, 4, ' ');
if(result) ffStrbufAppendNC(result, 4, ' ');
++data;
continue;
}
@@ -110,16 +110,20 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
{
const char* start = data;
ffStrbufAppendS(&result, "\e[");
if(result) ffStrbufAppendS(result, "\e[");
data += 2;
while(ffCharIsDigit(*data) || *data == ';')
ffStrbufAppendC(&result, *data++); // number
{
if(result) ffStrbufAppendC(result, *data); // number
++data;
}
//We have a valid control sequence, print it and continue with next char
if(isascii(*data))
{
ffStrbufAppendC(&result, *data++); // single letter, end of control sequence
if(result) ffStrbufAppendC(result, *data); // single letter, end of control sequence
++data;
continue;
}
@@ -137,7 +141,7 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
//If we have $$, or $\0, print it as single $
if(*data == '$' || *data == '\0')
{
ffStrbufAppendC(&result, '$');
if(result) ffStrbufAppendC(result, '$');
++currentlineLength;
++data;
continue;
@@ -146,18 +150,18 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
if(!instance.config.display.pipe)
{
//Map the number to an array index, so that '1' -> 0, '2' -> 1, etc.
int index = ((int) *data) - 49;
int index = *data - '1';
//If the index is valid, print the color. Otherwise continue as normal
if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS)
{
ffStrbufAppendC(&result, '$');
if(result) ffStrbufAppendC(result, '$');
++currentlineLength;
//Don't continue here, we want to print the current char as unicode
}
else
{
ffStrbufAppendF(&result, "\e[%sm", options->colors[index].chars);
if(result) ffStrbufAppendF(result, "\e[%sm", options->colors[index].chars);
++data;
continue;
}
@@ -192,25 +196,55 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement)
if(*data == '\0')
break;
ffStrbufAppendC(&result, *data++);
if(result) ffStrbufAppendC(result, *data);
++data;
}
}
//Happens if the last line is the longest
if(currentlineLength > instance.state.logoWidth)
instance.state.logoWidth = currentlineLength;
return logoHeight;
}
void ffLogoPrintChars(const char* data, bool doColorReplacement)
{
FFOptionsLogo* options = &instance.config.logo;
if (options->position == FF_LOGO_POSITION_RIGHT)
logoAppendChars(data, doColorReplacement, NULL);
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreateA(2048);
if (!instance.config.display.pipe && instance.config.display.brightColor)
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_BOLT);
ffStrbufAppendNC(&result, options->paddingTop, '\n');
//Use logoColor[0] as the default color
if(doColorReplacement && !instance.config.display.pipe)
ffStrbufAppendF(&result, "\e[%sm", options->colors[0].chars);
instance.state.logoHeight = options->paddingTop + logoAppendChars(data, doColorReplacement, &result);
if(!instance.config.display.pipe)
ffStrbufAppendS(&result, FASTFETCH_TEXT_MODIFIER_RESET);
if(!options->separate)
if(options->position == FF_LOGO_POSITION_LEFT)
{
//Happens if the last line is the longest
if(currentlineLength > instance.state.logoWidth)
instance.state.logoWidth = currentlineLength;
instance.state.logoWidth += options->paddingLeft + options->paddingRight;
//Go to the leftmost position and go up the height
ffStrbufAppendF(&result, "\e[1G\e[%uA", instance.state.logoHeight);
}
else
else if(options->position == FF_LOGO_POSITION_RIGHT)
{
instance.state.logoWidth = 0;
//Go to the leftmost position and go up the height
ffStrbufAppendF(&result, "\e[1G\e[%uA", instance.state.logoHeight);
}
else if (options->position == FF_LOGO_POSITION_TOP)
{
instance.state.logoWidth = instance.state.logoHeight = 0;
ffStrbufAppendNC(&result, options->paddingRight, '\n');
+2 -2
View File
@@ -50,7 +50,7 @@ void ffPrintBios(FFBiosOptions* options)
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
ffStrbufWriteTo(&bios.version, stdout);
if (bios.release.length)
printf(" (%s)\n", bios.release.chars);
@@ -59,7 +59,7 @@ void ffPrintBios(FFBiosOptions* options)
}
else
{
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BIOS_NUM_FORMAT_ARGS, ((FFformatarg[]) {
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BIOS_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &bios.date, "date"},
{FF_FORMAT_ARG_TYPE_STRBUF, &bios.release, "release"},
{FF_FORMAT_ARG_TYPE_STRBUF, &bios.vendor, "vendor"},
+9 -5
View File
@@ -12,15 +12,19 @@ static void printCPUCacheNormal(const FFCPUCacheResult* result, FFCPUCacheOption
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
char levelStr[4] = "L";
for (uint32_t i = 0; i < sizeof (result->caches) / sizeof (result->caches[0]) && result->caches[i].length > 0; i++)
{
ffStrbufClear(&key);
levelStr[1] = (char) ('1' + i);
if (options->moduleArgs.key.length == 0)
ffStrbufAppendF(&key, "%s (L%u)", FF_CPUCACHE_DISPLAY_NAME, i + 1);
ffStrbufAppendF(&key, "%s (%s)", FF_CPUCACHE_DISPLAY_NAME, levelStr);
else
{
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 1, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT, &i, "index"},
uint32_t index = i + 1;
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 2, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT, &index, "index"},
{FF_FORMAT_ARG_TYPE_STRING, levelStr, "level"},
}));
}
@@ -49,14 +53,14 @@ static void printCPUCacheNormal(const FFCPUCacheResult* result, FFCPUCacheOption
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
ffStrbufPutTo(&buffer, stdout);
}
else
{
FF_STRBUF_AUTO_DESTROY buffer2 = ffStrbufCreate();
ffParseSize(sum, &buffer2);
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPUCACHE_NUM_FORMAT_ARGS, ((FFformatarg[]) {
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_CPUCACHE_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer, "result"},
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer2, "sum"},
}));
+2 -2
View File
@@ -37,7 +37,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
if(error)
{
ffPrintError(FF_DISKIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
ffPrintError(FF_DISKIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
return;
}
@@ -55,7 +55,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
ffParseSize(dev->bytesRead, &buffer);
if (!options->detectTotal) ffStrbufAppendS(&buffer, "/s");
+8 -4
View File
@@ -150,6 +150,7 @@ bool ffParseGPUCommandOptions(FFGPUOptions* options, const char* key, const char
{ "auto", FF_GPU_DETECTION_METHOD_AUTO },
{ "pci", FF_GPU_DETECTION_METHOD_PCI },
{ "vulkan", FF_GPU_DETECTION_METHOD_VULKAN },
{ "opencl", FF_GPU_DETECTION_METHOD_OPENCL },
{ "opengl", FF_GPU_DETECTION_METHOD_OPENGL },
{},
});
@@ -204,6 +205,7 @@ void ffParseGPUJsonObject(FFGPUOptions* options, yyjson_val* module)
{ "auto", FF_GPU_DETECTION_METHOD_AUTO },
{ "pci", FF_GPU_DETECTION_METHOD_PCI },
{ "vulkan", FF_GPU_DETECTION_METHOD_VULKAN },
{ "opencl", FF_GPU_DETECTION_METHOD_OPENCL },
{ "opengl", FF_GPU_DETECTION_METHOD_OPENGL },
{},
});
@@ -260,6 +262,9 @@ void ffGenerateGPUJsonConfig(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_
case FF_GPU_DETECTION_METHOD_VULKAN:
yyjson_mut_obj_add_str(doc, module, "detectionMethod", "vulkan");
break;
case FF_GPU_DETECTION_METHOD_OPENCL:
yyjson_mut_obj_add_str(doc, module, "detectionMethod", "opencl");
break;
case FF_GPU_DETECTION_METHOD_OPENGL:
yyjson_mut_obj_add_str(doc, module, "detectionMethod", "opengl");
break;
@@ -350,10 +355,9 @@ void ffGenerateGPUJsonResult(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_
yyjson_mut_obj_add_strbuf(doc, obj, "platformApi", &gpu->platformApi);
if (gpu->frequency == FF_GPU_FREQUENCY_UNSET)
yyjson_mut_obj_add_null(doc, obj, "frequency");
else
yyjson_mut_obj_add_real(doc, obj, "frequency", gpu->frequency);
yyjson_mut_obj_add_real(doc, obj, "frequency", gpu->frequency); // NaN will be output as "null"
yyjson_mut_obj_add_uint(doc, obj, "deviceId", gpu->deviceId);
}
FF_LIST_FOR_EACH(FFGPUResult, gpu, gpus)
+1
View File
@@ -17,6 +17,7 @@ typedef enum FFGPUDetectionMethod
FF_GPU_DETECTION_METHOD_AUTO,
FF_GPU_DETECTION_METHOD_PCI,
FF_GPU_DETECTION_METHOD_VULKAN,
FF_GPU_DETECTION_METHOD_OPENCL,
FF_GPU_DETECTION_METHOD_OPENGL,
} FFGPUDetectionMethod;
+1 -1
View File
@@ -57,7 +57,7 @@ void ffPrintNetIO(FFNetIOOptions* options)
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
ffParseSize(inf->rxBytes, &buffer);
if (!options->detectTotal) ffStrbufAppendS(&buffer, "/s");
+76 -46
View File
@@ -1,6 +1,7 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "detection/opencl/opencl.h"
#include "detection/gpu/gpu.h"
#include "modules/opencl/opencl.h"
#include "util/stringUtils.h"
@@ -8,35 +9,27 @@
void ffPrintOpenCL(FFOpenCLOptions* options)
{
FFOpenCLResult opencl;
ffStrbufInit(&opencl.version);
ffStrbufInit(&opencl.device);
ffStrbufInit(&opencl.vendor);
FFOpenCLResult* result = ffDetectOpenCL();
const char* error = ffDetectOpenCL(&opencl);
if(error != NULL)
ffPrintError(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
else
if(result->error != NULL)
{
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffStrbufPutTo(&opencl.version, stdout);
}
else
{
FF_PRINT_FORMAT_CHECKED(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_OPENCL_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &opencl.version, "version"},
{FF_FORMAT_ARG_TYPE_STRBUF, &opencl.device, "device"},
{FF_FORMAT_ARG_TYPE_STRBUF, &opencl.vendor, "vendor"},
}));
}
ffPrintError(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", result->error);
return;
}
ffStrbufDestroy(&opencl.version);
ffStrbufDestroy(&opencl.device);
ffStrbufDestroy(&opencl.vendor);
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffStrbufPutTo(&result->version, stdout);
}
else
{
FF_PRINT_FORMAT_CHECKED(FF_OPENCL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_OPENCL_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result->version, "version"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name, "name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->vendor, "vendor"},
}));
}
}
bool ffParseOpenCLCommandOptions(FFOpenCLOptions* options, const char* key, const char* value)
@@ -76,36 +69,73 @@ void ffGenerateOpenCLJsonConfig(FFOpenCLOptions* options, yyjson_mut_doc* doc, y
void ffGenerateOpenCLJsonResult(FF_MAYBE_UNUSED FFOpenCLOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FFOpenCLResult opencl;
ffStrbufInit(&opencl.version);
ffStrbufInit(&opencl.device);
ffStrbufInit(&opencl.vendor);
FFOpenCLResult* result = ffDetectOpenCL();
const char* error = ffDetectOpenCL(&opencl);
if(error != NULL)
if(result->error != NULL)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
}
else
{
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
yyjson_mut_obj_add_strbuf(doc, obj, "version", &opencl.version);
yyjson_mut_obj_add_strbuf(doc, obj, "device", &opencl.device);
yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &opencl.vendor);
yyjson_mut_obj_add_str(doc, module, "error", result->error);
return;
}
ffStrbufDestroy(&opencl.version);
ffStrbufDestroy(&opencl.device);
ffStrbufDestroy(&opencl.vendor);
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->version);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &result->name);
yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &result->vendor);
yyjson_mut_val* gpus = yyjson_mut_obj_add_arr(doc, obj, "gpus");
FF_LIST_FOR_EACH(FFGPUResult, gpu, result->gpus)
{
yyjson_mut_val* gpuObj = yyjson_mut_arr_add_obj(doc, gpus);
yyjson_mut_obj_add_str(doc, gpuObj, "type", gpu->type == FF_GPU_TYPE_UNKNOWN ? "Unknown" : gpu->type == FF_GPU_TYPE_INTEGRATED ? "Integrated" : "Discrete");
yyjson_mut_obj_add_strbuf(doc, gpuObj, "vendor", &gpu->vendor);
yyjson_mut_obj_add_strbuf(doc, gpuObj, "name", &gpu->name);
yyjson_mut_obj_add_strbuf(doc, gpuObj, "driver", &gpu->driver);
yyjson_mut_obj_add_strbuf(doc, gpuObj, "platformApi", &gpu->platformApi);
if (gpu->coreCount != FF_GPU_CORE_COUNT_UNSET)
yyjson_mut_obj_add_int(doc, gpuObj, "coreCount", gpu->coreCount);
else
yyjson_mut_obj_add_null(doc, gpuObj, "coreCount");
yyjson_mut_obj_add_real(doc, gpuObj, "frequency", gpu->frequency);
yyjson_mut_val* memoryObj = yyjson_mut_obj_add_obj(doc, gpuObj, "memory");
{
yyjson_mut_val* dedicatedMemory = yyjson_mut_obj_add_obj(doc, memoryObj, "dedicated");
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
yyjson_mut_obj_add_uint(doc, dedicatedMemory, "total", gpu->dedicated.total);
else
yyjson_mut_obj_add_null(doc, dedicatedMemory, "total");
if (gpu->dedicated.used != FF_GPU_VMEM_SIZE_UNSET)
yyjson_mut_obj_add_uint(doc, dedicatedMemory, "used", gpu->dedicated.total);
else
yyjson_mut_obj_add_null(doc, dedicatedMemory, "used");
}
{
yyjson_mut_val* sharedMemory = yyjson_mut_obj_add_obj(doc, memoryObj, "shared");
if (gpu->shared.total != FF_GPU_VMEM_SIZE_UNSET)
yyjson_mut_obj_add_uint(doc, sharedMemory, "total", gpu->shared.total);
else
yyjson_mut_obj_add_null(doc, sharedMemory, "total");
if (gpu->shared.used != FF_GPU_VMEM_SIZE_UNSET)
yyjson_mut_obj_add_uint(doc, sharedMemory, "used", gpu->shared.used);
else
yyjson_mut_obj_add_null(doc, sharedMemory, "used");
}
yyjson_mut_obj_add_uint(doc, gpuObj, "deviceId", gpu->deviceId);
}
}
void ffPrintOpenCLHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_OPENCL_MODULE_NAME, "{1}", FF_OPENCL_NUM_FORMAT_ARGS, ((const char* []) {
"version - version",
"device - device",
"vendor - vendor"
"Platform version - version",
"Platform name - name",
"Platform vendor - vendor",
}));
}
+1 -1
View File
@@ -70,7 +70,7 @@ void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
if (physicalType[0] || removableType[0] || readOnlyType[0])
{
+2 -6
View File
@@ -32,11 +32,7 @@ void ffPrintPhysicalMemory(FFPhysicalMemoryOptions* options)
if (options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(
FF_PHYSICALMEMORY_DISPLAY_NAME,
result.length == 1 ? 0 : (uint8_t) i,
&options->moduleArgs,
FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(FF_PHYSICALMEMORY_DISPLAY_NAME, result.length == 1 ? 0 : (uint8_t) i, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
fputs(prettySize.chars, stdout);
fputs(" - ", stdout);
@@ -53,7 +49,7 @@ void ffPrintPhysicalMemory(FFPhysicalMemoryOptions* options)
}
else
{
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_PHYSICALMEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
FF_PRINT_FORMAT_CHECKED(FF_PHYSICALMEMORY_DISPLAY_NAME, (uint8_t) i, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_PHYSICALMEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_UINT64, &device->size, "bytes"},
{FF_FORMAT_ARG_TYPE_STRBUF, &prettySize, "size"},
{FF_FORMAT_ARG_TYPE_UINT, &device->maxSpeed, "max-speed"},
+1
View File
@@ -110,6 +110,7 @@ void ffGenerateVulkanJsonResult(FF_MAYBE_UNUSED FFVulkanOptions* options, yyjson
yyjson_mut_obj_add_strbuf(doc, gpuObj, "name", &vulkanGpu->name);
yyjson_mut_obj_add_strbuf(doc, gpuObj, "driver", &vulkanGpu->driver);
yyjson_mut_obj_add_strbuf(doc, gpuObj, "platformApi", &vulkanGpu->platformApi);
yyjson_mut_obj_add_uint(doc, gpuObj, "deviceId", vulkanGpu->deviceId);
yyjson_mut_val* memoryObj = yyjson_mut_obj_add_obj(doc, gpuObj, "memory");
+15
View File
@@ -1,5 +1,6 @@
#include "fastfetch.h"
#include "common/jsonconfig.h"
#include "common/processing.h"
#include "options/general.h"
#include "util/stringUtils.h"
@@ -21,6 +22,20 @@ const char* ffOptionsParseGeneralJsonConfig(FFOptionsGeneral* options, yyjson_va
options->multithreading = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "processingTimeout"))
options->processingTimeout = (int32_t) yyjson_get_int(val);
else if (ffStrEqualsIgnCase(key, "preRun"))
{
FF_STRBUF_AUTO_DESTROY _ = ffStrbufCreate();
const char* error = ffProcessAppendStdOut(&_, (char* const[]) {
#ifdef _WIN32
"cmd.exe", "/C",
#else
"/bin/sh", "-c",
#endif
(char*) yyjson_get_str(val), NULL
});
if (error)
return "Failed to execute preRun command";
}
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
else if (ffStrEqualsIgnCase(key, "escapeBedrock"))
+35 -6
View File
@@ -17,7 +17,7 @@ void ffOptionsInitLogo(FFOptionsLogo* options)
options->printRemaining = true;
options->preserveAspectRatio = false;
options->recache = false;
options->separate = false;
options->position = FF_LOGO_POSITION_LEFT;
options->chafaFgOnly = false;
ffStrbufInitStatic(&options->chafaSymbols, "block+border+space-wide-inverted"); // Chafa default
@@ -111,7 +111,19 @@ logoType:
else if(ffStrEqualsIgnCase(subKey, "recache"))
options->recache = ffOptionParseBoolean(value);
else if(ffStrEqualsIgnCase(subKey, "separate"))
options->separate = ffOptionParseBoolean(value);
{
fputs("--logo-separate has been renamed to --logo-position\n", stderr);
exit(477);
}
else if(ffStrEqualsIgnCase(subKey, "position"))
{
options->position = (FFLogoPosition) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
{ "left", FF_LOGO_POSITION_LEFT },
{ "right", FF_LOGO_POSITION_RIGHT },
{ "top", FF_LOGO_POSITION_TOP },
{},
});
}
else
return false;
}
@@ -355,9 +367,20 @@ const char* ffOptionsParseLogoJsonConfig(FFOptionsLogo* options, yyjson_val* roo
options->recache = yyjson_get_bool(val);
continue;
}
else if (ffStrEqualsIgnCase(key, "separate"))
else if(ffStrEqualsIgnCase(key, "separate"))
return "logo.separate has been renamed to logo.position\n";
else if (ffStrEqualsIgnCase(key, "position"))
{
options->separate = yyjson_get_bool(val);
int value;
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
{ "left", FF_LOGO_POSITION_LEFT },
{ "top", FF_LOGO_POSITION_TOP },
{ "right", FF_LOGO_POSITION_RIGHT },
{},
});
if (error) return error;
options->position = (FFLogoPosition) value;
continue;
}
else if (ffStrEqualsIgnCase(key, "chafa"))
@@ -528,8 +551,14 @@ void ffOptionsGenerateLogoJsonConfig(FFOptionsLogo* options, yyjson_mut_doc* doc
if (options->recache != defaultOptions.recache)
yyjson_mut_obj_add_bool(doc, obj, "recache", options->recache);
if (options->separate != defaultOptions.separate)
yyjson_mut_obj_add_bool(doc, obj, "separate", options->separate);
if (options->position != defaultOptions.position)
{
yyjson_mut_obj_add_str(doc, obj, "position", ((const char* []) {
"left",
"top",
"right",
})[options->position]);
}
{
yyjson_mut_val* chafa = yyjson_mut_obj(doc);
+8 -1
View File
@@ -23,10 +23,18 @@ typedef enum FFLogoType
FF_LOGO_TYPE_NONE, //--logo none
} FFLogoType;
typedef enum FFLogoPosition
{
FF_LOGO_POSITION_LEFT,
FF_LOGO_POSITION_TOP,
FF_LOGO_POSITION_RIGHT,
} FFLogoPosition;
typedef struct FFOptionsLogo
{
FFstrbuf source;
FFLogoType type;
FFLogoPosition position;
FFstrbuf colors[FASTFETCH_LOGO_MAX_COLORS];
uint32_t width;
uint32_t height;
@@ -36,7 +44,6 @@ typedef struct FFOptionsLogo
bool printRemaining;
bool preserveAspectRatio;
bool recache;
bool separate;
bool chafaFgOnly;
FFstrbuf chafaSymbols;