From 04180a73893775d6e13a1f87cf8dbd9bd63badf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 10 Mar 2023 10:56:36 +0800 Subject: [PATCH] Display: init support of JSON config --- CMakeLists.txt | 2 +- src/common/config.c | 35 +++ src/common/config.h | 2 + src/common/init.c | 8 +- src/common/option.c | 23 +- src/common/option.h | 12 +- .../displayserver/displayserver_apple.c | 2 +- .../displayserver/displayserver_windows.c | 2 +- src/detection/displayserver/linux/wayland.c | 2 +- src/fastfetch.c | 16 +- src/fastfetch.h | 14 +- src/flashfetch.c | 2 +- src/modules/display.c | 108 --------- src/modules/display/display.c | 218 ++++++++++++++++++ src/modules/display/display.h | 14 ++ src/modules/display/option.h | 22 ++ src/modules/jsonconfig/jsonconfig.c | 2 + src/modules/modules.h | 1 + src/modules/options.h | 1 + 19 files changed, 318 insertions(+), 168 deletions(-) delete mode 100644 src/modules/display.c create mode 100644 src/modules/display/display.c create mode 100644 src/modules/display/display.h create mode 100644 src/modules/display/option.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 19a202bed..2faf326fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -293,7 +293,7 @@ set(LIBFASTFETCH_SRC src/modules/poweradapter.c src/modules/processes.c src/modules/publicip.c - src/modules/display.c + src/modules/display/display.c src/modules/separator/separator.c src/modules/shell.c src/modules/sound.c diff --git a/src/common/config.c b/src/common/config.c index f7d124fce..c154583c9 100644 --- a/src/common/config.c +++ b/src/common/config.c @@ -23,4 +23,39 @@ bool ffJsonConfigParseModuleArgs(JSONCData* data, const char* key, json_object* return false; } +const char* ffJsonConfigParseEnum(JSONCData* data, json_object* val, int* result, FFKeyValuePair pairs[]) +{ + if (data->ffjson_object_is_type(val, json_type_int)) + { + int intVal = data->ffjson_object_get_int(val); + + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) + { + if (intVal == pPair->value) + { + *result = pPair->value; + return NULL; + } + } + + return "Invalid enum integer"; + } + else if (data->ffjson_object_is_type(val, json_type_string)) + { + const char* strVal = data->ffjson_object_get_string(val); + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) + { + if (strcasecmp(strVal, pPair->key) == 0) + { + *result = pPair->value; + return NULL; + } + } + + return "Invalid enum string"; + } + else + return "Invalid enum value type; must be a string or integer"; +} + #endif diff --git a/src/common/config.h b/src/common/config.h index 81dd9c011..d52b88440 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -13,6 +13,7 @@ typedef struct JSONCData FF_LIBRARY_SYMBOL(json_object_get_array) FF_LIBRARY_SYMBOL(json_object_get_boolean) FF_LIBRARY_SYMBOL(json_object_get_double) + FF_LIBRARY_SYMBOL(json_object_get_int) FF_LIBRARY_SYMBOL(json_object_get_string_len) FF_LIBRARY_SYMBOL(json_object_get_string) FF_LIBRARY_SYMBOL(json_object_get_object) @@ -23,5 +24,6 @@ typedef struct JSONCData } JSONCData; bool ffJsonConfigParseModuleArgs(JSONCData* data, const char* key, json_object* val, FFModuleArgs* moduleArgs); +const char* ffJsonConfigParseEnum(JSONCData* data, json_object* val, int* result, FFKeyValuePair pairs[]); #endif diff --git a/src/common/init.c b/src/common/init.c index 39d840869..950f30c1b 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -85,7 +85,7 @@ static void defaultConfig(FFinstance* instance) initModuleArg(&instance->config.processes); initModuleArg(&instance->config.packages); initModuleArg(&instance->config.shell); - initModuleArg(&instance->config.display); + ffInitDisplayOptions(&instance->config.display); initModuleArg(&instance->config.de); initModuleArg(&instance->config.wm); initModuleArg(&instance->config.wmTheme); @@ -160,10 +160,6 @@ static void defaultConfig(FFinstance* instance) ffStrbufInitA(&instance->config.diskFolders, 0); instance->config.diskShowTypes = FF_DISK_TYPE_REGULAR_BIT | FF_DISK_TYPE_EXTERNAL_BIT; - instance->config.displayCompactType = FF_DISPLAY_COMPACT_TYPE_NONE; - instance->config.displayDetectName = false; - instance->config.displayPreciseRefreshRate = false; - instance->config.bluetoothShowDisconnected = false; instance->config.soundType = FF_SOUND_TYPE_MAIN; @@ -328,7 +324,7 @@ static void destroyConfig(FFinstance* instance) destroyModuleArg(&instance->config.processes); destroyModuleArg(&instance->config.packages); destroyModuleArg(&instance->config.shell); - destroyModuleArg(&instance->config.display); + ffDestroyDisplayOptions(&instance->config.display); destroyModuleArg(&instance->config.de); destroyModuleArg(&instance->config.wm); destroyModuleArg(&instance->config.wmTheme); diff --git a/src/common/option.c b/src/common/option.c index 81e54c532..3f6c360e4 100644 --- a/src/common/option.c +++ b/src/common/option.c @@ -72,7 +72,7 @@ uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value) return num; } -void ffOptionParseEnum(const char* argumentKey, const char* requestedKey, void* result, ...) +int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]) { if(requestedKey == NULL) { @@ -80,27 +80,12 @@ void ffOptionParseEnum(const char* argumentKey, const char* requestedKey, void* exit(476); } - va_list args; - va_start(args, result); - - while(true) + for (const FFKeyValuePair* pPair = pairs; pPair->key; ++pPair) { - const char* key = va_arg(args, const char*); - if(key == NULL) - break; - - int value = va_arg(args, int); //C standard guarantees that enumeration constants are presented as ints - - if(strcasecmp(requestedKey, key) == 0) - { - *(int*)result = value; - va_end(args); - return; - } + if(strcasecmp(requestedKey, pPair->key) == 0) + return pPair->value; } - va_end(args); - fprintf(stderr, "Error: unknown %s value: %s\n", argumentKey, requestedKey); exit(478); } diff --git a/src/common/option.h b/src/common/option.h index b24c278b8..1c56de4d3 100644 --- a/src/common/option.h +++ b/src/common/option.h @@ -9,11 +9,17 @@ typedef struct FFModuleArgs FFstrbuf errorFormat; } FFModuleArgs; +typedef struct FFKeyValuePair +{ + const char* key; + int value; +} FFKeyValuePair; + const char* ffOptionTestPrefix(const char* argumentKey, const char* moduleName); bool ffOptionParseModuleArgs(const char* argumentKey, const char* pkey, const char* value, FFModuleArgs* result); void ffOptionParseString(const char* argumentKey, const char* value, FFstrbuf* buffer); -uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value); -void ffOptionParseEnum(const char* argumentKey, const char* requestedKey, void* result, ...); -bool ffOptionParseBoolean(const char* str); +FF_C_NODISCARD uint32_t ffOptionParseUInt32(const char* argumentKey, const char* value); +FF_C_NODISCARD int ffOptionParseEnum(const char* argumentKey, const char* requestedKey, FFKeyValuePair pairs[]); +FF_C_NODISCARD bool ffOptionParseBoolean(const char* str); void ffOptionInitModuleArg(FFModuleArgs* args); void ffOptionDestroyModuleArg(FFModuleArgs* args); diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index f2d2447aa..05c017a49 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -121,5 +121,5 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufAppendS(&ds->dePrettyName, "Aqua"); ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4); - detectDisplays(ds, instance->config.displayDetectName); + detectDisplays(ds, instance->config.display.detectName); } diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index 5d93746f5..1ee86ef5d 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -113,7 +113,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufInit(&ds->deVersion); ffListInit(&ds->displays, sizeof(FFDisplayResult)); - detectDisplays(ds, instance->config.displayDetectName); + detectDisplays(ds, instance->config.display.detectName); //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067 const FFOSResult* os = ffDetectOS(instance); diff --git a/src/detection/displayserver/linux/wayland.c b/src/detection/displayserver/linux/wayland.c index 7e7f98fb5..d65fa70a5 100644 --- a/src/detection/displayserver/linux/wayland.c +++ b/src/detection/displayserver/linux/wayland.c @@ -225,7 +225,7 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) if(data.display == NULL) return false; - data.detectName = instance->config.displayDetectName; + data.detectName = instance->config.display.detectName; waylandDetectWM(ffwl_display_get_fd(data.display), result); diff --git a/src/fastfetch.c b/src/fastfetch.c index 23e06fa39..071e947a5 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1144,7 +1144,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else if(optionParseModuleArgs(key, value, "processes", &instance->config.processes)) {} else if(optionParseModuleArgs(key, value, "packages", &instance->config.packages)) {} else if(optionParseModuleArgs(key, value, "shell", &instance->config.shell)) {} - else if(optionParseModuleArgs(key, value, "display", &instance->config.display)) {} + else if(ffParseDisplayCommandOptions(&instance->config.display, key, value)) {} else if(optionParseModuleArgs(key, value, "brightness", &instance->config.brightness)) {} else if(optionParseModuleArgs(key, value, "de", &instance->config.de)) {} else if(optionParseModuleArgs(key, value, "wifi", &instance->config.wifi)) {} @@ -1272,18 +1272,6 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_SUBVOLUME_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_SUBVOLUME_BIT); else if(strcasecmp(key, "--disk-show-unknown") == 0) optionParseBoolean(value) ? (instance->config.diskShowTypes |= FF_DISK_TYPE_UNKNOWN_BIT) : (instance->config.diskShowTypes &= ~FF_DISK_TYPE_UNKNOWN_BIT); - else if(strcasecmp(key, "--display-compact-type") == 0) - { - optionParseEnum(key, value, &instance->config.displayCompactType, - "none", FF_DISPLAY_COMPACT_TYPE_NONE, - "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT, - "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT, - NULL); - } - else if(strcasecmp(key, "--display-precise-refresh-rate") == 0) - instance->config.displayPreciseRefreshRate = optionParseBoolean(value); - else if(strcasecmp(key, "--display-detect-name") == 0) - instance->config.displayDetectName = optionParseBoolean(value); else if(strcasecmp(key, "--bluetooth-show-disconnected") == 0) instance->config.bluetoothShowDisconnected = optionParseBoolean(value); else if(strcasecmp(key, "--sound-type") == 0) @@ -1417,7 +1405,7 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char else if(strcasecmp(line, "shell") == 0) ffPrintShell(instance); else if(strcasecmp(line, "display") == 0) - ffPrintDisplay(instance); + ffPrintDisplay(instance, &instance->config.display); else if(strcasecmp(line, "desktopenvironment") == 0 || strcasecmp(line, "de") == 0) ffPrintDesktopEnvironment(instance); else if(strcasecmp(line, "windowmanager") == 0 || strcasecmp(line, "wm") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index c889f8cf7..7c1ecf1f2 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -43,13 +43,6 @@ typedef enum FFSoundType FF_SOUND_TYPE_ALL, } FFSoundType; -typedef enum FFDisplayCompactType -{ - FF_DISPLAY_COMPACT_TYPE_NONE = 0, - FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT = 1 << 0, - FF_DISPLAY_COMPACT_TYPE_SCALED_BIT = 1 << 1, -} FFDisplayCompactType; - typedef enum FFLocalIpCompactType { FF_LOCALIP_COMPACT_TYPE_NONE, @@ -146,7 +139,7 @@ typedef struct FFconfig FFModuleArgs processes; FFModuleArgs packages; FFModuleArgs shell; - FFModuleArgs display; + FFDisplayOptions display; FFModuleArgs de; FFModuleArgs wallpaper; FFModuleArgs wifi; @@ -221,10 +214,6 @@ typedef struct FFconfig FFstrbuf diskFolders; FFDiskType diskShowTypes; - FFDisplayCompactType displayCompactType; - bool displayDetectName; - bool displayPreciseRefreshRate; - bool bluetoothShowDisconnected; FFstrbuf localIpNamePrefix; @@ -306,7 +295,6 @@ void ffPrintUptime(FFinstance* instance); void ffPrintProcesses(FFinstance* instance); void ffPrintPackages(FFinstance* instance); void ffPrintShell(FFinstance* instance); -void ffPrintDisplay(FFinstance* instance); void ffPrintBrightness(FFinstance* instance); void ffPrintDesktopEnvironment(FFinstance* instance); void ffPrintWM(FFinstance* instance); diff --git a/src/flashfetch.c b/src/flashfetch.c index 6b961e04a..4ababc3a7 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -32,7 +32,7 @@ int main(int argc, char** argv) //ffPrintProcesses(&instance); ffPrintPackages(&instance); ffPrintShell(&instance); - ffPrintDisplay(&instance); + ffPrintDisplay(&instance, &instance.config.display); // ffPrintBrightness(&instance); ffPrintDesktopEnvironment(&instance); ffPrintWM(&instance); diff --git a/src/modules/display.c b/src/modules/display.c deleted file mode 100644 index f4dddbe1f..000000000 --- a/src/modules/display.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "fastfetch.h" -#include "common/printing.h" -#include "detection/displayserver/displayserver.h" - -#define FF_DISPLAY_MODULE_NAME "Display" -#define FF_DISPLAY_NUM_FORMAT_ARGS 7 - -void ffPrintDisplay(FFinstance* instance) -{ - #ifdef __ANDROID__ - ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display, "Display detection is not supported on Android"); - return; - #endif - - const FFDisplayServerResult* dsResult = ffConnectDisplayServer(instance); - - if (instance->config.displayCompactType != FF_DISPLAY_COMPACT_TYPE_NONE) - { - ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display.key); - - int index = 0; - FF_LIST_FOR_EACH(FFDisplayResult, result, dsResult->displays) - { - if (instance->config.displayCompactType & FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT) - { - if (index++) putchar(' '); - printf("%ix%i", result->width, result->height); - } - if (instance->config.displayCompactType & FF_DISPLAY_COMPACT_TYPE_SCALED_BIT) - { - if (index++) putchar(' '); - printf("%ix%i", result->scaledWidth, result->scaledHeight); - } - ffStrbufDestroy(&result->name); - } - putchar('\n'); - return; - } - - FF_STRBUF_AUTO_DESTROY key; - ffStrbufInit(&key); - - for(uint32_t i = 0; i < dsResult->displays.length; i++) - { - FFDisplayResult* result = ffListGet(&dsResult->displays, i); - uint8_t moduleIndex = dsResult->displays.length == 1 ? 0 : (uint8_t) (i + 1); - const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "built-in" : "external"; - - if(instance->config.display.outputFormat.length == 0) - { - if(result->name.length || (moduleIndex > 0 && displayType)) - { - ffStrbufClear(&key); - if(instance->config.display.key.length == 0) - { - ffStrbufAppendF(&key, "%s (%s)", FF_DISPLAY_MODULE_NAME, result->name.length ? result->name.chars : displayType); - } - else - { - ffParseFormatString(&key, &instance->config.display.key, 1, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_UINT, &i}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRING, displayType}, - }); - } - ffPrintLogoAndKey(instance, key.chars, 0, NULL); - } - else - { - ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &instance->config.display.key); - } - - printf("%ix%i", result->width, result->height); - - if(result->refreshRate > 0) - { - if(instance->config.displayPreciseRefreshRate) - printf(" @ %gHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0); - else - printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5)); - } - - if( - result->scaledWidth > 0 && result->scaledWidth != result->width && - result->scaledHeight > 0 && result->scaledHeight != result->height) - printf(" (as %ix%i)", result->scaledWidth, result->scaledHeight); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &instance->config.display, FF_DISPLAY_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_UINT, &result->width}, - {FF_FORMAT_ARG_TYPE_UINT, &result->height}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate}, - {FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth}, - {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRING, displayType}, - }); - } - - ffStrbufDestroy(&result->name); - } - - if(dsResult->displays.length == 0) - ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display, "Couldn't detect display"); -} diff --git a/src/modules/display/display.c b/src/modules/display/display.c new file mode 100644 index 000000000..72330878c --- /dev/null +++ b/src/modules/display/display.c @@ -0,0 +1,218 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/displayserver/displayserver.h" +#include "modules/display/display.h" + +#define FF_DISPLAY_MODULE_NAME "Display" +#define FF_DISPLAY_NUM_FORMAT_ARGS 7 + +void ffPrintDisplay(FFinstance* instance, FFDisplayOptions* options) +{ + #ifdef __ANDROID__ + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display.moduleArgs, "Display detection is not supported on Android"); + return; + #endif + + const FFDisplayServerResult* dsResult = ffConnectDisplayServer(instance); + + if(dsResult->displays.length == 0) + { + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &instance->config.display.moduleArgs, "Couldn't detect display"); + return; + } + + if (options->compactType != FF_DISPLAY_COMPACT_TYPE_NONE) + { + ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, 0, &options->moduleArgs.key); + + int index = 0; + FF_LIST_FOR_EACH(FFDisplayResult, result, dsResult->displays) + { + if (options->compactType & FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT) + { + if (index++) putchar(' '); + printf("%ix%i", result->width, result->height); + } + if (options->compactType & FF_DISPLAY_COMPACT_TYPE_SCALED_BIT) + { + if (index++) putchar(' '); + printf("%ix%i", result->scaledWidth, result->scaledHeight); + } + ffStrbufDestroy(&result->name); + } + putchar('\n'); + return; + } + + FF_STRBUF_AUTO_DESTROY key; + ffStrbufInit(&key); + + for(uint32_t i = 0; i < dsResult->displays.length; i++) + { + FFDisplayResult* result = ffListGet(&dsResult->displays, i); + uint8_t moduleIndex = dsResult->displays.length == 1 ? 0 : (uint8_t) (i + 1); + const char* displayType = result->type == FF_DISPLAY_TYPE_UNKNOWN ? NULL : result->type == FF_DISPLAY_TYPE_BUILTIN ? "built-in" : "external"; + + if(options->moduleArgs.outputFormat.length == 0) + { + if(result->name.length || (moduleIndex > 0 && displayType)) + { + ffStrbufClear(&key); + if(options->moduleArgs.key.length == 0) + { + ffStrbufAppendF(&key, "%s (%s)", FF_DISPLAY_MODULE_NAME, result->name.length ? result->name.chars : displayType); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_UINT, &i}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRING, displayType}, + }); + } + ffPrintLogoAndKey(instance, key.chars, 0, NULL); + } + else + { + ffPrintLogoAndKey(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &options->moduleArgs.key); + } + + printf("%ix%i", result->width, result->height); + + if(result->refreshRate > 0) + { + if(options->preciseRefreshRate) + printf(" @ %gHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0); + else + printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5)); + } + + if( + result->scaledWidth > 0 && result->scaledWidth != result->width && + result->scaledHeight > 0 && result->scaledHeight != result->height) + printf(" (as %ix%i)", result->scaledWidth, result->scaledHeight); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_DISPLAY_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_DISPLAY_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_UINT, &result->width}, + {FF_FORMAT_ARG_TYPE_UINT, &result->height}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate}, + {FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth}, + {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRING, displayType}, + }); + } + + ffStrbufDestroy(&result->name); + } +} + +void ffInitDisplayOptions(FFDisplayOptions* options) +{ + options->moduleName = FF_DISPLAY_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->compactType = FF_DISPLAY_COMPACT_TYPE_NONE; + options->detectName = false; + options->preciseRefreshRate = false; +} + +bool ffParseDisplayCommandOptions(FFDisplayOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DISPLAY_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "compact-type") == 0) + { + options->compactType = (FFDisplayCompactType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { + { "none", FF_DISPLAY_COMPACT_TYPE_NONE }, + { "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT }, + { "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT }, + {}, + }); + return true; + } + + if (strcasecmp(subKey, "detect-name") == 0) + { + options->detectName = ffOptionParseBoolean(value); + return true; + } + + if (strcasecmp(subKey, "precise-refresh-rate") == 0) + { + options->preciseRefreshRate = ffOptionParseBoolean(value); + return true; + } + + return false; +} + +void ffDestroyDisplayOptions(FFDisplayOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +bool ffParseDisplayJsonObject(FFinstance* instance, const char* type, JSONCData* data, json_object* module) +{ + if (strcasecmp(type, FF_DISPLAY_MODULE_NAME) != 0) + return false; + + FFDisplayOptions __attribute__((__cleanup__(ffDestroyDisplayOptions))) options; + ffInitDisplayOptions(&options); + + if (module) + { + struct lh_entry* entry; + lh_foreach(data->ffjson_object_get_object(module), entry) + { + const char* key = (const char *)lh_entry_k(entry); + if (strcasecmp(key, "type") == 0) + continue; + json_object* val = (struct json_object *)lh_entry_v(entry); + + if (ffJsonConfigParseModuleArgs(data, key, val, &options.moduleArgs)) + continue; + + if (strcasecmp(key, "compactType") == 0) + { + int value; + const char* error = ffJsonConfigParseEnum(data, val, &value, (FFKeyValuePair[]) { + { "none", FF_DISPLAY_COMPACT_TYPE_NONE }, + { "original", FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT }, + { "scaled", FF_DISPLAY_COMPACT_TYPE_SCALED_BIT }, + {}, + }); + if (error) + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &options.moduleArgs, "Invalid %s value: %s", key, error); + else + options.compactType = (FFDisplayCompactType) value; + continue; + } + + if (strcasecmp(key, "detectName") == 0) + { + options.detectName = data->ffjson_object_get_boolean(val); + continue; + } + + if (strcasecmp(key, "preciseRefreshRate") == 0) + { + options.preciseRefreshRate = data->ffjson_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_DISPLAY_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintDisplay(instance, &options); + return true; +} +#endif diff --git a/src/modules/display/display.h b/src/modules/display/display.h new file mode 100644 index 000000000..7ee6d65d1 --- /dev/null +++ b/src/modules/display/display.h @@ -0,0 +1,14 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/display/option.h" + +void ffPrintDisplay(FFinstance* instance, FFDisplayOptions* options); +void ffInitDisplayOptions(FFDisplayOptions* options); +bool ffParseDisplayCommandOptions(FFDisplayOptions* options, const char* key, const char* value); +void ffDestroyDisplayOptions(FFDisplayOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/config.h" +bool ffParseDisplayJsonObject(FFinstance* instance, const char* type, JSONCData* data, json_object* module); +#endif diff --git a/src/modules/display/option.h b/src/modules/display/option.h new file mode 100644 index 000000000..4e47b1bee --- /dev/null +++ b/src/modules/display/option.h @@ -0,0 +1,22 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef enum FFDisplayCompactType +{ + FF_DISPLAY_COMPACT_TYPE_NONE = 0, + FF_DISPLAY_COMPACT_TYPE_ORIGINAL_BIT = 1 << 0, + FF_DISPLAY_COMPACT_TYPE_SCALED_BIT = 1 << 1, +} FFDisplayCompactType; + +typedef struct FFDisplayOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + FFDisplayCompactType compactType; + bool detectName; + bool preciseRefreshRate; +} FFDisplayOptions; diff --git a/src/modules/jsonconfig/jsonconfig.c b/src/modules/jsonconfig/jsonconfig.c index 2f0309d2a..c7a4aec6f 100644 --- a/src/modules/jsonconfig/jsonconfig.c +++ b/src/modules/jsonconfig/jsonconfig.c @@ -16,6 +16,7 @@ static inline bool parseModuleJsonObject(FFinstance* instance, const char* type, ffParseBatteryJsonObject(instance, type, data, module) || ffParseCommandJsonObject(instance, type, data, module) || ffParseDateTimeJsonObject(instance, type, data, module) || + ffParseDisplayJsonObject(instance, type, data, module) || ffParseOSJsonObject(instance, type, data, module) || ffParseSeparatorJsonObject(instance, type, data, module) || false; @@ -72,6 +73,7 @@ static const char* printJsonConfig(FFinstance* instance) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libjsonc, data, json_object_get_array) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libjsonc, data, json_object_get_boolean) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libjsonc, data, json_object_get_double) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libjsonc, data, json_object_get_int) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libjsonc, data, json_object_get_string_len) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libjsonc, data, json_object_get_string) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libjsonc, data, json_object_get_object) diff --git a/src/modules/modules.h b/src/modules/modules.h index 4bd1a79e3..5235729f4 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -6,6 +6,7 @@ #include "modules/battery/battery.h" #include "modules/command/command.h" #include "modules/datetime/datetime.h" +#include "modules/display/display.h" #include "modules/separator/separator.h" #include "modules/title/title.h" #include "modules/jsonconfig/jsonconfig.h" diff --git a/src/modules/options.h b/src/modules/options.h index 157c34cb2..a929492cb 100644 --- a/src/modules/options.h +++ b/src/modules/options.h @@ -5,6 +5,7 @@ #include "modules/battery/option.h" #include "modules/command/option.h" #include "modules/datetime/option.h" +#include "modules/display/option.h" #include "modules/os/option.h" #include "modules/separator/option.h" #include "modules/title/option.h"