mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ff8b69019f | |||
| 28c367c6a4 | |||
| 48929622f8 | |||
| 1754aaef5f | |||
| da401a7c3e | |||
| 412fda612f | |||
| 2299439873 | |||
| 62fe9e1d11 | |||
| e9258cc5a8 | |||
| d8ae93f85d | |||
| ff1ecb4166 | |||
| d8ef56c3b3 | |||
| 68a0f5e3c6 | |||
| a0e913a14c | |||
| 9a940d73ba | |||
| 19ae272052 | |||
| d9286050b6 | |||
| 14ca210655 | |||
| 300ad93022 | |||
| 63ff315914 | |||
| 7663cb4399 | |||
| 944c63e8ec | |||
| 12f0088d72 | |||
| 4826986cd8 |
@@ -1,3 +1,20 @@
|
|||||||
|
# 2.66.1
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fixed I/O rate calculation precision and prevented division by zero. (DiskIO / NetIO)
|
||||||
|
* Fixed ash and fish version detection, including a potential out-of-bounds read. (Shell)
|
||||||
|
* Fixed integer handling for varying sysctl data lengths. (Sysctl)
|
||||||
|
* Fixed several memory leaks in Camera, Codec, Display, Separator and Weather.
|
||||||
|
* Fixed Base64 encoding on big-endian hosts. (Base64)
|
||||||
|
* Fixed VP9 codec detection and macOS 10.15 Codec compatibility. (Codec, macOS)
|
||||||
|
* Relaxed accepted HTTP response formats and fixed invalid PublicIP URL parsing. (Networking / PublicIP)
|
||||||
|
* Added a response size limit to prevent excessive network memory allocation. (Networking)
|
||||||
|
* Added integer overflow checks to string buffer capacity handling. (FFstrbuf)
|
||||||
|
* Fixed Ubuntu Studio Core detection. (OS, Linux)
|
||||||
|
* Fixed preferred monitor mode detection for KDE Plasma. (Display, Linux)
|
||||||
|
* Fixed bright colors being enabled incorrectly in light themes. (Display)
|
||||||
|
* Fixed a macOS compiler warning. (Version, macOS)
|
||||||
|
|
||||||
# 2.66.0
|
# 2.66.0
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||||
|
|
||||||
project(fastfetch
|
project(fastfetch
|
||||||
VERSION 2.66.0
|
VERSION 2.66.1
|
||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
DESCRIPTION "Fast neofetch-like system information tool"
|
DESCRIPTION "Fast neofetch-like system information tool"
|
||||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||||
|
|||||||
@@ -223,9 +223,7 @@ static inline void ffStrbufClear(FFstrbuf* strbuf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void ffStrbufAppendC(FFstrbuf* strbuf, char c) {
|
static inline void ffStrbufAppendC(FFstrbuf* strbuf, char c) {
|
||||||
if (__builtin_expect(ffStrbufGetFree(strbuf) == 0, false)) {
|
ffStrbufEnsureFree(strbuf, 1);
|
||||||
ffStrbufEnsureFreeNoCheck(strbuf, 1);
|
|
||||||
}
|
|
||||||
strbuf->chars[strbuf->length++] = c;
|
strbuf->chars[strbuf->length++] = c;
|
||||||
strbuf->chars[strbuf->length] = '\0';
|
strbuf->chars[strbuf->length] = '\0';
|
||||||
}
|
}
|
||||||
@@ -234,9 +232,7 @@ static inline void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c) {
|
|||||||
if (__builtin_expect(num == 0, false)) {
|
if (__builtin_expect(num == 0, false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (__builtin_expect(ffStrbufGetFree(strbuf) < num, false)) {
|
ffStrbufEnsureFree(strbuf, num);
|
||||||
ffStrbufEnsureFreeNoCheck(strbuf, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&strbuf->chars[strbuf->length], c, num);
|
memset(&strbuf->chars[strbuf->length], c, num);
|
||||||
strbuf->length += num;
|
strbuf->length += num;
|
||||||
@@ -247,9 +243,7 @@ static inline void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const cha
|
|||||||
if (__builtin_expect(value == NULL || length == 0, false)) {
|
if (__builtin_expect(value == NULL || length == 0, false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (__builtin_expect(ffStrbufGetFree(strbuf) < length, false)) {
|
ffStrbufEnsureFree(strbuf, length);
|
||||||
ffStrbufEnsureFreeNoCheck(strbuf, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&strbuf->chars[strbuf->length], value, length);
|
memcpy(&strbuf->chars[strbuf->length], value, length);
|
||||||
strbuf->length += length;
|
strbuf->length += length;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ bool ffGetAppNameAndVersion(const char* exePath, FFstrbuf* retName, FFstrbuf* re
|
|||||||
|
|
||||||
lastSlash -= strlen("MacOS");
|
lastSlash -= strlen("MacOS");
|
||||||
char infoPlistPath[PATH_MAX];
|
char infoPlistPath[PATH_MAX];
|
||||||
memcpy(infoPlistPath, exePath, lastSlash - exePath);
|
memcpy(infoPlistPath, exePath, (size_t) (lastSlash - exePath));
|
||||||
memcpy(infoPlistPath + (lastSlash - exePath), "Info.plist", sizeof("Info.plist")); // X.app/Contents/Info.plist
|
memcpy(infoPlistPath + (lastSlash - exePath), "Info.plist", sizeof("Info.plist")); // X.app/Contents/Info.plist
|
||||||
NSError* error;
|
NSError* error;
|
||||||
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@(infoPlistPath)]
|
NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@(infoPlistPath)]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "common/FFstrbuf.h"
|
#include "common/FFstrbuf.h"
|
||||||
#include "common/mallocHelper.h"
|
#include "common/mallocHelper.h"
|
||||||
#include "common/strutil.h"
|
#include "common/strutil.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -64,13 +65,24 @@ FFstrbuf ffStrbufCreateF(const char* format, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free) {
|
void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free) {
|
||||||
uint32_t allocate = strbuf->length + free;
|
uint32_t allocate;
|
||||||
|
if (__builtin_expect(__builtin_uadd_overflow(strbuf->length, free, &allocate), false)) {
|
||||||
|
FF_DEBUG("Error: Integer overflow when calculating allocation size. Aborting");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) { // `<` for null terminator
|
if (allocate < FASTFETCH_STRBUF_DEFAULT_ALLOC) { // `<` for null terminator
|
||||||
allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC;
|
allocate = FASTFETCH_STRBUF_DEFAULT_ALLOC;
|
||||||
} else {
|
} else {
|
||||||
|
if (__builtin_expect(allocate > (UINT32_MAX >> 1), false)) {
|
||||||
|
// User tried to allocate more than 2GB of memory, which exceeds the maximum size supported by FFstrbuf.
|
||||||
|
// This is likely an error or an attempt to exploit the program. Abort to prevent potential issues.
|
||||||
|
FF_DEBUG("Error: Attempted to allocate %" PRIu32 " bytes more than 2GB of memory in FFstrbuf. Aborting", allocate);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
// Round up to the next power of 2.
|
// Round up to the next power of 2.
|
||||||
// If the value is already a power of 2, it will be rounded up to the next power of 2.
|
// If the value is already a power of 2, it will be rounded up to the next power of 2.
|
||||||
assert(allocate < (UINT32_MAX >> 1));
|
|
||||||
allocate = 1U << (32 - __builtin_clz(allocate));
|
allocate = 1U << (32 - __builtin_clz(allocate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,16 +103,17 @@ void ffStrbufEnsureFreeNoCheck(FFstrbuf* strbuf, uint32_t free) {
|
|||||||
|
|
||||||
// Ensure that at least `free` bytes are available in the buffer besides the current length
|
// Ensure that at least `free` bytes are available in the buffer besides the current length
|
||||||
// for an empty buffer, free + 1 length memory will be allocated(+1 for the NUL)
|
// for an empty buffer, free + 1 length memory will be allocated(+1 for the NUL)
|
||||||
|
// This function ensures a dynamic buffer is allocated even if free == 0
|
||||||
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
|
void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
|
||||||
uint32_t oldFree = ffStrbufGetFree(strbuf);
|
uint32_t newCap;
|
||||||
if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t newCap = strbuf->allocated + (free - oldFree);
|
|
||||||
|
|
||||||
if (strbuf->allocated == 0) {
|
if (strbuf->allocated == 0) {
|
||||||
newCap += strbuf->length + 1;
|
assert(strbuf->length < UINT32_MAX - 1); // We don't use static strings with length >= UINT32_MAX - 1, so this should never happen
|
||||||
|
if (__builtin_expect(__builtin_uadd_overflow(strbuf->length + 1, free, &newCap), false)) {
|
||||||
|
FF_DEBUG("Error: Integer overflow when calculating new capacity. Aborting");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
char* newbuf = malloc(sizeof(*strbuf->chars) * newCap);
|
char* newbuf = malloc(sizeof(*strbuf->chars) * newCap);
|
||||||
if (strbuf->length == 0) {
|
if (strbuf->length == 0) {
|
||||||
*newbuf = '\0';
|
*newbuf = '\0';
|
||||||
@@ -109,6 +122,15 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free) {
|
|||||||
}
|
}
|
||||||
strbuf->chars = newbuf;
|
strbuf->chars = newbuf;
|
||||||
} else {
|
} else {
|
||||||
|
uint32_t oldFree = ffStrbufGetFree(strbuf);
|
||||||
|
if (oldFree >= free) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__builtin_expect(__builtin_uadd_overflow(strbuf->allocated, free - oldFree, &newCap), false)) {
|
||||||
|
FF_DEBUG("Error: Integer overflow when calculating new capacity. Aborting");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
|
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ void ffBase64EncodeRaw(uint32_t size, const char* str, uint32_t* out_size, char*
|
|||||||
char* out = output;
|
char* out = output;
|
||||||
const char* ends = str + (size - size % 3);
|
const char* ends = str + (size - size % 3);
|
||||||
while (str != ends) {
|
while (str != ends) {
|
||||||
uint32_t n = __builtin_bswap32(*(uint32_t*) str);
|
uint32_t n = *(uint32_t*) str;
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
// The 3 input bytes must be laid out big-endian (str[0] in the most
|
||||||
|
// significant position). On little-endian hosts swap; on big-endian
|
||||||
|
// hosts the word is already in the right order.
|
||||||
|
n = __builtin_bswap32(n);
|
||||||
|
#endif
|
||||||
*out++ = chars[(n >> 26) & 63];
|
*out++ = chars[(n >> 26) & 63];
|
||||||
*out++ = chars[(n >> 20) & 63];
|
*out++ = chars[(n >> 20) & 63];
|
||||||
*out++ = chars[(n >> 14) & 63];
|
*out++ = chars[(n >> 14) & 63];
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <stdalign.h>
|
||||||
|
|
||||||
bool ffParseModuleOptions(const char* key, const char* value) {
|
bool ffParseModuleOptions(const char* key, const char* value) {
|
||||||
if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) {
|
if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) {
|
||||||
@@ -175,7 +176,7 @@ static bool parseStructureCommand(
|
|||||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules) {
|
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules) {
|
||||||
FFModuleBaseInfo* baseInfo = *modules;
|
FFModuleBaseInfo* baseInfo = *modules;
|
||||||
if (ffStrEqualsIgnCase(line, baseInfo->name)) {
|
if (ffStrEqualsIgnCase(line, baseInfo->name)) {
|
||||||
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
alignas(uint64_t) uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
||||||
baseInfo->initOptions(optionBuf);
|
baseInfo->initOptions(optionBuf);
|
||||||
if (data->resultDoc != NULL) {
|
if (data->resultDoc != NULL) {
|
||||||
fn(data, baseInfo, optionBuf);
|
fn(data, baseInfo, optionBuf);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include "common/textModifier.h"
|
#include "common/textModifier.h"
|
||||||
#include "common/strutil.h"
|
#include "common/strutil.h"
|
||||||
#include "detection/displayserver/displayserver.h"
|
#include "detection/displayserver/displayserver.h"
|
||||||
#include "detection/terminaltheme/terminaltheme.h"
|
|
||||||
#include "logo/logo.h"
|
#include "logo/logo.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -27,21 +26,10 @@ static void initState(FFstate* state) {
|
|||||||
state->logoWidth = 0;
|
state->logoWidth = 0;
|
||||||
state->logoHeight = 0;
|
state->logoHeight = 0;
|
||||||
state->keysHeight = 0;
|
state->keysHeight = 0;
|
||||||
state->terminalLightTheme = false;
|
|
||||||
state->titleFqdn = false;
|
state->titleFqdn = false;
|
||||||
|
|
||||||
ffPlatformInit(&state->platform);
|
ffPlatformInit(&state->platform);
|
||||||
state->dynamicInterval = 0;
|
state->dynamicInterval = 0;
|
||||||
|
|
||||||
#if !FF_MODULE_DISABLE_TERMINALTHEME
|
|
||||||
{
|
|
||||||
// don't enable bright color if the terminal is in light mode
|
|
||||||
FFTerminalThemeResult result;
|
|
||||||
if (ffDetectTerminalTheme(&result, true /* forceEnv for performance */) && !result.bg.dark) {
|
|
||||||
state->terminalLightTheme = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void defaultConfig(void) {
|
static void defaultConfig(void) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <stdalign.h>
|
||||||
|
|
||||||
bool ffJsonConfigParseModuleArgs(yyjson_val* key, yyjson_val* val, FFModuleArgs* moduleArgs) {
|
bool ffJsonConfigParseModuleArgs(yyjson_val* key, yyjson_val* val, FFModuleArgs* moduleArgs) {
|
||||||
if (unsafe_yyjson_equals_str(key, "type") || unsafe_yyjson_equals_str(key, "condition")) {
|
if (unsafe_yyjson_equals_str(key, "type") || unsafe_yyjson_equals_str(key, "condition")) {
|
||||||
@@ -95,7 +96,7 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_
|
|||||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules) {
|
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules) {
|
||||||
FFModuleBaseInfo* baseInfo = *modules;
|
FFModuleBaseInfo* baseInfo = *modules;
|
||||||
if (ffStrEqualsIgnCase(type, baseInfo->name)) {
|
if (ffStrEqualsIgnCase(type, baseInfo->name)) {
|
||||||
uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
alignas(uint64_t) uint8_t optionBuf[FF_OPTION_MAX_SIZE];
|
||||||
baseInfo->initOptions(optionBuf);
|
baseInfo->initOptions(optionBuf);
|
||||||
if (jsonVal) {
|
if (jsonVal) {
|
||||||
baseInfo->parseJsonObject(optionBuf, jsonVal);
|
baseInfo->parseJsonObject(optionBuf, jsonVal);
|
||||||
|
|||||||
@@ -457,6 +457,13 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
if (clHeader) {
|
if (clHeader) {
|
||||||
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
|
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
|
||||||
if (contentLength > 0) {
|
if (contentLength > 0) {
|
||||||
|
if (contentLength > 1024 * 1024) { // 1MB limit to prevent excessive memory allocation and potential attacks
|
||||||
|
FF_DEBUG("Content-Length is too large: %u bytes, aborting", contentLength);
|
||||||
|
close(state->sockfd);
|
||||||
|
state->sockfd = -1;
|
||||||
|
return "Content-Length too large";
|
||||||
|
}
|
||||||
|
|
||||||
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
||||||
// Ensure buffer is large enough, adding header size and some margin
|
// Ensure buffer is large enough, adding header size and some margin
|
||||||
ffStrbufEnsureFree(buffer, contentLength + 16);
|
ffStrbufEnsureFree(buffer, contentLength + 16);
|
||||||
@@ -481,7 +488,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
return "No HTTP header end found";
|
return "No HTTP header end found";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n") && !ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n")) {
|
||||||
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
||||||
return "Invalid response";
|
return "Invalid response";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,6 +322,13 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
if (clHeader) {
|
if (clHeader) {
|
||||||
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
|
contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10);
|
||||||
if (contentLength > 0) {
|
if (contentLength > 0) {
|
||||||
|
if (contentLength > 1024 * 1024) { // 1MB limit to prevent excessive memory allocation and potential attacks
|
||||||
|
FF_DEBUG("Content-Length is too large: %u bytes, aborting", contentLength);
|
||||||
|
closesocket(state->sockfd);
|
||||||
|
state->sockfd = INVALID_SOCKET;
|
||||||
|
return "Content-Length too large";
|
||||||
|
}
|
||||||
|
|
||||||
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength);
|
||||||
// Ensure buffer is large enough, adding header size and some margin
|
// Ensure buffer is large enough, adding header size and some margin
|
||||||
ffStrbufEnsureFree(buffer, contentLength + 16);
|
ffStrbufEnsureFree(buffer, contentLength + 16);
|
||||||
@@ -346,7 +353,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
|||||||
return "No HTTP header end found";
|
return "No HTTP header end found";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n") && !ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n")) {
|
||||||
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
||||||
return "Invalid response";
|
return "Invalid response";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "common/sysctl.h"
|
#include "common/sysctl.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdalign.h>
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result) {
|
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result) {
|
||||||
@@ -22,21 +23,41 @@ const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ffSysctlGetInt(int mib1, int mib2, int defaultValue) {
|
int ffSysctlGetInt(int mib1, int mib2, int defaultValue) {
|
||||||
int result;
|
alignas(int) uint8_t result[sizeof(int)];
|
||||||
size_t neededLength = sizeof(result);
|
size_t neededLength = sizeof(result);
|
||||||
if (sysctl((int[]) { mib1, mib2 }, 2, &result, &neededLength, NULL, 0) != 0) {
|
if (sysctl((int[]) { mib1, mib2 }, 2, &result, &neededLength, NULL, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
switch (neededLength) {
|
||||||
|
case sizeof(int32_t):
|
||||||
|
return *(int32_t*)result;
|
||||||
|
case sizeof(int16_t):
|
||||||
|
return *(int16_t*)result;
|
||||||
|
case sizeof(int8_t):
|
||||||
|
return *(int8_t*)result;
|
||||||
|
default:
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue) {
|
int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue) {
|
||||||
int64_t result;
|
alignas(int64_t) uint8_t result[sizeof(int64_t)];
|
||||||
size_t neededLength = sizeof(result);
|
size_t neededLength = sizeof(result);
|
||||||
if (sysctl((int[]) { mib1, mib2 }, 2, &result, &neededLength, NULL, 0) != 0) {
|
if (sysctl((int[]) { mib1, mib2 }, 2, &result, &neededLength, NULL, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
switch (neededLength) {
|
||||||
|
case sizeof(int64_t):
|
||||||
|
return *(int64_t*)result;
|
||||||
|
case sizeof(int32_t):
|
||||||
|
return *(int32_t*)result;
|
||||||
|
case sizeof(int16_t):
|
||||||
|
return *(int16_t*)result;
|
||||||
|
case sizeof(int8_t):
|
||||||
|
return *(int8_t*)result;
|
||||||
|
default:
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
|
const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
|
||||||
@@ -59,21 +80,41 @@ const char* ffSysctlGetString(const char* propName, FFstrbuf* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ffSysctlGetInt(const char* propName, int defaultValue) {
|
int ffSysctlGetInt(const char* propName, int defaultValue) {
|
||||||
int result;
|
alignas(int) uint8_t result[sizeof(int)];
|
||||||
size_t neededLength = sizeof(result);
|
size_t neededLength = sizeof(result);
|
||||||
if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
|
if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
switch (neededLength) {
|
||||||
|
case sizeof(int32_t):
|
||||||
|
return *(int32_t*)result;
|
||||||
|
case sizeof(int16_t):
|
||||||
|
return *(int16_t*)result;
|
||||||
|
case sizeof(int8_t):
|
||||||
|
return *(int8_t*)result;
|
||||||
|
default:
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue) {
|
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue) {
|
||||||
int64_t result;
|
alignas(int64_t) uint8_t result[sizeof(int64_t)];
|
||||||
size_t neededLength = sizeof(result);
|
size_t neededLength = sizeof(result);
|
||||||
if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
|
if (sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
return result;
|
switch (neededLength) {
|
||||||
|
case sizeof(int64_t):
|
||||||
|
return *(int64_t*)result;
|
||||||
|
case sizeof(int32_t):
|
||||||
|
return *(int32_t*)result;
|
||||||
|
case sizeof(int16_t):
|
||||||
|
return *(int16_t*)result;
|
||||||
|
case sizeof(int8_t):
|
||||||
|
return *(int8_t*)result;
|
||||||
|
default:
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // OpenBSD
|
#endif // OpenBSD
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
#include <VideoToolbox/VideoToolbox.h>
|
#include <VideoToolbox/VideoToolbox.h>
|
||||||
#include "common/apple/cf_helpers.h"
|
#include "common/apple/cf_helpers.h"
|
||||||
|
|
||||||
|
#ifdef MAC_OS_VERSION_11_0
|
||||||
|
[[clang::weak_import]] VT_EXPORT void VTRegisterSupplementalVideoDecoderIfAvailable(CMVideoCodecType codecType);
|
||||||
|
#endif
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
CMVideoCodecType codec;
|
CMVideoCodecType codec;
|
||||||
FFCodecType type;
|
FFCodecType type;
|
||||||
@@ -41,7 +45,7 @@ static FFCodecType ffCodecCodecToType(CMVideoCodecType codec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static FFCodecType ffCodecDetectEncoders(void) {
|
static FFCodecType ffCodecDetectEncoders(void) {
|
||||||
CFArrayRef encoderList = NULL;
|
FF_CFTYPE_AUTO_RELEASE CFArrayRef encoderList = NULL;
|
||||||
if (VTCopyVideoEncoderList(NULL, &encoderList) != noErr || !encoderList) {
|
if (VTCopyVideoEncoderList(NULL, &encoderList) != noErr || !encoderList) {
|
||||||
return FF_CODEC_TYPE_NONE;
|
return FF_CODEC_TYPE_NONE;
|
||||||
}
|
}
|
||||||
@@ -65,16 +69,22 @@ static FFCodecType ffCodecDetectEncoders(void) {
|
|||||||
static FFCodecType ffCodecDetectDecoders() {
|
static FFCodecType ffCodecDetectDecoders() {
|
||||||
FFCodecType types = FF_CODEC_TYPE_NONE;
|
FFCodecType types = FF_CODEC_TYPE_NONE;
|
||||||
for (uint32_t i = 0; i < ARRAY_SIZE(FF_CODEC_CODECS); ++i) {
|
for (uint32_t i = 0; i < ARRAY_SIZE(FF_CODEC_CODECS); ++i) {
|
||||||
if (types & FF_CODEC_CODECS[i].type) {
|
__auto_type codec = FF_CODEC_CODECS[i];
|
||||||
|
if (types & codec.type) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supported = VTIsHardwareDecodeSupported(FF_CODEC_CODECS[i].codec);
|
#ifdef MAC_OS_VERSION_11_0
|
||||||
|
if (VTRegisterSupplementalVideoDecoderIfAvailable) {
|
||||||
|
VTRegisterSupplementalVideoDecoderIfAvailable(codec.codec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bool supported = VTIsHardwareDecodeSupported(codec.codec);
|
||||||
if (!supported) {
|
if (!supported) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
types |= FF_CODEC_CODECS[i].type;
|
types |= codec.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
|
|||||||
@@ -72,8 +72,7 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options) {
|
|||||||
uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off);
|
uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off);
|
||||||
uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off);
|
uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off);
|
||||||
uint64_t temp = *currValue;
|
uint64_t temp = *currValue;
|
||||||
*currValue -= *prevValue;
|
*currValue = (*currValue - *prevValue) * 1000 / (time2 - time1); // Calculate per second
|
||||||
*currValue /= (time2 - time1) / 1000 /* seconds */;
|
|
||||||
|
|
||||||
// For next function call
|
// For next function call
|
||||||
*prevValue = temp;
|
*prevValue = temp;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ static void handleXdgLogicalSize(void* data, FF_A_UNUSED struct zxdg_output_v1*
|
|||||||
static void* outputListener[] = {
|
static void* outputListener[] = {
|
||||||
waylandOutputGeometryListener, // geometry
|
waylandOutputGeometryListener, // geometry
|
||||||
waylandOutputModeListener, // mode
|
waylandOutputModeListener, // mode
|
||||||
stubListener, // done
|
ffWaylandStubListener, // done
|
||||||
waylandOutputScaleListener, // scale
|
waylandOutputScaleListener, // scale
|
||||||
ffWaylandOutputNameListener, // name
|
ffWaylandOutputNameListener, // name
|
||||||
ffWaylandOutputDescriptionListener, // description
|
ffWaylandOutputDescriptionListener, // description
|
||||||
@@ -64,9 +64,9 @@ static_assert(
|
|||||||
"sizeof(outputListener) is too small. Please report it to fastfetch github issue");
|
"sizeof(outputListener) is too small. Please report it to fastfetch github issue");
|
||||||
|
|
||||||
static struct zxdg_output_v1_listener zxdgOutputListener = {
|
static struct zxdg_output_v1_listener zxdgOutputListener = {
|
||||||
.logical_position = (void*) stubListener,
|
.logical_position = (void*) ffWaylandStubListener,
|
||||||
.logical_size = handleXdgLogicalSize,
|
.logical_size = handleXdgLogicalSize,
|
||||||
.done = (void*) stubListener,
|
.done = (void*) ffWaylandStubListener,
|
||||||
.name = (void*) ffWaylandOutputNameListener,
|
.name = (void*) ffWaylandOutputNameListener,
|
||||||
.description = (void*) ffWaylandOutputDescriptionListener,
|
.description = (void*) ffWaylandOutputDescriptionListener,
|
||||||
};
|
};
|
||||||
@@ -84,17 +84,17 @@ static void handleWpTfNamed(void *data, FF_A_UNUSED struct wp_image_description_
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct wp_image_description_info_v1_listener wpImageDescInfoListener = {
|
static const struct wp_image_description_info_v1_listener wpImageDescInfoListener = {
|
||||||
.done = (void*) stubListener,
|
.done = (void*) ffWaylandStubListener,
|
||||||
.icc_file = (void*) stubListener,
|
.icc_file = (void*) ffWaylandStubListener,
|
||||||
.primaries = (void*) stubListener,
|
.primaries = (void*) ffWaylandStubListener,
|
||||||
.primaries_named = (void*) stubListener,
|
.primaries_named = (void*) ffWaylandStubListener,
|
||||||
.tf_power = (void*) stubListener,
|
.tf_power = (void*) ffWaylandStubListener,
|
||||||
.tf_named = (void*) handleWpTfNamed,
|
.tf_named = (void*) handleWpTfNamed,
|
||||||
.luminances = (void*) stubListener,
|
.luminances = (void*) ffWaylandStubListener,
|
||||||
.target_primaries = (void*) stubListener,
|
.target_primaries = (void*) ffWaylandStubListener,
|
||||||
.target_luminance = (void*) stubListener,
|
.target_luminance = (void*) ffWaylandStubListener,
|
||||||
.target_max_cll = (void*) stubListener,
|
.target_max_cll = (void*) ffWaylandStubListener,
|
||||||
.target_max_fall = (void*) stubListener,
|
.target_max_fall = (void*) ffWaylandStubListener,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) {
|
const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) {
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ static const struct kde_output_device_mode_v2_listener modeListener = {
|
|||||||
.size = waylandKdeModeSizeListener,
|
.size = waylandKdeModeSizeListener,
|
||||||
.refresh = waylandKdeModeRefreshListener,
|
.refresh = waylandKdeModeRefreshListener,
|
||||||
.preferred = waylandKdeModePreferredListener,
|
.preferred = waylandKdeModePreferredListener,
|
||||||
.removed = (void*) stubListener,
|
.removed = (void*) ffWaylandStubListener,
|
||||||
.flags = (void*) stubListener,
|
.flags = (void*) ffWaylandStubListener,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void waylandKdeModeListener(void* data, FF_A_UNUSED struct kde_output_device_v2* _, struct kde_output_device_mode_v2* mode) {
|
static void waylandKdeModeListener(void* data, FF_A_UNUSED struct kde_output_device_v2* _, struct kde_output_device_mode_v2* mode) {
|
||||||
@@ -57,23 +57,22 @@ static void waylandKdeCurrentModeListener(void* data, FF_A_UNUSED struct kde_out
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int set = 0;
|
bool foundCurrent = false, foundPreferred = false;
|
||||||
FF_LIST_FOR_EACH (WaylandKdeMode, m, *(FFlist*) wldata->internal) {
|
FF_LIST_FOR_EACH (WaylandKdeMode, m, *(FFlist*) wldata->internal) {
|
||||||
if (m->pMode == mode) {
|
if (!foundCurrent && m->pMode == mode) {
|
||||||
wldata->width = m->width;
|
wldata->width = m->width;
|
||||||
wldata->height = m->height;
|
wldata->height = m->height;
|
||||||
wldata->refreshRate = m->refreshRate;
|
wldata->refreshRate = m->refreshRate;
|
||||||
if (++set == 2) {
|
foundCurrent = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (m->preferred) {
|
if (!foundPreferred && m->preferred) {
|
||||||
wldata->preferredWidth = m->width;
|
wldata->preferredWidth = m->width;
|
||||||
wldata->preferredHeight = m->height;
|
wldata->preferredHeight = m->height;
|
||||||
wldata->preferredRefreshRate = m->refreshRate;
|
wldata->preferredRefreshRate = m->refreshRate;
|
||||||
if (++set == 2) {
|
foundPreferred = true;
|
||||||
break;
|
}
|
||||||
}
|
if (foundCurrent && foundPreferred) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,43 +150,43 @@ static struct kde_output_device_v2_listener outputListener = {
|
|||||||
.geometry = waylandKdeGeometryListener,
|
.geometry = waylandKdeGeometryListener,
|
||||||
.current_mode = waylandKdeCurrentModeListener,
|
.current_mode = waylandKdeCurrentModeListener,
|
||||||
.mode = waylandKdeModeListener,
|
.mode = waylandKdeModeListener,
|
||||||
.done = (void*) stubListener,
|
.done = (void*) ffWaylandStubListener,
|
||||||
.scale = waylandKdeScaleListener,
|
.scale = waylandKdeScaleListener,
|
||||||
.edid = waylandKdeEdidListener,
|
.edid = waylandKdeEdidListener,
|
||||||
.enabled = waylandKdeEnabledListener,
|
.enabled = waylandKdeEnabledListener,
|
||||||
.uuid = (void*) stubListener,
|
.uuid = (void*) ffWaylandStubListener,
|
||||||
.serial_number = (void*) stubListener,
|
.serial_number = (void*) ffWaylandStubListener,
|
||||||
.eisa_id = (void*) stubListener,
|
.eisa_id = (void*) ffWaylandStubListener,
|
||||||
.capabilities = (void*) stubListener,
|
.capabilities = (void*) ffWaylandStubListener,
|
||||||
.overscan = (void*) stubListener,
|
.overscan = (void*) ffWaylandStubListener,
|
||||||
.vrr_policy = (void*) stubListener,
|
.vrr_policy = (void*) ffWaylandStubListener,
|
||||||
.rgb_range = (void*) stubListener,
|
.rgb_range = (void*) ffWaylandStubListener,
|
||||||
.name = waylandKdeNameListener,
|
.name = waylandKdeNameListener,
|
||||||
.high_dynamic_range = waylandKdeHdrListener,
|
.high_dynamic_range = waylandKdeHdrListener,
|
||||||
.sdr_brightness = (void*) stubListener,
|
.sdr_brightness = (void*) ffWaylandStubListener,
|
||||||
.wide_color_gamut = (void*) stubListener,
|
.wide_color_gamut = (void*) ffWaylandStubListener,
|
||||||
.auto_rotate_policy = (void*) stubListener,
|
.auto_rotate_policy = (void*) ffWaylandStubListener,
|
||||||
.icc_profile_path = (void*) stubListener,
|
.icc_profile_path = (void*) ffWaylandStubListener,
|
||||||
.brightness_metadata = (void*) stubListener,
|
.brightness_metadata = (void*) ffWaylandStubListener,
|
||||||
.brightness_overrides = (void*) stubListener,
|
.brightness_overrides = (void*) ffWaylandStubListener,
|
||||||
.sdr_gamut_wideness = (void*) stubListener,
|
.sdr_gamut_wideness = (void*) ffWaylandStubListener,
|
||||||
.color_profile_source = (void*) stubListener,
|
.color_profile_source = (void*) ffWaylandStubListener,
|
||||||
.brightness = (void*) stubListener,
|
.brightness = (void*) ffWaylandStubListener,
|
||||||
.color_power_tradeoff = (void*) stubListener,
|
.color_power_tradeoff = (void*) ffWaylandStubListener,
|
||||||
.dimming = (void*) stubListener,
|
.dimming = (void*) ffWaylandStubListener,
|
||||||
.replication_source = (void*) stubListener,
|
.replication_source = (void*) ffWaylandStubListener,
|
||||||
.ddc_ci_allowed = (void*) stubListener,
|
.ddc_ci_allowed = (void*) ffWaylandStubListener,
|
||||||
.max_bits_per_color = (void*) waylandKdeMaxBitsPerColorListener,
|
.max_bits_per_color = (void*) waylandKdeMaxBitsPerColorListener,
|
||||||
.max_bits_per_color_range = (void*) stubListener,
|
.max_bits_per_color_range = (void*) ffWaylandStubListener,
|
||||||
.automatic_max_bits_per_color_limit = (void*) stubListener,
|
.automatic_max_bits_per_color_limit = (void*) ffWaylandStubListener,
|
||||||
.edr_policy = (void*) stubListener,
|
.edr_policy = (void*) ffWaylandStubListener,
|
||||||
.sharpness = (void*) stubListener,
|
.sharpness = (void*) ffWaylandStubListener,
|
||||||
.priority = waylandKdePriorityListener,
|
.priority = waylandKdePriorityListener,
|
||||||
.auto_brightness = (void*) stubListener,
|
.auto_brightness = (void*) ffWaylandStubListener,
|
||||||
.removed = (void*) stubListener,
|
.removed = (void*) ffWaylandStubListener,
|
||||||
.hdr_icc_profile_path = (void*) stubListener,
|
.hdr_icc_profile_path = (void*) ffWaylandStubListener,
|
||||||
.hdr_color_profile_source = (void*) stubListener,
|
.hdr_color_profile_source = (void*) ffWaylandStubListener,
|
||||||
.abm_level = (void*) stubListener,
|
.abm_level = (void*) ffWaylandStubListener,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* waylandKdeHandleOutput(WaylandData* wldata, struct wl_proxy* output) {
|
static const char* waylandKdeHandleOutput(WaylandData* wldata, struct wl_proxy* output) {
|
||||||
@@ -288,7 +287,7 @@ static void waylandKdeOutputListener(void* data, FF_A_UNUSED struct kde_output_d
|
|||||||
|
|
||||||
static struct kde_output_device_registry_v2_listener registryListener = {
|
static struct kde_output_device_registry_v2_listener registryListener = {
|
||||||
.output = waylandKdeOutputListener,
|
.output = waylandKdeOutputListener,
|
||||||
.finished = (void*) stubListener,
|
.finished = (void*) ffWaylandStubListener,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* ffWaylandHandleKdeOutputRegistry(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) {
|
const char* ffWaylandHandleKdeOutputRegistry(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) {
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ const char* ffdsConnectWayland(FFDisplayServerResult* result) {
|
|||||||
|
|
||||||
struct wl_registry_listener registry_listener = {
|
struct wl_registry_listener registry_listener = {
|
||||||
.global = waylandGlobalAddListener,
|
.global = waylandGlobalAddListener,
|
||||||
.global_remove = (void*) stubListener
|
.global_remove = (void*) ffWaylandStubListener
|
||||||
};
|
};
|
||||||
|
|
||||||
data.ffwl_proxy_add_listener(registry, (void (**)(void)) ®istry_listener, &data);
|
data.ffwl_proxy_add_listener(registry, (void (**)(void)) ®istry_listener, &data);
|
||||||
@@ -339,6 +339,10 @@ const char* ffdsConnectWayland(FFDisplayServerResult* result) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ffWaylandStubListener(void* data, ...) {
|
||||||
|
FF_UNUSED(data);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
const char* ffdsConnectWayland(FF_A_UNUSED FFDisplayServerResult* result) {
|
const char* ffdsConnectWayland(FF_A_UNUSED FFDisplayServerResult* result) {
|
||||||
|
|||||||
@@ -60,9 +60,7 @@ typedef struct WaylandDisplay {
|
|||||||
bool primary;
|
bool primary;
|
||||||
} WaylandDisplay;
|
} WaylandDisplay;
|
||||||
|
|
||||||
inline static void stubListener(void* data, ...) {
|
void ffWaylandStubListener(void* data, ...);
|
||||||
(void) data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static uint64_t ffWaylandGenerateIdFromName(const char* name) {
|
inline static uint64_t ffWaylandGenerateIdFromName(const char* name) {
|
||||||
uint64_t id = 0;
|
uint64_t id = 0;
|
||||||
|
|||||||
@@ -70,8 +70,7 @@ const char* ffDetectNetIO(FFlist* result, FFNetIOOptions* options) {
|
|||||||
uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off);
|
uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off);
|
||||||
uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off);
|
uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off);
|
||||||
uint64_t temp = *currValue;
|
uint64_t temp = *currValue;
|
||||||
*currValue -= *prevValue;
|
*currValue = (*currValue - *prevValue) * 1000 / (time2 - time1); // Calculate per second
|
||||||
*currValue /= (time2 - time1) / 1000 /* seconds */;
|
|
||||||
*prevValue = temp;
|
*prevValue = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ FF_A_UNUSED static bool getUbuntuFlavour(FFOSResult* result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// xdgConfigDirs contains plasma only
|
// xdgConfigDirs contains plasma only
|
||||||
if (ffPathExists("/var/lib/dpkg/info/ubuntustudio-desktop.list", FF_PATHTYPE_FILE)) {
|
// `ubuntustudio-desktop-core` is installed on both the full and core installations
|
||||||
|
if (ffPathExists("/var/lib/dpkg/info/ubuntustudio-desktop-core.list", FF_PATHTYPE_FILE)) {
|
||||||
ffStrbufSetStatic(&result->name, "Ubuntu Studio");
|
ffStrbufSetStatic(&result->name, "Ubuntu Studio");
|
||||||
ffStrbufSetStatic(&result->id, "ubuntu-studio");
|
ffStrbufSetStatic(&result->id, "ubuntu-studio");
|
||||||
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
ffStrbufSetStatic(&result->idLike, "ubuntu");
|
||||||
|
|||||||
@@ -34,9 +34,8 @@ void ffPreparePublicIp(FFPublicIPOptions* options) {
|
|||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||||
if (pathStartIndex != host.length) {
|
if (pathStartIndex != host.length) {
|
||||||
ffStrbufAppendNS(&path, pathStartIndex, host.chars + (host.length - pathStartIndex));
|
ffStrbufAppendNS(&path, host.length - pathStartIndex, host.chars + pathStartIndex);
|
||||||
host.length = pathStartIndex;
|
ffStrbufSubstrBefore(&host, pathStartIndex);
|
||||||
host.chars[pathStartIndex] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*status = ffNetworkingSendHttpRequest(state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
|
*status = ffNetworkingSendHttpRequest(state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
|
||||||
|
|||||||
@@ -89,7 +89,14 @@ static bool getShellVersionFish(FFstrbuf* exe, FFstrbuf* version) {
|
|||||||
if (version->length < strlen("fish, v") || !ffStrbufStartsWithS(version, "fish")) {
|
if (version->length < strlen("fish, v") || !ffStrbufStartsWithS(version, "fish")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t index = ffStrbufNextIndexC(version, strlen("fish, "), ' ');
|
uint32_t index = ffStrbufFirstIndexC(version, ' '); // skip "fish,"
|
||||||
|
while (index + 1 < version->length && !ffCharIsDigit(version->chars[index + 1])) {
|
||||||
|
index = ffStrbufNextIndexC(version, index + 1, ' '); // skip "version"
|
||||||
|
}
|
||||||
|
if (index + 1 >= version->length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ffStrbufSubstrAfter(version, index);
|
ffStrbufSubstrAfter(version, index);
|
||||||
ffStrbufSubstrBeforeFirstC(version, ' ');
|
ffStrbufSubstrBeforeFirstC(version, ' ');
|
||||||
return true;
|
return true;
|
||||||
@@ -187,6 +194,9 @@ static bool extractBusyboxVersion(const char* line, uint32_t len, void* userdata
|
|||||||
|
|
||||||
static bool getShellVersionAsh(FFstrbuf* exe, FFstrbuf* version) {
|
static bool getShellVersionAsh(FFstrbuf* exe, FFstrbuf* version) {
|
||||||
ffBinaryExtractStrings(exe->chars, extractBusyboxVersion, version, (uint32_t) strlen("BusyBox v0.0.0"));
|
ffBinaryExtractStrings(exe->chars, extractBusyboxVersion, version, (uint32_t) strlen("BusyBox v0.0.0"));
|
||||||
|
if (version->length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const char* error = ffStrbufEndsWithS(exe, "busybox")
|
const char* error = ffStrbufEndsWithS(exe, "busybox")
|
||||||
? ffProcessAppendStdErr(version, (char* const[]) { exe->chars, "ash", "--help", NULL })
|
? ffProcessAppendStdErr(version, (char* const[]) { exe->chars, "ash", "--help", NULL })
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ static const char* status = FF_UNITIALIZED;
|
|||||||
|
|
||||||
void ffPrepareWeather(FFWeatherOptions* options) {
|
void ffPrepareWeather(FFWeatherOptions* options) {
|
||||||
if (status != FF_UNITIALIZED) {
|
if (status != FF_UNITIALIZED) {
|
||||||
fputs("Error: Weather module can only be used once due to internal limitations\n", stderr);
|
status = "Weather module can only be used once due to internal limitations";
|
||||||
exit(1);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.timeout = options->timeout;
|
state.timeout = options->timeout;
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ typedef struct FFstate {
|
|||||||
uint32_t logoWidth;
|
uint32_t logoWidth;
|
||||||
uint32_t logoHeight;
|
uint32_t logoHeight;
|
||||||
uint32_t keysHeight;
|
uint32_t keysHeight;
|
||||||
bool terminalLightTheme;
|
|
||||||
bool titleFqdn;
|
bool titleFqdn;
|
||||||
uint32_t dynamicInterval;
|
uint32_t dynamicInterval;
|
||||||
FFPlatform platform;
|
FFPlatform platform;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ bool ffPrintCamera(FFCameraOptions* options) {
|
|||||||
|
|
||||||
FF_LIST_FOR_EACH (FFCameraResult, dev, result) {
|
FF_LIST_FOR_EACH (FFCameraResult, dev, result) {
|
||||||
ffStrbufDestroy(&dev->name);
|
ffStrbufDestroy(&dev->name);
|
||||||
|
ffStrbufDestroy(&dev->vendor);
|
||||||
ffStrbufDestroy(&dev->id);
|
ffStrbufDestroy(&dev->id);
|
||||||
ffStrbufDestroy(&dev->colorspace);
|
ffStrbufDestroy(&dev->colorspace);
|
||||||
}
|
}
|
||||||
@@ -99,6 +100,7 @@ bool ffGenerateCameraJsonResult(FF_A_UNUSED FFCameraOptions* options, yyjson_mut
|
|||||||
|
|
||||||
FF_LIST_FOR_EACH (FFCameraResult, dev, result) {
|
FF_LIST_FOR_EACH (FFCameraResult, dev, result) {
|
||||||
ffStrbufDestroy(&dev->name);
|
ffStrbufDestroy(&dev->name);
|
||||||
|
ffStrbufDestroy(&dev->vendor);
|
||||||
ffStrbufDestroy(&dev->id);
|
ffStrbufDestroy(&dev->id);
|
||||||
ffStrbufDestroy(&dev->colorspace);
|
ffStrbufDestroy(&dev->colorspace);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ void ffInitSeparatorOptions(FFSeparatorOptions* options) {
|
|||||||
|
|
||||||
void ffDestroySeparatorOptions(FFSeparatorOptions* options) {
|
void ffDestroySeparatorOptions(FFSeparatorOptions* options) {
|
||||||
ffStrbufDestroy(&options->string);
|
ffStrbufDestroy(&options->string);
|
||||||
|
ffStrbufDestroy(&options->outputColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
FFModuleBaseInfo ffSeparatorModuleInfo = {
|
FFModuleBaseInfo ffSeparatorModuleInfo = {
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ void ffInitWeatherOptions(FFWeatherOptions* options) {
|
|||||||
void ffDestroyWeatherOptions(FFWeatherOptions* options) {
|
void ffDestroyWeatherOptions(FFWeatherOptions* options) {
|
||||||
ffOptionDestroyModuleArg(&options->moduleArgs);
|
ffOptionDestroyModuleArg(&options->moduleArgs);
|
||||||
|
|
||||||
|
ffStrbufDestroy(&options->location);
|
||||||
ffStrbufDestroy(&options->outputFormat);
|
ffStrbufDestroy(&options->outputFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-7
@@ -5,6 +5,10 @@
|
|||||||
#include "common/strutil.h"
|
#include "common/strutil.h"
|
||||||
#include "options/display.h"
|
#include "options/display.h"
|
||||||
|
|
||||||
|
#if !FF_MODULE_DISABLE_TERMINALTHEME
|
||||||
|
#include "detection/terminaltheme/terminaltheme.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_val* root, yyjson_val** pkey) {
|
const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_val* root, yyjson_val** pkey) {
|
||||||
@@ -825,11 +829,22 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
||||||
|
bool terminalLightTheme = false;
|
||||||
|
#if !FF_MODULE_DISABLE_TERMINALTHEME
|
||||||
|
{
|
||||||
|
// don't enable bright color if the terminal is in light mode
|
||||||
|
FFTerminalThemeResult result;
|
||||||
|
if (ffDetectTerminalTheme(&result, true /* forceEnv for performance */) && !result.bg.dark) {
|
||||||
|
terminalLightTheme = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ffStrbufInit(&options->colorKeys);
|
ffStrbufInit(&options->colorKeys);
|
||||||
ffStrbufInit(&options->colorTitle);
|
ffStrbufInit(&options->colorTitle);
|
||||||
ffStrbufInit(&options->colorOutput);
|
ffStrbufInit(&options->colorOutput);
|
||||||
ffStrbufInit(&options->colorSeparator);
|
ffStrbufInit(&options->colorSeparator);
|
||||||
options->brightColor = !instance.state.terminalLightTheme;
|
options->brightColor = !terminalLightTheme;
|
||||||
ffStrbufInitStatic(&options->keyValueSeparator, ": ");
|
ffStrbufInitStatic(&options->keyValueSeparator, ": ");
|
||||||
|
|
||||||
options->showErrors = false;
|
options->showErrors = false;
|
||||||
@@ -856,8 +871,8 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
|||||||
options->tempUnit = FF_TEMPERATURE_UNIT_DEFAULT;
|
options->tempUnit = FF_TEMPERATURE_UNIT_DEFAULT;
|
||||||
options->tempNdigits = 1;
|
options->tempNdigits = 1;
|
||||||
ffStrbufInitStatic(&options->tempColorGreen, FF_COLOR_FG_GREEN);
|
ffStrbufInitStatic(&options->tempColorGreen, FF_COLOR_FG_GREEN);
|
||||||
ffStrbufInitStatic(&options->tempColorYellow, instance.state.terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
ffStrbufInitStatic(&options->tempColorYellow, terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
||||||
ffStrbufInitStatic(&options->tempColorRed, instance.state.terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
ffStrbufInitStatic(&options->tempColorRed, terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
||||||
options->tempSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
|
options->tempSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
|
||||||
|
|
||||||
ffStrbufInitStatic(&options->barCharElapsed, "■");
|
ffStrbufInitStatic(&options->barCharElapsed, "■");
|
||||||
@@ -867,8 +882,8 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
|||||||
ffStrbufInit(&options->barBorderLeftElapsed);
|
ffStrbufInit(&options->barBorderLeftElapsed);
|
||||||
ffStrbufInit(&options->barBorderRightElapsed);
|
ffStrbufInit(&options->barBorderRightElapsed);
|
||||||
ffStrbufInitStatic(&options->barColorElapsed, "auto");
|
ffStrbufInitStatic(&options->barColorElapsed, "auto");
|
||||||
ffStrbufInitStatic(&options->barColorTotal, instance.state.terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
ffStrbufInitStatic(&options->barColorTotal, terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
||||||
ffStrbufInitStatic(&options->barColorBorder, instance.state.terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
ffStrbufInitStatic(&options->barColorBorder, terminalLightTheme ? FF_COLOR_FG_WHITE : FF_COLOR_FG_LIGHT_WHITE);
|
||||||
options->barWidth = 10;
|
options->barWidth = 10;
|
||||||
|
|
||||||
options->durationAbbreviation = false;
|
options->durationAbbreviation = false;
|
||||||
@@ -876,8 +891,8 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options) {
|
|||||||
options->percentType = FF_PERCENTAGE_TYPE_NUM_BIT | FF_PERCENTAGE_TYPE_NUM_COLOR_BIT;
|
options->percentType = FF_PERCENTAGE_TYPE_NUM_BIT | FF_PERCENTAGE_TYPE_NUM_COLOR_BIT;
|
||||||
options->percentNdigits = 0;
|
options->percentNdigits = 0;
|
||||||
ffStrbufInitStatic(&options->percentColorGreen, FF_COLOR_FG_GREEN);
|
ffStrbufInitStatic(&options->percentColorGreen, FF_COLOR_FG_GREEN);
|
||||||
ffStrbufInitStatic(&options->percentColorYellow, instance.state.terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
ffStrbufInitStatic(&options->percentColorYellow, terminalLightTheme ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_LIGHT_YELLOW);
|
||||||
ffStrbufInitStatic(&options->percentColorRed, instance.state.terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
ffStrbufInitStatic(&options->percentColorRed, terminalLightTheme ? FF_COLOR_FG_RED : FF_COLOR_FG_LIGHT_RED);
|
||||||
options->percentSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
|
options->percentSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
|
||||||
options->percentWidth = 0;
|
options->percentWidth = 0;
|
||||||
|
|
||||||
@@ -897,6 +912,19 @@ void ffOptionsDestroyDisplay(FFOptionsDisplay* options) {
|
|||||||
ffStrbufDestroy(&options->keyValueSeparator);
|
ffStrbufDestroy(&options->keyValueSeparator);
|
||||||
ffStrbufDestroy(&options->barCharElapsed);
|
ffStrbufDestroy(&options->barCharElapsed);
|
||||||
ffStrbufDestroy(&options->barCharTotal);
|
ffStrbufDestroy(&options->barCharTotal);
|
||||||
|
ffStrbufDestroy(&options->barBorderLeft);
|
||||||
|
ffStrbufDestroy(&options->barBorderRight);
|
||||||
|
ffStrbufDestroy(&options->barBorderLeftElapsed);
|
||||||
|
ffStrbufDestroy(&options->barBorderRightElapsed);
|
||||||
|
ffStrbufDestroy(&options->barColorElapsed);
|
||||||
|
ffStrbufDestroy(&options->barColorTotal);
|
||||||
|
ffStrbufDestroy(&options->barColorBorder);
|
||||||
|
ffStrbufDestroy(&options->tempColorGreen);
|
||||||
|
ffStrbufDestroy(&options->tempColorYellow);
|
||||||
|
ffStrbufDestroy(&options->tempColorRed);
|
||||||
|
ffStrbufDestroy(&options->percentColorGreen);
|
||||||
|
ffStrbufDestroy(&options->percentColorYellow);
|
||||||
|
ffStrbufDestroy(&options->percentColorRed);
|
||||||
FF_LIST_FOR_EACH (FFstrbuf, item, options->constants) {
|
FF_LIST_FOR_EACH (FFstrbuf, item, options->constants) {
|
||||||
ffStrbufDestroy(item);
|
ffStrbufDestroy(item);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -414,7 +414,7 @@ int main(void) {
|
|||||||
ffStrbufInit(&strbuf);
|
ffStrbufInit(&strbuf);
|
||||||
ffStrbufEnsureFixedLengthFree(&strbuf, 0);
|
ffStrbufEnsureFixedLengthFree(&strbuf, 0);
|
||||||
VERIFY(strbuf.length == 0);
|
VERIFY(strbuf.length == 0);
|
||||||
VERIFY(strbuf.allocated == 0);
|
VERIFY(strbuf.allocated == 1);
|
||||||
ffStrbufDestroy(&strbuf);
|
ffStrbufDestroy(&strbuf);
|
||||||
|
|
||||||
// ffStrbufEnsureFixedLengthFree / empty buffer but oldFree >= newFree
|
// ffStrbufEnsureFixedLengthFree / empty buffer but oldFree >= newFree
|
||||||
|
|||||||
Reference in New Issue
Block a user