From bed1b4cf0f952e6e5963242911352cef43f8c9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 25 Oct 2023 13:39:13 +0800 Subject: [PATCH] Global: move general options to a new separate folder --- CHANGELOG.md | 3 + CMakeLists.txt | 1 + doc/json_schema.json | 20 +- src/common/commandoption.c | 2 +- src/common/init.c | 20 +- src/common/jsonconfig.c | 62 +- src/common/jsonconfig.h | 1 - src/common/processing_linux.c | 2 +- src/common/processing_windows.c | 2 +- src/detection/battery/battery_windows.c | 2 +- src/detection/chassis/chassis_windows.cpp | 2 +- .../displayserver/displayserver_apple.c | 2 +- .../displayserver/linux/displayserver_linux.c | 2 +- src/detection/displayserver/linux/wmde.c | 8 +- src/detection/media/media_linux.c | 4 +- src/detection/os/os_linux.c | 6 +- src/detection/packages/packages_windows.c | 2 +- src/detection/terminalfont/terminalfont.c | 2 +- src/detection/vulkan/vulkan.c | 2 +- src/fastfetch.c | 53 +- src/fastfetch.h | 19 +- src/logo/option.c | 560 ------------------ src/logo/option.h | 46 -- src/options/general.c | 98 +++ src/options/general.h | 25 + src/options/logo.c | 8 +- src/options/logo.h | 2 +- src/util/windows/wmi.hpp | 2 +- 28 files changed, 195 insertions(+), 763 deletions(-) delete mode 100644 src/logo/option.c delete mode 100644 src/logo/option.h create mode 100644 src/options/general.c create mode 100644 src/options/general.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c58a2ac0..9db77642c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # 2.2.0 +Changes: +* `--pipe` and `--stat` are moved from `general` options to `display` options. This affects cjson configuration. + Features: * Quirks for MIPS platforms (CPU, Linux) * Use devicetree path for OBP hosts (Host, Linux) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0239cdbc0..243172947 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,7 @@ set(LIBFASTFETCH_SRC src/modules/wm/wm.c src/modules/wmtheme/wmtheme.c src/options/logo.c + src/options/general.c src/util/edidHelper.c src/util/FFlist.c src/util/FFstrbuf.c diff --git a/doc/json_schema.json b/doc/json_schema.json index e309dee87..b099900da 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -242,21 +242,11 @@ "title": "Alias of multithreading", "default": true }, - "stat": { - "type": "boolean", - "title": "Show time usage (in ms) for individual modules", - "default": false - }, "escapeBedrock": { "type": "boolean", "title": "On Bedrock Linux, whether to escape the bedrock jail", "default": true }, - "pipe": { - "type": "boolean", - "title": "Whether to enable pipe mode (disable logo and all escape sequences)", - "default": false - }, "playerName": { "type": "string", "title": "The name of the player to use for module Media and Player. Linux only" @@ -287,6 +277,16 @@ "title": "Configure how things to be displayed", "type": "object", "properties": { + "stat": { + "type": "boolean", + "title": "Show time usage (in ms) for individual modules", + "default": false + }, + "pipe": { + "type": "boolean", + "title": "Whether to enable pipe mode (disable logo and all escape sequences)", + "default": false + }, "showErrors": { "type": "boolean", "title": "Print occurring errors to the console. False to ignore errored modules", diff --git a/src/common/commandoption.c b/src/common/commandoption.c index 727292fa2..ab3ac56da 100644 --- a/src/common/commandoption.c +++ b/src/common/commandoption.c @@ -87,7 +87,7 @@ void ffPrepareCommandOption(FFdata* data) if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME)) ffPrepareNetIO(&instance.config.netIo); - if(instance.config.multithreading) + if(instance.config.general.multithreading) { if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME)) ffPreparePublicIp(&instance.config.publicIP); diff --git a/src/common/init.c b/src/common/init.c index bfabc8129..84efec1db 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -33,23 +33,14 @@ static void initState(FFstate* state) static void defaultConfig(void) { ffInitLogoOptions(&instance.config.logo); + ffInitGeneralOptions(&instance.config.general); ffStrbufInit(&instance.config.colorKeys); ffStrbufInit(&instance.config.colorTitle); instance.config.brightColor = true; ffStrbufInitStatic(&instance.config.keyValueSeparator, ": "); - instance.config.processingTimeout = 1000; - - #if defined(__linux__) || defined(__FreeBSD__) - ffStrbufInit(&instance.config.playerName); - ffStrbufInit(&instance.config.osFile); - instance.config.dsForceDrm = false; - #elif defined(_WIN32) - instance.config.wmiTimeout = 5000; - #endif instance.config.showErrors = false; - instance.config.allowSlowOperations = false; instance.config.pipe = !isatty(STDOUT_FILENO); #ifdef NDEBUG @@ -60,12 +51,10 @@ static void defaultConfig(void) instance.config.hideCursor = false; #endif - instance.config.escapeBedrock = true; instance.config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC; instance.config.sizeNdigits = 2; instance.config.sizeMaxPrefix = UINT8_MAX; instance.config.temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS; - instance.config.multithreading = true; instance.config.stat = false; instance.config.noBuffer = false; instance.config.keyWidth = 0; @@ -233,7 +222,7 @@ static void exitSignalHandler(int signal) void ffStart(void) { #ifdef FF_START_DETECTION_THREADS - if(instance.config.multithreading) + if(instance.config.general.multithreading) startDetectionThreads(); #endif @@ -287,11 +276,6 @@ static void destroyConfig(void) ffStrbufDestroy(&instance.config.barCharElapsed); ffStrbufDestroy(&instance.config.barCharTotal); - #if defined(__linux__) || defined(__FreeBSD__) - ffStrbufDestroy(&instance.config.playerName); - ffStrbufDestroy(&instance.config.osFile); - #endif - ffDestroyBatteryOptions(&instance.config.battery); ffDestroyBiosOptions(&instance.config.bios); ffDestroyBluetoothOptions(&instance.config.bluetooth); diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c index f4ef9bc75..f3f240fef 100644 --- a/src/common/jsonconfig.c +++ b/src/common/jsonconfig.c @@ -227,59 +227,6 @@ static const char* printJsonConfig(bool prepare) return NULL; } -const char* ffParseGeneralJsonConfig(FFconfig* config) -{ - yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); - assert(root); - - if (!yyjson_is_obj(root)) - return "Invalid JSON config format. Root value must be an object"; - - yyjson_val* object = yyjson_obj_get(root, "general"); - if (!object) return NULL; - if (!yyjson_is_obj(object)) return "Property 'general' must be an object"; - - yyjson_val *key_, *val; - size_t idx, max; - yyjson_obj_foreach(object, idx, max, key_, val) - { - const char* key = yyjson_get_str(key_); - - if (ffStrEqualsIgnCase(key, "allowSlowOperations")) - config->allowSlowOperations = yyjson_get_bool(val); - else if (ffStrEqualsIgnCase(key, "thread") || ffStrEqualsIgnCase(key, "multithreading")) - config->multithreading = yyjson_get_bool(val); - else if (ffStrEqualsIgnCase(key, "stat")) - { - if ((config->stat = yyjson_get_bool(val))) - config->showErrors = true; - } - else if (ffStrEqualsIgnCase(key, "escapeBedrock")) - config->escapeBedrock = yyjson_get_bool(val); - else if (ffStrEqualsIgnCase(key, "pipe")) - config->pipe = yyjson_get_bool(val); - else if (ffStrEqualsIgnCase(key, "processingTimeout")) - config->processingTimeout = (int32_t) yyjson_get_int(val); - - #if defined(__linux__) || defined(__FreeBSD__) - else if (ffStrEqualsIgnCase(key, "playerName")) - ffStrbufSetS(&config->playerName, yyjson_get_str(val)); - else if (ffStrEqualsIgnCase(key, "osFile")) - ffStrbufSetS(&config->osFile, yyjson_get_str(val)); - else if (ffStrEqualsIgnCase(key, "dsForceDrm")) - config->dsForceDrm = yyjson_get_bool(val); - #elif defined(_WIN32) - else if (ffStrEqualsIgnCase(key, "wmiTimeout")) - config->wmiTimeout = (int32_t) yyjson_get_int(val); - #endif - - else - return "Unknown general property"; - } - - return NULL; -} - const char* ffParseDisplayJsonConfig(FFconfig* config) { yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); @@ -298,7 +245,14 @@ const char* ffParseDisplayJsonConfig(FFconfig* config) { const char* key = yyjson_get_str(key_); - if (ffStrEqualsIgnCase(key, "showErrors")) + if (ffStrEqualsIgnCase(key, "stat")) + { + if ((config->stat = yyjson_get_bool(val))) + config->showErrors = true; + } + else if (ffStrEqualsIgnCase(key, "pipe")) + config->pipe = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "showErrors")) config->showErrors = yyjson_get_bool(val); else if (ffStrEqualsIgnCase(key, "disableLinewrap")) config->disableLinewrap = yyjson_get_bool(val); diff --git a/src/common/jsonconfig.h b/src/common/jsonconfig.h index f7546f174..6103d7337 100644 --- a/src/common/jsonconfig.h +++ b/src/common/jsonconfig.h @@ -5,7 +5,6 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs); const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]); void ffPrintJsonConfig(bool prepare); -const char* ffParseGeneralJsonConfig(FFconfig* config); const char* ffParseDisplayJsonConfig(FFconfig* config); const char* ffParseLibraryJsonConfig(FFconfig* config); void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs); diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index 84bc79cec..b96a2ff85 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -48,7 +48,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use int FF_AUTO_CLOSE_FD childPipeFd = pipes[0]; - int timeout = instance.config.processingTimeout; + int timeout = instance.config.general.processingTimeout; if (timeout >= 0) fcntl(childPipeFd, F_SETFL, fcntl(childPipeFd, F_GETFL) | O_NONBLOCK); diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 6355a3a1f..5f44d5210 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -8,7 +8,7 @@ enum { FF_PIPE_BUFSIZ = 4096 }; const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr) { - int timeout = instance.config.processingTimeout; + int timeout = instance.config.general.processingTimeout; FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW( L"\\\\.\\pipe\\LOCAL\\", diff --git a/src/detection/battery/battery_windows.c b/src/detection/battery/battery_windows.c index 056bfd06a..e75baccbc 100644 --- a/src/detection/battery/battery_windows.c +++ b/src/detection/battery/battery_windows.c @@ -32,7 +32,7 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev) const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results) { - if(instance.config.allowSlowOperations) + if(instance.config.general.allowSlowOperations) { //https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) = diff --git a/src/detection/chassis/chassis_windows.cpp b/src/detection/chassis/chassis_windows.cpp index 2332c5b31..05fe63ad1 100644 --- a/src/detection/chassis/chassis_windows.cpp +++ b/src/detection/chassis/chassis_windows.cpp @@ -67,7 +67,7 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result) extern "C" const char* ffDetectChassis(FFChassisResult* result) { - if (instance.config.allowSlowOperations) + if (instance.config.general.allowSlowOperations) return detectWithWmi(result); return detectWithRegistry(result); } diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index dfd2fe77f..1bc386c52 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -116,7 +116,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) } ffStrbufInit(&ds->wmProtocolName); - if(instance.config.allowSlowOperations) + if(instance.config.general.allowSlowOperations) { FF_STRBUF_AUTO_DESTROY name; ffStrbufInit(&name); diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c index 3c93d29c0..3de10d9dc 100644 --- a/src/detection/displayserver/linux/displayserver_linux.c +++ b/src/detection/displayserver/linux/displayserver_linux.c @@ -88,7 +88,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) ffStrbufInit(&ds->deVersion); ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4); - if (!instance.config.dsForceDrm) + if (!instance.config.general.dsForceDrm) { //We try wayland as our prefered display server, as it supports the most features. //This method can't detect the name of our WM / DE diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index b34c429f2..8829f2352 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -154,7 +154,7 @@ static void getKDE(FFDisplayServerResult* result) if(result->deVersion.length == 0) ffParsePropFileData("wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion); - if(result->deVersion.length == 0 && instance.config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.general.allowSlowOperations) { if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){ "plasmashell", @@ -214,7 +214,7 @@ static void getMate(FFDisplayServerResult* result) ffParseSemver(&result->deVersion, &major, &minor, µ); - if(result->deVersion.length == 0 && instance.config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.general.allowSlowOperations) { ffProcessAppendStdOut(&result->deVersion, (char* const[]){ "mate-session", @@ -250,7 +250,7 @@ static void getXFCE4(FFDisplayServerResult* result) } #endif - if(result->deVersion.length == 0 && instance.config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.general.allowSlowOperations) { //This is somewhat slow ffProcessAppendStdOut(&result->deVersion, (char* const[]){ @@ -276,7 +276,7 @@ static void getLXQt(FFDisplayServerResult* result) if(result->deVersion.length == 0) ffParsePropFileData("cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", &result->deVersion); - if(result->deVersion.length == 0 && instance.config.allowSlowOperations) + if(result->deVersion.length == 0 && instance.config.general.allowSlowOperations) { //This is really, really, really slow. Thank you, LXQt developers ffProcessAppendStdOut(&result->deVersion, (char* const[]){ diff --git a/src/detection/media/media_linux.c b/src/detection/media/media_linux.c index 2552fdab2..35830f1b9 100644 --- a/src/detection/media/media_linux.c +++ b/src/detection/media/media_linux.c @@ -161,8 +161,8 @@ static const char* getMedia(FFMediaResult* result) // FIXME: This is shared for both player and media module. // However it uses an option in one specific module - if(instance.config.playerName.length > 0) - getCustomBus(&data, &instance.config.playerName, result); + if(instance.config.general.playerName.length > 0) + getCustomBus(&data, &instance.config.general.playerName, result); else getBestBus(&data, result); diff --git a/src/detection/os/os_linux.c b/src/detection/os/os_linux.c index 1b99c174c..346b2937a 100644 --- a/src/detection/os/os_linux.c +++ b/src/detection/os/os_linux.c @@ -133,13 +133,13 @@ static void getDebianVersion(FFOSResult* result) static void detectOS(FFOSResult* os) { - if(instance.config.osFile.length > 0) + if(instance.config.general.osFile.length > 0) { - parseFile(instance.config.osFile.chars, os); + parseFile(instance.config.general.osFile.chars, os); return; } - if(instance.config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os)) + if(instance.config.general.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os)) { if(os->id.length == 0) ffStrbufAppendS(&os->id, "bedrock"); diff --git a/src/detection/packages/packages_windows.c b/src/detection/packages/packages_windows.c index bfd6a4c79..e5b591361 100644 --- a/src/detection/packages/packages_windows.c +++ b/src/detection/packages/packages_windows.c @@ -110,6 +110,6 @@ void ffDetectPackagesImpl(FFPackagesResult* result) detectScoop(result); detectChoco(result); detectPacman(result); - if (instance.config.allowSlowOperations) + if (instance.config.general.allowSlowOperations) detectWinget(result); } diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 1ebca55d9..cf5366f5b 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -247,7 +247,7 @@ FF_MAYBE_UNUSED static bool detectKitty(const FFstrbuf* exe, FFTerminalFontResul {"font_size ", &fontSize}, }; - if(instance.config.allowSlowOperations) + if(instance.config.general.allowSlowOperations) { FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); if(!ffProcessAppendStdOut(&buf, (char* const[]){ diff --git a/src/detection/vulkan/vulkan.c b/src/detection/vulkan/vulkan.c index 88d687c8e..0516e1bbc 100644 --- a/src/detection/vulkan/vulkan.c +++ b/src/detection/vulkan/vulkan.c @@ -119,7 +119,7 @@ static const char* detectVulkan(FFVulkanResult* result) PFN_vkGetPhysicalDeviceMemoryProperties ffvkGetPhysicalDeviceMemoryProperties = NULL; PFN_vkGetPhysicalDeviceMemoryProperties2 ffvkGetPhysicalDeviceMemoryProperties2 = - instance.config.allowSlowOperations ? (PFN_vkGetPhysicalDeviceMemoryProperties2) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties2") : NULL; // 1.1 + instance.config.general.allowSlowOperations ? (PFN_vkGetPhysicalDeviceMemoryProperties2) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties2") : NULL; // 1.1 if(!ffvkGetPhysicalDeviceMemoryProperties2) ffvkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties"); diff --git a/src/fastfetch.c b/src/fastfetch.c index 4a531e87e..5a34305eb 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -471,9 +471,9 @@ static void parseOption(FFdata* data, const char* key, const char* value) customValue->printKey = key[5] == '\0'; } - /////////////////// - //General options// - /////////////////// + //////////// + //Switches// + //////////// else if(ffStrEqualsIgnCase(key, "-c") || ffStrEqualsIgnCase(key, "--load-config") || ffStrEqualsIgnCase(key, "--config")) optionParseConfigFile(data, key, value); @@ -501,23 +501,8 @@ static void parseOption(FFdata* data, const char* key, const char* value) else instance.state.migrateConfigDoc = NULL; } - else if(ffStrEqualsIgnCase(key, "--thread") || ffStrEqualsIgnCase(key, "--multithreading")) - instance.config.multithreading = ffOptionParseBoolean(value); - else if(ffStrEqualsIgnCase(key, "--stat")) - { - if((instance.config.stat = ffOptionParseBoolean(value))) - instance.config.showErrors = true; - } - else if(ffStrEqualsIgnCase(key, "--allow-slow-operations")) - instance.config.allowSlowOperations = ffOptionParseBoolean(value); - else if(ffStrEqualsIgnCase(key, "--escape-bedrock")) - instance.config.escapeBedrock = ffOptionParseBoolean(value); - else if(ffStrEqualsIgnCase(key, "--pipe")) - instance.config.pipe = ffOptionParseBoolean(value); else if(ffStrEqualsIgnCase(key, "--load-user-config")) data->loadUserConfig = ffOptionParseBoolean(value); - else if(ffStrEqualsIgnCase(key, "--processing-timeout")) - instance.config.processingTimeout = ffOptionParseInt32(key, value); else if(ffStrEqualsIgnCase(key, "--format")) { switch (ffOptionParseEnum(key, value, (FFKeyValuePair[]) { @@ -543,17 +528,11 @@ static void parseOption(FFdata* data, const char* key, const char* value) } } - #if defined(__linux__) || defined(__FreeBSD__) - else if(ffStrEqualsIgnCase(key, "--player-name")) - ffOptionParseString(key, value, &instance.config.playerName); - else if (ffStrEqualsIgnCase(key, "--os-file")) - ffOptionParseString(key, value, &instance.config.osFile); - else if(ffStrEqualsIgnCase(key, "--ds-force-drm")) - instance.config.dsForceDrm = ffOptionParseBoolean(value); - #elif defined(_WIN32) - else if (ffStrEqualsIgnCase(key, "--wmi-timeout")) - instance.config.wmiTimeout = ffOptionParseInt32(key, value); - #endif + /////////////////// + //General options// + /////////////////// + + else if(ffParseGeneralCommandOptions(&instance.config.general, key, value)) {} //////////////// //Logo options// @@ -565,6 +544,13 @@ static void parseOption(FFdata* data, const char* key, const char* value) //Display options// /////////////////// + else if(ffStrEqualsIgnCase(key, "--stat")) + { + if((instance.config.stat = ffOptionParseBoolean(value))) + instance.config.showErrors = true; + } + else if(ffStrEqualsIgnCase(key, "--pipe")) + instance.config.pipe = ffOptionParseBoolean(value); else if(ffStrEqualsIgnCase(key, "--show-errors")) instance.config.showErrors = ffOptionParseBoolean(value); else if(ffStrEqualsIgnCase(key, "--disable-linewrap")) @@ -801,9 +787,14 @@ static void run(FFdata* data) { const char* error = NULL; + yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); + if (!yyjson_is_obj(root)) + error = "Invalid JSON config format. Root value must be an object"; + if ( - (error = ffParseLogoJsonConfig(&instance.config.logo)) || - (error = ffParseGeneralJsonConfig(&instance.config)) || + error || + (error = ffParseLogoJsonConfig(&instance.config.logo, root)) || + (error = ffParseGeneralJsonConfig(&instance.config.general, root)) || (error = ffParseDisplayJsonConfig(&instance.config)) || (error = ffParseLibraryJsonConfig(&instance.config)) || false diff --git a/src/fastfetch.h b/src/fastfetch.h index 76ed4181c..eaef3b803 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -25,6 +25,7 @@ #include "modules/options.h" #include "options/logo.h" +#include "options/general.h" typedef enum FFBinaryPrefixType { @@ -43,6 +44,7 @@ typedef enum FFTemperatureUnit typedef struct FFconfig { FFLogoOptions logo; + FFGeneralOptions general; //If one of those is empty, ffLogoPrint will set them FFstrbuf colorKeys; @@ -52,11 +54,11 @@ typedef struct FFconfig FFstrbuf keyValueSeparator; + bool stat; + bool pipe; //disables logo and all escape sequences bool showErrors; - bool allowSlowOperations; bool disableLinewrap; bool hideCursor; - bool escapeBedrock; FFBinaryPrefixType binaryPrefixType; uint8_t sizeNdigits; uint8_t sizeMaxPrefix; @@ -67,22 +69,9 @@ typedef struct FFconfig bool barBorder; uint8_t percentType; uint8_t percentNdigits; - bool pipe; //disables logo and all escape sequences - bool multithreading; - bool stat; bool noBuffer; - int32_t processingTimeout; uint32_t keyWidth; - // Module options that cannot be put in module option structure - #if defined(__linux__) || defined(__FreeBSD__) - FFstrbuf playerName; - FFstrbuf osFile; - bool dsForceDrm; - #elif defined(_WIN32) - int32_t wmiTimeout; - #endif - FFBatteryOptions battery; FFBiosOptions bios; FFBluetoothOptions bluetooth; diff --git a/src/logo/option.c b/src/logo/option.c deleted file mode 100644 index 3bd9ebccb..000000000 --- a/src/logo/option.c +++ /dev/null @@ -1,560 +0,0 @@ -#include "logo/logo.h" - -#include "common/jsonconfig.h" -#include "util/stringUtils.h" - -void ffInitLogoOptions(FFLogoOptions* options) -{ - ffStrbufInit(&options->source); - options->type = FF_LOGO_TYPE_AUTO; - for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) - ffStrbufInit(&options->colors[i]); - options->width = 0; - options->height = 0; //preserve aspect ratio - options->paddingTop = 0; - options->paddingLeft = 0; - options->paddingRight = 4; - options->printRemaining = true; - options->preserveAspectRadio = false; - options->recache = false; - options->separate = false; - - options->chafaFgOnly = false; - ffStrbufInitStatic(&options->chafaSymbols, "block+border+space-wide-inverted"); // Chafa default - options->chafaCanvasMode = UINT32_MAX; - options->chafaColorSpace = UINT32_MAX; - options->chafaDitherMode = UINT32_MAX; -} - -bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const char* value) -{ - if (strcasecmp(key, "-l") == 0) - goto logoType; - - const char* subKey = ffOptionTestPrefix(key, "logo"); - if(subKey) - { - if (subKey[0] == '\0') - { -logoType: - if(value == NULL) - { - fprintf(stderr, "Error: usage: %s \n", key); - exit(477); - } - //this is usually wanted when disabling logo - if(strcasecmp(value, "none") == 0) - { - options->paddingTop = 0; - options->paddingRight = 0; - options->paddingLeft = 0; - options->type = FF_LOGO_TYPE_NONE; - } - else if(strcasecmp(value, "small") == 0) - { - options->type = FF_LOGO_TYPE_SMALL; - } - else - ffOptionParseString(key, value, &options->source); - } - else if(strcasecmp(subKey, "type") == 0) - { - options->type = (FFLogoType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { - { "auto", FF_LOGO_TYPE_AUTO }, - { "builtin", FF_LOGO_TYPE_BUILTIN }, - { "small", FF_LOGO_TYPE_SMALL }, - { "file", FF_LOGO_TYPE_FILE }, - { "file-raw", FF_LOGO_TYPE_FILE_RAW }, - { "data", FF_LOGO_TYPE_DATA }, - { "data-raw", FF_LOGO_TYPE_DATA_RAW }, - { "sixel", FF_LOGO_TYPE_IMAGE_SIXEL }, - { "kitty", FF_LOGO_TYPE_IMAGE_KITTY }, - { "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT }, - { "iterm", FF_LOGO_TYPE_IMAGE_ITERM }, - { "chafa", FF_LOGO_TYPE_IMAGE_CHAFA }, - { "raw", FF_LOGO_TYPE_IMAGE_RAW }, - { "none", FF_LOGO_TYPE_NONE }, - {}, - }); - } - else if(ffStrStartsWithIgnCase(subKey, "color-") && subKey[6] != '\0' && subKey[7] == '\0') // matches "--logo-color-*" - { - //Map the number to an array index, so that '1' -> 0, '2' -> 1, etc. - int index = (int)subKey[6] - '0' - 1; - - //Match only --logo-color-[1-9] - if(index < 0 || index >= FASTFETCH_LOGO_MAX_COLORS) - { - fprintf(stderr, "Error: invalid --color-[1-9] index: %c\n", key[13]); - exit(472); - } - if(value == NULL) - { - fprintf(stderr, "Error: usage: %s \n", key); - exit(477); - } - ffOptionParseColor(value, &options->colors[index]); - } - else if(strcasecmp(subKey, "width") == 0) - options->width = ffOptionParseUInt32(key, value); - else if(strcasecmp(subKey, "height") == 0) - options->height = ffOptionParseUInt32(key, value); - else if(strcasecmp(subKey, "padding") == 0) - { - uint32_t padding = ffOptionParseUInt32(key, value); - options->paddingLeft = padding; - options->paddingRight = padding; - } - else if(strcasecmp(subKey, "padding-top") == 0) - options->paddingTop = ffOptionParseUInt32(key, value); - else if(strcasecmp(subKey, "padding-left") == 0) - options->paddingLeft = ffOptionParseUInt32(key, value); - else if(strcasecmp(subKey, "padding-right") == 0) - options->paddingRight = ffOptionParseUInt32(key, value); - else if(strcasecmp(subKey, "print-remaining") == 0) - options->printRemaining = ffOptionParseBoolean(value); - else if(strcasecmp(subKey, "preserve-aspect-radio") == 0) - options->preserveAspectRadio = ffOptionParseBoolean(value); - else if(strcasecmp(subKey, "recache") == 0) - options->recache = ffOptionParseBoolean(value); - else if(strcasecmp(subKey, "separate") == 0) - options->separate = ffOptionParseBoolean(value); - else - return false; - } - else if((subKey = ffOptionTestPrefix(key, "file"))) - { - if(subKey[0] == '\0') - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_FILE; - } - else if(strcasecmp(subKey, "raw") == 0) - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_FILE_RAW; - } - else - return false; - } - else if((subKey = ffOptionTestPrefix(key, "data"))) - { - if(subKey[0] == '\0') - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_DATA; - } - else if(strcasecmp(subKey, "raw") == 0) - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_DATA_RAW; - } - else - return false; - } - else if(strcasecmp(key, "--sixel") == 0) - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_IMAGE_SIXEL; - } - else if(strcasecmp(key, "--kitty") == 0) - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_IMAGE_KITTY; - } - else if(strcasecmp(key, "--kitty-direct") == 0) - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_IMAGE_KITTY_DIRECT; - } - else if(strcasecmp(key, "--iterm") == 0) - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_IMAGE_ITERM; - } - else if(strcasecmp(key, "--raw") == 0) - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_IMAGE_RAW; - } - else if((subKey = ffOptionTestPrefix(key, "chafa"))) - { - if(subKey[0] == '\0') - { - ffOptionParseString(key, value, &options->source); - options->type = FF_LOGO_TYPE_IMAGE_CHAFA; - } - else if(strcasecmp(subKey, "fg-only") == 0) - options->chafaFgOnly = ffOptionParseBoolean(value); - else if(strcasecmp(subKey, "symbols") == 0) - ffOptionParseString(key, value, &options->chafaSymbols); - else if(strcasecmp(subKey, "canvas-mode") == 0) - options->chafaCanvasMode = ffOptionParseUInt32(key, value); - else if(strcasecmp(subKey, "color-space") == 0) - options->chafaColorSpace = ffOptionParseUInt32(key, value); - else if(strcasecmp(subKey, "dither-mode") == 0) - options->chafaDitherMode = ffOptionParseUInt32(key, value); - else - return false; - } - else - return false; - - return true; -} - -void ffDestroyLogoOptions(FFLogoOptions* options) -{ - ffStrbufDestroy(&options->source); - ffStrbufDestroy(&options->chafaSymbols); - for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i) - ffStrbufDestroy(&options->colors[i]); -} - -const char* ffParseLogoJsonConfig(FFLogoOptions* options) -{ - yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); - assert(root); - - if (!yyjson_is_obj(root)) - return "Invalid JSON config format. Root value must be an object"; - - yyjson_val* object = yyjson_obj_get(root, "logo"); - if (!object) return NULL; - if (yyjson_is_null(object)) - { - options->type = FF_LOGO_TYPE_NONE; - options->paddingTop = 0; - options->paddingRight = 0; - options->paddingLeft = 0; - return NULL; - } - - if (yyjson_is_str(object)) - { - const char* value = yyjson_get_str(object); - ffStrbufSetS(&options->source, value); - return NULL; - } - - if (!yyjson_is_obj(object)) return "Property 'logo' must be an object"; - - yyjson_val *key_, *val; - size_t idx, max; - yyjson_obj_foreach(object, idx, max, key_, val) - { - const char* key = yyjson_get_str(key_); - - if (strcasecmp(key, "type") == 0) - { - int value; - const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { - { "auto", FF_LOGO_TYPE_AUTO }, - { "builtin", FF_LOGO_TYPE_BUILTIN }, - { "small", FF_LOGO_TYPE_SMALL }, - { "file", FF_LOGO_TYPE_FILE }, - { "file-raw", FF_LOGO_TYPE_FILE_RAW }, - { "data", FF_LOGO_TYPE_DATA }, - { "data-raw", FF_LOGO_TYPE_DATA_RAW }, - { "sixel", FF_LOGO_TYPE_IMAGE_SIXEL }, - { "kitty", FF_LOGO_TYPE_IMAGE_KITTY }, - { "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT }, - { "iterm", FF_LOGO_TYPE_IMAGE_ITERM }, - { "chafa", FF_LOGO_TYPE_IMAGE_CHAFA }, - { "raw", FF_LOGO_TYPE_IMAGE_RAW }, - { "none", FF_LOGO_TYPE_NONE }, - {}, - }); - - if (error) return error; - options->type = (FFLogoType) value; - continue; - } - else if (strcasecmp(key, "source") == 0) - { - ffStrbufSetS(&options->source, yyjson_get_str(val)); - continue; - } - else if (strcasecmp(key, "color") == 0) - { - if (!yyjson_is_obj(val)) - return "Property 'color' must be an object"; - - yyjson_val *key_c, *valc; - size_t idxc, maxc; - yyjson_obj_foreach(val, idxc, maxc, key_c, valc) - { - const char* keyc = yyjson_get_str(key_c); - uint32_t index = (uint32_t) strtoul(keyc, NULL, 10); - if (index < 1 || index > FASTFETCH_LOGO_MAX_COLORS) - return "Keys of property 'color' must be a number between 1 to 9"; - - ffOptionParseColor(yyjson_get_str(valc), &options->colors[index - 1]); - } - continue; - } - else if (strcasecmp(key, "width") == 0) - { - uint32_t value = (uint32_t) yyjson_get_uint(val); - if (value == 0) - return "Logo width must be a possitive integer"; - options->width = value; - continue; - } - else if (strcasecmp(key, "height") == 0) - { - uint32_t value = (uint32_t) yyjson_get_uint(val); - if (value == 0) - return "Logo height must be a possitive integer"; - options->height = value; - continue; - } - else if (strcasecmp(key, "padding") == 0) - { - if (!yyjson_is_obj(val)) - return "Logo padding must be an object"; - - #define FF_PARSE_PADDING_POSITON(pos, paddingPos) \ - yyjson_val* pos = yyjson_obj_get(val, #pos); \ - if (pos) \ - { \ - if (!yyjson_is_uint(pos)) \ - return "Logo padding values must be possitive integers"; \ - options->paddingPos = (uint32_t) yyjson_get_uint(pos); \ - } - FF_PARSE_PADDING_POSITON(left, paddingLeft); - FF_PARSE_PADDING_POSITON(top, paddingTop); - FF_PARSE_PADDING_POSITON(right, paddingRight); - #undef FF_PARSE_PADDING_POSITON - continue; - } - else if (strcasecmp(key, "printRemaining") == 0) - { - options->printRemaining = yyjson_get_bool(val); - continue; - } - else if (strcasecmp(key, "preserveAspectRadio") == 0) - { - options->preserveAspectRadio = yyjson_get_bool(val); - continue; - } - else if (strcasecmp(key, "recache") == 0) - { - options->recache = yyjson_get_bool(val); - continue; - } - else if (strcasecmp(key, "separate") == 0) - { - options->separate = yyjson_get_bool(val); - continue; - } - else if (strcasecmp(key, "chafa") == 0) - { - if (!yyjson_is_obj(val)) - return "Chafa config must be an object"; - - yyjson_val* fgOnly = yyjson_obj_get(val, "fgOnly"); - if (fgOnly) - options->chafaFgOnly = yyjson_get_bool(fgOnly); - - yyjson_val* symbols = yyjson_obj_get(val, "symbols"); - if (symbols) - ffStrbufAppendS(&options->chafaSymbols, yyjson_get_str(symbols)); - - yyjson_val* canvasMode = yyjson_obj_get(val, "canvasMode"); - if (canvasMode) - { - int value; - const char* error = ffJsonConfigParseEnum(canvasMode, &value, (FFKeyValuePair[]) { - { "TRUECOLOR", 0 }, - { "INDEXED_256", 1 }, - { "INDEXED_240", 2 }, - { "INDEXED_16", 3 }, - { "FGBG_BGFG", 4 }, - { "FGBG", 5 }, - { "INDEXED_8", 6 }, - { "INDEXED_16_8", 7 }, - {}, - }); - - if (error) return error; - options->chafaCanvasMode = (uint32_t) value; - } - - yyjson_val* colorSpace = yyjson_obj_get(val, "colorSpace"); - if (colorSpace) - { - int value; - const char* error = ffJsonConfigParseEnum(colorSpace, &value, (FFKeyValuePair[]) { - { "RGB", 0 }, - { "DIN99D", 1 }, - {}, - }); - - if (error) return error; - options->chafaColorSpace = (uint32_t) value; - } - - yyjson_val* ditherMode = yyjson_obj_get(val, "ditherMode"); - if (ditherMode) - { - int value; - const char* error = ffJsonConfigParseEnum(ditherMode, &value, (FFKeyValuePair[]) { - { "NONE", 0 }, - { "ORDERED", 1 }, - { "DIFFUSION", 2 }, - {}, - }); - - if (error) return error; - options->chafaDitherMode = (uint32_t) value; - } - continue; - } - else - return "Unknown logo key"; - } - - return NULL; -} - -void ffGenerateLogoJsonConfig(FFLogoOptions* options, yyjson_mut_doc* doc) -{ - __attribute__((__cleanup__(ffDestroyLogoOptions))) FFLogoOptions defaultOptions; - ffInitLogoOptions(&defaultOptions); - - yyjson_mut_val* obj = yyjson_mut_obj(doc); - - if (options->type != defaultOptions.type) - { - switch (options->type) - { - case FF_LOGO_TYPE_NONE: - yyjson_mut_obj_add_null(doc, doc->root, "logo"); - return; - case FF_LOGO_TYPE_BUILTIN: - yyjson_mut_obj_add_str(doc, obj, "type", "builtin"); - break; - case FF_LOGO_TYPE_SMALL: - yyjson_mut_obj_add_str(doc, obj, "type", "small"); - break; - case FF_LOGO_TYPE_FILE: - yyjson_mut_obj_add_str(doc, obj, "type", "file"); - break; - case FF_LOGO_TYPE_FILE_RAW: - yyjson_mut_obj_add_str(doc, obj, "type", "file-raw"); - break; - case FF_LOGO_TYPE_DATA: - yyjson_mut_obj_add_str(doc, obj, "type", "data"); - break; - case FF_LOGO_TYPE_DATA_RAW: - yyjson_mut_obj_add_str(doc, obj, "type", "data-raw"); - break; - case FF_LOGO_TYPE_IMAGE_SIXEL: - yyjson_mut_obj_add_str(doc, obj, "type", "sixel"); - break; - case FF_LOGO_TYPE_IMAGE_KITTY: - yyjson_mut_obj_add_str(doc, obj, "type", "kitty"); - break; - case FF_LOGO_TYPE_IMAGE_ITERM: - yyjson_mut_obj_add_str(doc, obj, "type", "iterm"); - break; - case FF_LOGO_TYPE_IMAGE_CHAFA: - yyjson_mut_obj_add_str(doc, obj, "type", "chafa"); - break; - case FF_LOGO_TYPE_IMAGE_RAW: - yyjson_mut_obj_add_str(doc, obj, "type", "raw"); - break; - default: - yyjson_mut_obj_add_str(doc, obj, "type", "auto"); - break; - } - } - - if (!ffStrbufEqual(&options->source, &defaultOptions.source)) - yyjson_mut_obj_add_str(doc, obj, "source", options->source.chars); - - { - yyjson_mut_val* color = yyjson_mut_arr(doc); - for (int i = 0; i < FASTFETCH_LOGO_MAX_COLORS; i++) - { - if (!ffStrbufEqual(&options->colors[i], &defaultOptions.colors[i])) - yyjson_mut_arr_add_strbuf(doc, color, &options->colors[i]); - } - if (yyjson_mut_arr_size(color) > 0) - yyjson_mut_obj_add_val(doc, obj, "color", color); - } - - if (options->width != defaultOptions.width) - yyjson_mut_obj_add_uint(doc, obj, "width", options->width); - - if (options->height != defaultOptions.height) - yyjson_mut_obj_add_uint(doc, obj, "height", options->height); - - { - yyjson_mut_val* padding = yyjson_mut_obj(doc); - if (options->paddingTop != defaultOptions.paddingTop) - yyjson_mut_obj_add_uint(doc, padding, "top", options->paddingTop); - if (options->paddingLeft != defaultOptions.paddingLeft) - yyjson_mut_obj_add_uint(doc, padding, "left", options->paddingLeft); - if (options->paddingRight != defaultOptions.paddingRight) - yyjson_mut_obj_add_uint(doc, padding, "right", options->paddingRight); - - if (yyjson_mut_obj_size(padding) > 0) - yyjson_mut_obj_add_val(doc, obj, "padding", padding); - } - - if (options->printRemaining != defaultOptions.printRemaining) - yyjson_mut_obj_add_bool(doc, obj, "printRemaining", options->printRemaining); - - if (options->preserveAspectRadio != defaultOptions.preserveAspectRadio) - yyjson_mut_obj_add_bool(doc, obj, "preserveAspectRadio", options->preserveAspectRadio); - - 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); - - { - yyjson_mut_val* chafa = yyjson_mut_obj(doc); - if (options->chafaFgOnly != defaultOptions.chafaFgOnly) - yyjson_mut_obj_add_bool(doc, chafa, "fgOnly", options->chafaFgOnly); - if (!ffStrbufEqual(&options->chafaSymbols, &defaultOptions.chafaSymbols)) - yyjson_mut_obj_add_strbuf(doc, chafa, "symbols", &options->chafaSymbols); - if (options->chafaCanvasMode != defaultOptions.chafaCanvasMode && options->chafaCanvasMode <= 7) - { - yyjson_mut_obj_add_str(doc, chafa, "canvasMode", ((const char* []) { - "TRUECOLOR", - "INDEXED_256", - "INDEXED_240", - "INDEXED_16", - "FGBG_BGFG", - "FGBG", - "INDEXED_8", - "INDEXED_16_8", - })[options->chafaCanvasMode]); - } - if (options->chafaColorSpace != defaultOptions.chafaColorSpace && options->chafaColorSpace <= 1) - { - yyjson_mut_obj_add_str(doc, chafa, "colorSpace", ((const char* []) { - "RGB", - "DIN99D", - })[options->chafaColorSpace]); - } - if (options->chafaDitherMode != defaultOptions.chafaDitherMode && options->chafaDitherMode <= 2) - { - yyjson_mut_obj_add_str(doc, chafa, "ditherMode", ((const char* []) { - "NONE", - "ORDERED", - "DIFFUSION", - })[options->chafaDitherMode]); - } - - if (yyjson_mut_obj_size(chafa) > 0) - yyjson_mut_obj_add_val(doc, obj, "chafa", chafa); - } - - if (yyjson_mut_obj_size(obj) > 0) - yyjson_mut_obj_add_val(doc, doc->root, "logo", obj); -} diff --git a/src/logo/option.h b/src/logo/option.h deleted file mode 100644 index 9273e2a3f..000000000 --- a/src/logo/option.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "util/FFstrbuf.h" - -#define FASTFETCH_LOGO_MAX_NAMES 9 -#define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) - -typedef enum FFLogoType -{ - FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo - FF_LOGO_TYPE_BUILTIN, //builtin ascii art - FF_LOGO_TYPE_SMALL, //builtin ascii art, small version - FF_LOGO_TYPE_FILE, //text file, printed with color code replacement - FF_LOGO_TYPE_FILE_RAW, //text file, printed as is - FF_LOGO_TYPE_DATA, //text data, printed with color code replacement - FF_LOGO_TYPE_DATA_RAW, //text data, printed as is - FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes. - FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol - FF_LOGO_TYPE_IMAGE_KITTY_DIRECT, //image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm) - FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol - FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa - FF_LOGO_TYPE_IMAGE_RAW, //image file, printed as raw binary string - FF_LOGO_TYPE_NONE, //--logo none -} FFLogoType; - -typedef struct FFLogoOptions -{ - FFstrbuf source; - FFLogoType type; - FFstrbuf colors[FASTFETCH_LOGO_MAX_COLORS]; - uint32_t width; - uint32_t height; - uint32_t paddingTop; - uint32_t paddingLeft; - uint32_t paddingRight; - bool printRemaining; - bool preserveAspectRadio; - bool recache; - bool separate; - - bool chafaFgOnly; - FFstrbuf chafaSymbols; - uint32_t chafaCanvasMode; - uint32_t chafaColorSpace; - uint32_t chafaDitherMode; -} FFLogoOptions; diff --git a/src/options/general.c b/src/options/general.c new file mode 100644 index 000000000..ac5d4f451 --- /dev/null +++ b/src/options/general.c @@ -0,0 +1,98 @@ +#include "fastfetch.h" +#include "util/stringUtils.h" +#include "options/general.h" + +#include + +const char* ffParseGeneralJsonConfig(FFGeneralOptions* options, yyjson_val* root) +{ + yyjson_val* object = yyjson_obj_get(root, "general"); + if (!object) return NULL; + if (!yyjson_is_obj(object)) return "Property 'general' must be an object"; + + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(object, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + + if (ffStrEqualsIgnCase(key, "allowSlowOperations")) + options->allowSlowOperations = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "thread") || ffStrEqualsIgnCase(key, "multithreading")) + options->multithreading = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "processingTimeout")) + options->processingTimeout = (int32_t) yyjson_get_int(val); + + #if defined(__linux__) || defined(__FreeBSD__) + else if (ffStrEqualsIgnCase(key, "escapeBedrock")) + options->escapeBedrock = yyjson_get_bool(val); + else if (ffStrEqualsIgnCase(key, "playerName")) + ffStrbufSetS(&options->playerName, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "osFile")) + ffStrbufSetS(&options->osFile, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "dsForceDrm")) + options->dsForceDrm = yyjson_get_bool(val); + #elif defined(_WIN32) + else if (ffStrEqualsIgnCase(key, "wmiTimeout")) + options->wmiTimeout = (int32_t) yyjson_get_int(val); + #endif + + else + return "Unknown general property"; + } + + return NULL; +} + +bool ffParseGeneralCommandOptions(FFGeneralOptions* options, const char* key, const char* value) +{ + if(ffStrEqualsIgnCase(key, "--allow-slow-operations")) + options->allowSlowOperations = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--thread") || ffStrEqualsIgnCase(key, "--multithreading")) + options->multithreading = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--processing-timeout")) + options->processingTimeout = ffOptionParseInt32(key, value); + + #if defined(__linux__) || defined(__FreeBSD__) + else if(ffStrEqualsIgnCase(key, "--escape-bedrock")) + options->escapeBedrock = ffOptionParseBoolean(value); + else if(ffStrEqualsIgnCase(key, "--player-name")) + ffOptionParseString(key, value, &options->playerName); + else if (ffStrEqualsIgnCase(key, "--os-file")) + ffOptionParseString(key, value, &options->osFile); + else if(ffStrEqualsIgnCase(key, "--ds-force-drm")) + options->dsForceDrm = ffOptionParseBoolean(value); + #elif defined(_WIN32) + else if (ffStrEqualsIgnCase(key, "--wmi-timeout")) + options->wmiTimeout = ffOptionParseInt32(key, value); + #endif + + else + return false; + + return true; +} + +void ffInitGeneralOptions(FFGeneralOptions* options) +{ + options->processingTimeout = 1000; + options->allowSlowOperations = false; + options->multithreading = true; + + #if defined(__linux__) || defined(__FreeBSD__) + options->escapeBedrock = true; + ffStrbufInit(&options->playerName); + ffStrbufInit(&options->osFile); + options->dsForceDrm = false; + #elif defined(_WIN32) + options->wmiTimeout = 5000; + #endif +} + +void ffDestroyGeneralOptions(FF_MAYBE_UNUSED FFGeneralOptions* options) +{ + #if defined(__linux__) || defined(__FreeBSD__) + ffStrbufDestroy(&options->playerName); + ffStrbufDestroy(&options->osFile); + #endif +} diff --git a/src/options/general.h b/src/options/general.h new file mode 100644 index 000000000..d84e55bad --- /dev/null +++ b/src/options/general.h @@ -0,0 +1,25 @@ +#pragma once + +#include "util/FFstrbuf.h" + +typedef struct FFGeneralOptions +{ + bool allowSlowOperations; + bool multithreading; + int32_t processingTimeout; + + // Module options that cannot be put in module option structure + #if defined(__linux__) || defined(__FreeBSD__) + FFstrbuf playerName; + FFstrbuf osFile; + bool escapeBedrock; + bool dsForceDrm; + #elif defined(_WIN32) + int32_t wmiTimeout; + #endif +} FFGeneralOptions; + +const char* ffParseGeneralJsonConfig(FFGeneralOptions* options, yyjson_val* root); +bool ffParseGeneralCommandOptions(FFGeneralOptions* options, const char* key, const char* value); +void ffInitGeneralOptions(FFGeneralOptions* options); +void ffDestroyGeneralOptions(FFGeneralOptions* options); diff --git a/src/options/logo.c b/src/options/logo.c index 3bd9ebccb..12854b662 100644 --- a/src/options/logo.c +++ b/src/options/logo.c @@ -211,14 +211,8 @@ void ffDestroyLogoOptions(FFLogoOptions* options) ffStrbufDestroy(&options->colors[i]); } -const char* ffParseLogoJsonConfig(FFLogoOptions* options) +const char* ffParseLogoJsonConfig(FFLogoOptions* options, yyjson_val* root) { - yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc); - assert(root); - - if (!yyjson_is_obj(root)) - return "Invalid JSON config format. Root value must be an object"; - yyjson_val* object = yyjson_obj_get(root, "logo"); if (!object) return NULL; if (yyjson_is_null(object)) diff --git a/src/options/logo.h b/src/options/logo.h index 98d0d4bb8..5bc0ef614 100644 --- a/src/options/logo.h +++ b/src/options/logo.h @@ -48,5 +48,5 @@ typedef struct FFLogoOptions void ffInitLogoOptions(FFLogoOptions* options); bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const char* value); void ffDestroyLogoOptions(FFLogoOptions* options); -const char* ffParseLogoJsonConfig(FFLogoOptions* options); +const char* ffParseLogoJsonConfig(FFLogoOptions* options, yyjson_val* root); void ffGenerateLogoJsonConfig(FFLogoOptions* options, yyjson_mut_doc* doc); diff --git a/src/util/windows/wmi.hpp b/src/util/windows/wmi.hpp index f9719a664..5e8d57a32 100644 --- a/src/util/windows/wmi.hpp +++ b/src/util/windows/wmi.hpp @@ -162,7 +162,7 @@ struct FFWmiRecord if(!pEnumerator) return; ULONG ret; - bool ok = SUCCEEDED(pEnumerator->Next(instance.config.wmiTimeout, 1, &obj, &ret)) && ret; + bool ok = SUCCEEDED(pEnumerator->Next(instance.config.general.wmiTimeout, 1, &obj, &ret)) && ret; if(!ok) obj = nullptr; } FFWmiRecord(const FFWmiRecord&) = delete;