From fb2004a6f9222d6bb6e8338e6e3e62bf1371efd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 13 Mar 2023 17:36:48 +0800 Subject: [PATCH] Bluetooth: support JSON config --- CMakeLists.txt | 2 +- src/common/init.c | 6 +- src/fastfetch.c | 6 +- src/fastfetch.h | 5 +- src/modules/bluetooth.c | 64 -------------- src/modules/bluetooth/bluetooth.c | 126 ++++++++++++++++++++++++++++ src/modules/bluetooth/bluetooth.h | 13 +++ src/modules/bluetooth/option.h | 13 +++ src/modules/jsonconfig/jsonconfig.c | 1 + src/modules/modules.h | 1 + src/modules/options.h | 1 + 11 files changed, 161 insertions(+), 77 deletions(-) delete mode 100644 src/modules/bluetooth.c create mode 100644 src/modules/bluetooth/bluetooth.c create mode 100644 src/modules/bluetooth/bluetooth.h create mode 100644 src/modules/bluetooth/option.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b3b487584..e58949ddc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -263,7 +263,7 @@ set(LIBFASTFETCH_SRC src/logo/option.c src/modules/battery/battery.c src/modules/bios/bios.c - src/modules/bluetooth.c + src/modules/bluetooth/bluetooth.c src/modules/board.c src/modules/brightness.c src/modules/break.c diff --git a/src/common/init.c b/src/common/init.c index 8d2e7a48f..62a877fba 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -101,7 +101,7 @@ static void defaultConfig(FFinstance* instance) initModuleArg(&instance->config.openGL); initModuleArg(&instance->config.openCL); initModuleArg(&instance->config.users); - initModuleArg(&instance->config.bluetooth); + ffInitBluetoothOptions(&instance->config.bluetooth); initModuleArg(&instance->config.sound); ffInitSeparatorOptions(&instance->config.separator); initModuleArg(&instance->config.gamepad); @@ -145,8 +145,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.bluetoothShowDisconnected = false; - instance->config.soundType = FF_SOUND_TYPE_MAIN; instance->config.localIpShowType = FF_LOCALIP_TYPE_IPV4_BIT; @@ -338,7 +336,7 @@ static void destroyConfig(FFinstance* instance) destroyModuleArg(&instance->config.openGL); destroyModuleArg(&instance->config.openCL); destroyModuleArg(&instance->config.users); - destroyModuleArg(&instance->config.bluetooth); + ffDestroyBluetoothOptions(&instance->config.bluetooth); ffDestroySeparatorOptions(&instance->config.separator); destroyModuleArg(&instance->config.sound); destroyModuleArg(&instance->config.gamepad); diff --git a/src/fastfetch.c b/src/fastfetch.c index eb9ab31c9..89c54fbbb 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1052,7 +1052,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con else if(optionParseModuleArgs(key, value, "opengl", &instance->config.openGL)) {} else if(optionParseModuleArgs(key, value, "opencl", &instance->config.openCL)) {} else if(optionParseModuleArgs(key, value, "users", &instance->config.users)) {} - else if(optionParseModuleArgs(key, value, "bluetooth", &instance->config.bluetooth)) {} + else if(ffParseBluetoothCommandOptions(&instance->config.bluetooth, key, value)) {} else if(ffParseSeparatorCommandOptions(&instance->config.separator, key, value)) {} else if(optionParseModuleArgs(key, value, "sound", &instance->config.sound)) {} else if(optionParseModuleArgs(key, value, "gamepad", &instance->config.gamepad)) {} @@ -1148,8 +1148,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, "--bluetooth-show-disconnected") == 0) - instance->config.bluetoothShowDisconnected = optionParseBoolean(value); else if(strcasecmp(key, "--sound-type") == 0) { optionParseEnum(key, value, &instance->config.soundType, @@ -1347,7 +1345,7 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char else if(strcasecmp(line, "command") == 0) ffPrintCommand(instance, &instance->config.command); else if(strcasecmp(line, "bluetooth") == 0) - ffPrintBluetooth(instance); + ffPrintBluetooth(instance, &instance->config.bluetooth); else if(strcasecmp(line, "sound") == 0) ffPrintSound(instance); else if(strcasecmp(line, "gamepad") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index 3453f3bd5..8001cdf5d 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -135,7 +135,7 @@ typedef struct FFconfig FFModuleArgs openGL; FFModuleArgs openCL; FFModuleArgs users; - FFModuleArgs bluetooth; + FFBluetoothOptions bluetooth; FFSeparatorOptions separator; FFModuleArgs sound; FFModuleArgs gamepad; @@ -179,8 +179,6 @@ typedef struct FFconfig FFstrbuf diskFolders; FFDiskType diskShowTypes; - bool bluetoothShowDisconnected; - FFstrbuf localIpNamePrefix; FFLocalIpType localIpShowType; @@ -292,7 +290,6 @@ void ffPrintVulkan(FFinstance* instance); void ffPrintOpenGL(FFinstance* instance); void ffPrintOpenCL(FFinstance* instance); void ffPrintUsers(FFinstance* instance); -void ffPrintBluetooth(FFinstance* instance); void ffPrintSound(FFinstance* instance); void ffPrintGamepad(FFinstance* instance); diff --git a/src/modules/bluetooth.c b/src/modules/bluetooth.c deleted file mode 100644 index 6038acf01..000000000 --- a/src/modules/bluetooth.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "common/printing.h" -#include "detection/bluetooth/bluetooth.h" - -#define FF_BLUETOOTH_MODULE_NAME "Bluetooth" -#define FF_BLUETOOTH_NUM_FORMAT_ARGS 4 - -static void printDevice(FFinstance* instance, const FFBluetoothDevice* device, uint8_t index) -{ - if(instance->config.bluetooth.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_BLUETOOTH_MODULE_NAME, index, &instance->config.bluetooth.key); - ffStrbufWriteTo(&device->name, stdout); - - if(device->battery > 0) - printf(" (%d%%)", device->battery); - - putchar('\n'); - } - else - { - ffPrintFormat(instance, FF_BLUETOOTH_MODULE_NAME, index, &instance->config.bluetooth, FF_BLUETOOTH_NUM_FORMAT_ARGS, (FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->address}, - {FF_FORMAT_ARG_TYPE_STRBUF, &device->type}, - {FF_FORMAT_ARG_TYPE_UINT8, &device->battery} - }); - } -} - -void ffPrintBluetooth(FFinstance* instance) -{ - const FFBluetoothResult* bluetooth = ffDetectBluetooth(instance); - - if(bluetooth->error.length > 0) - { - ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &instance->config.bluetooth, "%s", bluetooth->error.chars); - return; - } - - FFlist filtered; - ffListInit(&filtered, sizeof(FFBluetoothDevice*)); - - FF_LIST_FOR_EACH(FFBluetoothDevice, device, bluetooth->devices) - { - if(!device->connected && !instance->config.bluetoothShowDisconnected) - continue; - - *(FFBluetoothDevice**)ffListAdd(&filtered) = device; - } - - if(filtered.length == 0) - { - ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &instance->config.bluetooth, "No bluetooth devices found"); - return; - } - - for(uint32_t i = 0; i < filtered.length; i++) - { - uint8_t index = (uint8_t) (filtered.length == 1 ? 0 : i + 1); - printDevice(instance, *(FFBluetoothDevice**)ffListGet(&filtered, i), index); - } - - ffListDestroy(&filtered); -} diff --git a/src/modules/bluetooth/bluetooth.c b/src/modules/bluetooth/bluetooth.c new file mode 100644 index 000000000..90d5c2f4d --- /dev/null +++ b/src/modules/bluetooth/bluetooth.c @@ -0,0 +1,126 @@ +#include "common/printing.h" +#include "detection/bluetooth/bluetooth.h" +#include "modules/bluetooth/bluetooth.h" + +#define FF_BLUETOOTH_MODULE_NAME "Bluetooth" +#define FF_BLUETOOTH_NUM_FORMAT_ARGS 4 + +static void printDevice(FFinstance* instance, FFBluetoothOptions* options, const FFBluetoothDevice* device, uint8_t index) +{ + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs.key); + ffStrbufWriteTo(&device->name, stdout); + + if(device->battery > 0) + printf(" (%d%%)", device->battery); + + putchar('\n'); + } + else + { + ffPrintFormat(instance, FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_BLUETOOTH_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &device->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->address}, + {FF_FORMAT_ARG_TYPE_STRBUF, &device->type}, + {FF_FORMAT_ARG_TYPE_UINT8, &device->battery} + }); + } +} + +void ffPrintBluetooth(FFinstance* instance, FFBluetoothOptions* options) +{ + const FFBluetoothResult* bluetooth = ffDetectBluetooth(instance); + + if(bluetooth->error.length > 0) + { + ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &options->moduleArgs, "%s", bluetooth->error.chars); + return; + } + + FFlist filtered; + ffListInit(&filtered, sizeof(FFBluetoothDevice*)); + + FF_LIST_FOR_EACH(FFBluetoothDevice, device, bluetooth->devices) + { + if(!device->connected && !options->showDisconnected) + continue; + + *(FFBluetoothDevice**)ffListAdd(&filtered) = device; + } + + if(filtered.length == 0) + { + ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &options->moduleArgs, "No bluetooth devices found"); + return; + } + + for(uint32_t i = 0; i < filtered.length; i++) + { + uint8_t index = (uint8_t) (filtered.length == 1 ? 0 : i + 1); + printDevice(instance, options, *(FFBluetoothDevice**)ffListGet(&filtered, i), index); + } + + ffListDestroy(&filtered); +} + +void ffInitBluetoothOptions(FFBluetoothOptions* options) +{ + options->moduleName = FF_BLUETOOTH_MODULE_NAME; + ffOptionInitModuleArg(&options->moduleArgs); + options->showDisconnected = false; +} + +bool ffParseBluetoothCommandOptions(FFBluetoothOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BLUETOOTH_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (strcasecmp(subKey, "show-disconnected") == 0) + options->showDisconnected = ffOptionParseBoolean(value); + return false; +} + +void ffDestroyBluetoothOptions(FFBluetoothOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} + +#ifdef FF_HAVE_JSONC +bool ffParseBluetoothJsonObject(FFinstance* instance, const char* type, JSONCData* data, json_object* module) +{ + if (strcasecmp(type, FF_BLUETOOTH_MODULE_NAME) != 0) + return false; + + FFBluetoothOptions __attribute__((__cleanup__(ffDestroyBluetoothOptions))) options; + ffInitBluetoothOptions(&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, "showConnected") == 0) + { + options.showDisconnected = data->ffjson_object_get_boolean(val); + continue; + } + + ffPrintError(instance, FF_BLUETOOTH_MODULE_NAME, 0, &options.moduleArgs, "Unknown JSON key %s", key); + } + } + + ffPrintBluetooth(instance, &options); + return true; +} +#endif diff --git a/src/modules/bluetooth/bluetooth.h b/src/modules/bluetooth/bluetooth.h new file mode 100644 index 000000000..500d39290 --- /dev/null +++ b/src/modules/bluetooth/bluetooth.h @@ -0,0 +1,13 @@ +#pragma once + +#include "fastfetch.h" + +void ffPrintBluetooth(FFinstance* instance, FFBluetoothOptions* options); +void ffInitBluetoothOptions(FFBluetoothOptions* options); +bool ffParseBluetoothCommandOptions(FFBluetoothOptions* options, const char* key, const char* value); +void ffDestroyBluetoothOptions(FFBluetoothOptions* options); + +#ifdef FF_HAVE_JSONC +#include "common/config.h" +bool ffParseBluetoothJsonObject(FFinstance* instance, const char* type, JSONCData* data, json_object* module); +#endif diff --git a/src/modules/bluetooth/option.h b/src/modules/bluetooth/option.h new file mode 100644 index 000000000..b347dc466 --- /dev/null +++ b/src/modules/bluetooth/option.h @@ -0,0 +1,13 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFBluetoothOptions +{ + const char* moduleName; + FFModuleArgs moduleArgs; + + bool showDisconnected; +} FFBluetoothOptions; diff --git a/src/modules/jsonconfig/jsonconfig.c b/src/modules/jsonconfig/jsonconfig.c index bd062ae7d..bcfd07f7c 100644 --- a/src/modules/jsonconfig/jsonconfig.c +++ b/src/modules/jsonconfig/jsonconfig.c @@ -15,6 +15,7 @@ static inline bool parseModuleJsonObject(FFinstance* instance, const char* type, ffParseTitleJsonObject(instance, type, data, module) || ffParseBatteryJsonObject(instance, type, data, module) || ffParseBiosJsonObject(instance, type, data, module) || + ffParseBluetoothJsonObject(instance, type, data, module) || ffParseCommandJsonObject(instance, type, data, module) || ffParseDateTimeJsonObject(instance, type, data, module) || ffParseDisplayJsonObject(instance, type, data, module) || diff --git a/src/modules/modules.h b/src/modules/modules.h index be6bac672..19a6414c7 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -5,6 +5,7 @@ #include "modules/os/os.h" #include "modules/battery/battery.h" #include "modules/bios/bios.h" +#include "modules/bluetooth/bluetooth.h" #include "modules/command/command.h" #include "modules/datetime/datetime.h" #include "modules/display/display.h" diff --git a/src/modules/options.h b/src/modules/options.h index 1b7502204..9f992996a 100644 --- a/src/modules/options.h +++ b/src/modules/options.h @@ -4,6 +4,7 @@ #include "modules/battery/option.h" #include "modules/bios/option.h" +#include "modules/bluetooth/option.h" #include "modules/command/option.h" #include "modules/datetime/option.h" #include "modules/display/option.h"