diff --git a/CMakeLists.txt b/CMakeLists.txt index 882997f14..1792122dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -328,6 +328,7 @@ set(LIBFASTFETCH_SRC src/modules/locale/locale.c src/modules/localip/localip.c src/modules/memory/memory.c + src/modules/nativeresolution/nativeresolution.c src/modules/opencl/opencl.c src/modules/opengl/opengl.c src/modules/os/os.c @@ -393,6 +394,7 @@ if(LINUX) src/detection/gamepad/gamepad_linux.c src/detection/media/media_linux.c src/detection/memory/memory_linux.c + src/detection/nativeresolution/nativeresolution_nosupport.c src/detection/opengl/opengl_linux.c src/detection/os/os_linux.c src/detection/packages/packages_linux.c @@ -438,6 +440,7 @@ elseif(ANDROID) src/detection/gamepad/gamepad_nosupport.c src/detection/media/media_nosupport.c src/detection/memory/memory_linux.c + src/detection/nativeresolution/nativeresolution_nosupport.c src/detection/opengl/opengl_linux.c src/detection/os/os_android.c src/detection/packages/packages_linux.c @@ -489,6 +492,7 @@ elseif(BSD) src/detection/gamepad/gamepad_bsd.c src/detection/media/media_linux.c src/detection/memory/memory_bsd.c + src/detection/nativeresolution/nativeresolution_nosupport.c src/detection/opengl/opengl_linux.c src/detection/os/os_linux.c src/detection/packages/packages_linux.c @@ -536,6 +540,7 @@ elseif(APPLE) src/detection/gamepad/gamepad_apple.c src/detection/media/media_apple.m src/detection/memory/memory_apple.c + src/detection/nativeresolution/nativeresolution_nosupport.c src/detection/opengl/opengl_apple.c src/detection/os/os_apple.m src/detection/packages/packages_apple.c @@ -582,6 +587,7 @@ elseif(WIN32) src/detection/gamepad/gamepad_windows.c src/detection/media/media_nosupport.c src/detection/memory/memory_windows.c + src/detection/nativeresolution/nativeresolution_nosupport.c src/detection/opengl/opengl_windows.c src/detection/os/os_windows.cpp src/detection/packages/packages_windows.c diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c index 9e7f1e481..55ba7d6e0 100644 --- a/src/common/jsonconfig.c +++ b/src/common/jsonconfig.c @@ -157,6 +157,12 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* module) false; } + case 'N': { + return + tryModule(type, module, FF_NATIVERESOLUTION_MODULE_NAME, ffParseNativeResolutionJsonObject) || + false; + } + case 'O': { return tryModule(type, module, FF_OPENCL_MODULE_NAME, ffParseOpenCLJsonObject) || diff --git a/src/detection/nativeresolution/nativeresolution.h b/src/detection/nativeresolution/nativeresolution.h new file mode 100644 index 000000000..aa07971c1 --- /dev/null +++ b/src/detection/nativeresolution/nativeresolution.h @@ -0,0 +1,10 @@ +#include "fastfetch.h" + +typedef struct FFNativeResolutionResult +{ + FFstrbuf name; + uint32_t width; + uint32_t height; +} FFNativeResolutionResult; + +const char* ffDetectNativeResolution(FFlist* results); diff --git a/src/detection/nativeresolution/nativeresolution_nosupport.c b/src/detection/nativeresolution/nativeresolution_nosupport.c new file mode 100644 index 000000000..6731a0dde --- /dev/null +++ b/src/detection/nativeresolution/nativeresolution_nosupport.c @@ -0,0 +1,6 @@ +#include "nativeresolution.h" + +const char* ffDetectNativeResolution(FF_MAYBE_UNUSED FFlist* results) +{ + return "Not supported on this platform"; +} diff --git a/src/fastfetch.c b/src/fastfetch.c index 2e7faf24b..6f451ab84 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1018,6 +1018,7 @@ static void parseOption(FFdata* data, const char* key, const char* value) else if(ffParseWeatherCommandOptions(&instance.config.weather, key, value)) {} else if(ffParsePlayerCommandOptions(&instance.config.player, key, value)) {} else if(ffParseMediaCommandOptions(&instance.config.media, key, value)) {} + else if(ffParseNativeResolutionCommandOptions(&instance.config.nativeResolution, key, value)) {} else if(ffParseDateTimeCommandOptions(&instance.config.dateTime, key, value)) {} else if(ffParseVulkanCommandOptions(&instance.config.vulkan, key, value)) {} else if(ffParseOpenGLCommandOptions(&instance.config.openGL, key, value)) {} @@ -1251,6 +1252,8 @@ static void parseStructureCommand(const char* line, FFlist* customValues) ffPrintPlayer(&instance.config.player); else if(ffStrEqualsIgnCase(line, FF_MEDIA_MODULE_NAME)) ffPrintMedia(&instance.config.media); + else if(ffStrEqualsIgnCase(line, FF_NATIVERESOLUTION_MODULE_NAME)) + ffPrintNativeResolution(&instance.config.nativeResolution); else if(ffStrEqualsIgnCase(line, FF_DATETIME_MODULE_NAME)) ffPrintDateTime(&instance.config.dateTime); else if(ffStrEqualsIgnCase(line, FF_COLORS_MODULE_NAME)) diff --git a/src/fastfetch.h b/src/fastfetch.h index b261654ee..09501bd5f 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -110,6 +110,7 @@ typedef struct FFconfig FFWeatherOptions weather; FFPlayerOptions player; FFMediaOptions media; + FFNativeResolutionOptions nativeResolution; FFDateTimeOptions dateTime; FFVulkanOptions vulkan; FFOpenGLOptions openGL; diff --git a/src/modules/modules.h b/src/modules/modules.h index f2a6f6799..70521efd0 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -30,6 +30,7 @@ #include "modules/localip/localip.h" #include "modules/media/media.h" #include "modules/memory/memory.h" +#include "modules/nativeresolution/nativeresolution.h" #include "modules/opengl/opengl.h" #include "modules/opencl/opencl.h" #include "modules/os/os.h" diff --git a/src/modules/nativeresolution/nativeresolution.c b/src/modules/nativeresolution/nativeresolution.c new file mode 100644 index 000000000..bbdc25ab7 --- /dev/null +++ b/src/modules/nativeresolution/nativeresolution.c @@ -0,0 +1,106 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/nativeresolution/nativeresolution.h" +#include "modules/nativeresolution/nativeresolution.h" +#include "util/stringUtils.h" + +#define FF_NATIVERESOLUTION_DISPLAY_NAME "Native Resolution" +#define FF_NATIVERESOLUTION_NUM_FORMAT_ARGS 3 + +void ffPrintNativeResolution(FFNativeResolutionOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFNativeResolutionResult)); + + const char* error = ffDetectNativeResolution(&result); + + if(error) + { + ffPrintError(FF_NATIVERESOLUTION_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error); + return; + } + + if(!result.length) + { + ffPrintError(FF_NATIVERESOLUTION_DISPLAY_NAME, 0, &options->moduleArgs, "No devices detected"); + return; + } + + uint8_t index = 0; + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); + FF_LIST_FOR_EACH(FFNativeResolutionResult, display, result) + { + if(options->moduleArgs.outputFormat.length == 0) + { + ffStrbufClear(&key); + if(options->moduleArgs.key.length == 0) + { + ffStrbufAppendF(&key, "%s (%s)", FF_NATIVERESOLUTION_DISPLAY_NAME, display->name.chars); + } + else + { + ffParseFormatString(&key, &options->moduleArgs.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &display->name}, + }); + } + ffPrintLogoAndKey(key.chars, 0, NULL, &options->moduleArgs.keyColor); + + printf("%ux%u", display->width, display->height); + } + else + { + ffPrintFormat(FF_NATIVERESOLUTION_DISPLAY_NAME, index, &options->moduleArgs, FF_NATIVERESOLUTION_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &display->name}, + {FF_FORMAT_ARG_TYPE_UINT, &display->width}, + {FF_FORMAT_ARG_TYPE_UINT, &display->height}, + }); + } + + ffStrbufDestroy(&display->name); + } +} + +void ffInitNativeResolutionOptions(FFNativeResolutionOptions* options) +{ + options->moduleName = FF_NATIVERESOLUTION_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); +} + +bool ffParseNativeResolutionCommandOptions(FFNativeResolutionOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_NATIVERESOLUTION_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffDestroyNativeResolutionOptions(FFNativeResolutionOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +void ffParseNativeResolutionJsonObject(yyjson_val* module) +{ + FFNativeResolutionOptions __attribute__((__cleanup__(ffDestroyNativeResolutionOptions))) options; + ffInitNativeResolutionOptions(&options); + + if (module) + { + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options.moduleArgs)) + continue; + + ffPrintError(FF_NATIVERESOLUTION_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintNativeResolution(&options); +} diff --git a/src/modules/nativeresolution/nativeresolution.h b/src/modules/nativeresolution/nativeresolution.h new file mode 100644 index 000000000..e7d065394 --- /dev/null +++ b/src/modules/nativeresolution/nativeresolution.h @@ -0,0 +1,11 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_NATIVERESOLUTION_MODULE_NAME "NativeResolution" + +void ffPrintNativeResolution(FFNativeResolutionOptions* options); +void ffInitNativeResolutionOptions(FFNativeResolutionOptions* options); +bool ffParseNativeResolutionCommandOptions(FFNativeResolutionOptions* options, const char* key, const char* value); +void ffDestroyNativeResolutionOptions(FFNativeResolutionOptions* options); +void ffParseNativeResolutionJsonObject(yyjson_val* module); diff --git a/src/modules/nativeresolution/option.h b/src/modules/nativeresolution/option.h new file mode 100644 index 000000000..7c5f6fdd7 --- /dev/null +++ b/src/modules/nativeresolution/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFNativeResolutionOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; +} FFNativeResolutionOptions; diff --git a/src/modules/options.h b/src/modules/options.h index 7d9c0668d..c93103387 100644 --- a/src/modules/options.h +++ b/src/modules/options.h @@ -29,6 +29,7 @@ #include "modules/localip/option.h" #include "modules/media/option.h" #include "modules/memory/option.h" +#include "modules/nativeresolution/option.h" #include "modules/opengl/option.h" #include "modules/opencl/option.h" #include "modules/os/option.h"