Display: init support of JSON config

This commit is contained in:
李通洲
2023-03-10 10:56:36 +08:00
parent da81111575
commit 04180a7389
19 changed files with 318 additions and 168 deletions
-108
View File
@@ -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");
}
+218
View File
@@ -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
+14
View File
@@ -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
+22
View File
@@ -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;
+2
View File
@@ -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)
+1
View File
@@ -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"
+1
View File
@@ -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"