From 5c75e271ef6c51f417744f4d1fcab8d0a487bd52 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 4 Jan 2024 13:54:11 +0800 Subject: [PATCH] PowerAdapter (Linux): add support --- CMakeLists.txt | 2 +- src/detection/poweradapter/poweradapter.h | 2 +- .../poweradapter/poweradapter_apple.c | 2 +- .../poweradapter/poweradapter_linux.c | 96 +++++++++++++++++++ .../poweradapter/poweradapter_nosupport.c | 5 +- src/modules/poweradapter/poweradapter.c | 4 +- 6 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 src/detection/poweradapter/poweradapter_linux.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 83d9105e5..4e0624a46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -422,7 +422,7 @@ if(LINUX) src/detection/opengl/opengl_linux.c src/detection/os/os_linux.c src/detection/packages/packages_linux.c - src/detection/poweradapter/poweradapter_nosupport.c + src/detection/poweradapter/poweradapter_linux.c src/detection/processes/processes_linux.c src/detection/gtk_qt/qt.c src/detection/sound/sound_linux.c diff --git a/src/detection/poweradapter/poweradapter.h b/src/detection/poweradapter/poweradapter.h index 21c93b64a..405480690 100644 --- a/src/detection/poweradapter/poweradapter.h +++ b/src/detection/poweradapter/poweradapter.h @@ -11,7 +11,7 @@ typedef struct FFPowerAdapterResult int watts; } FFPowerAdapterResult; -const char* ffDetectPowerAdapterImpl(FFlist* results); +const char* ffDetectPowerAdapter(FFlist* results); #define FF_POWERADAPTER_UNSET -2 #define FF_POWERADAPTER_NOT_CONNECTED -1 diff --git a/src/detection/poweradapter/poweradapter_apple.c b/src/detection/poweradapter/poweradapter_apple.c index 435532ee4..7c17a4f0b 100644 --- a/src/detection/poweradapter/poweradapter_apple.c +++ b/src/detection/poweradapter/poweradapter_apple.c @@ -4,7 +4,7 @@ #include -const char* ffDetectPowerAdapterImpl(FFlist* results) +const char* ffDetectPowerAdapter(FFlist* results) { io_iterator_t iterator; if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleSmartBattery"), &iterator) != kIOReturnSuccess) diff --git a/src/detection/poweradapter/poweradapter_linux.c b/src/detection/poweradapter/poweradapter_linux.c new file mode 100644 index 000000000..b514c2590 --- /dev/null +++ b/src/detection/poweradapter/poweradapter_linux.c @@ -0,0 +1,96 @@ +#include "poweradapter.h" +#include "common/io/io.h" +#include "util/stringUtils.h" + +#include + +static void parsePowerAdapter(FFstrbuf* dir, FF_MAYBE_UNUSED const char* id, FFlist* results) +{ + uint32_t dirLength = dir->length; + + FF_STRBUF_AUTO_DESTROY tmpBuffer = ffStrbufCreate(); + + //type must exist and be "Mains" + ffStrbufAppendS(dir, "/type"); + if (ffReadFileBuffer(dir->chars, &tmpBuffer)) + ffStrbufTrimRightSpace(&tmpBuffer); + ffStrbufSubstrBefore(dir, dirLength); + + if(!ffStrbufIgnCaseEqualS(&tmpBuffer, "Mains")) + return; + + //scope may not exist or must not be "Device" (?) + ffStrbufAppendS(dir, "/scope"); + if (ffReadFileBuffer(dir->chars, &tmpBuffer)) + ffStrbufTrimRightSpace(&tmpBuffer); + ffStrbufSubstrBefore(dir, dirLength); + + if(ffStrbufIgnCaseEqualS(&tmpBuffer, "Device")) + return; + + //input_power_limit must exist and be not empty + ffStrbufAppendS(dir, "/input_power_limit"); + bool available = ffReadFileBuffer(dir->chars, &tmpBuffer); + ffStrbufSubstrBefore(dir, dirLength); + + if (!available) + return; + + FFPowerAdapterResult* result = ffListAdd(results); + ffStrbufInit(&result->name); + ffStrbufInit(&result->description); + + ffStrbufAppendS(dir, "/online"); + char online = '1'; + ffReadFileData(dir->chars, sizeof(online), &online); + ffStrbufSubstrBefore(dir, dirLength); + + if (online == '0') + result->watts = FF_POWERADAPTER_NOT_CONNECTED; + else + result->watts = (int) (ffStrbufToDouble(&tmpBuffer) / 1e6 + 0.5); + + //At this point, we have a battery. Try to get as much values as possible. + + ffStrbufInit(&result->manufacturer); + ffStrbufAppendS(dir, "/manufacturer"); + if (ffReadFileBuffer(dir->chars, &result->manufacturer)) + ffStrbufTrimRightSpace(&result->manufacturer); + else if (ffStrEquals(id, "macsmc-ac")) // asahi + ffStrbufSetStatic(&result->manufacturer, "Apple Inc."); + ffStrbufSubstrBefore(dir, dirLength); + + ffStrbufInit(&result->modelName); + ffStrbufAppendS(dir, "/model_name"); + if (ffReadFileBuffer(dir->chars, &result->modelName)) + ffStrbufTrimRightSpace(&result->modelName); + ffStrbufSubstrBefore(dir, dirLength); +} + +const char* ffDetectPowerAdapter(FFlist* results) +{ + FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64); + ffStrbufAppendS(&baseDir, "/sys/class/power_supply/"); + + uint32_t baseDirLength = baseDir.length; + + FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars); + if(dirp == NULL) + return "opendir(\"/sys/class/power_supply/\") == NULL"; + + struct dirent* entry; + while((entry = readdir(dirp)) != NULL) + { + if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, "..")) + continue; + + ffStrbufAppendS(&baseDir, entry->d_name); + parsePowerAdapter(&baseDir, entry->d_name, results); + ffStrbufSubstrBefore(&baseDir, baseDirLength); + } + + if(results->length == 0) + return "\"/sys/class/power_supply/\" doesn't contain any power adapter folder"; + + return NULL; +} diff --git a/src/detection/poweradapter/poweradapter_nosupport.c b/src/detection/poweradapter/poweradapter_nosupport.c index 80730810d..1ae9d5395 100644 --- a/src/detection/poweradapter/poweradapter_nosupport.c +++ b/src/detection/poweradapter/poweradapter_nosupport.c @@ -1,7 +1,6 @@ -#include "fastfetch.h" +#include "poweradapter.h" -const char* ffDetectPowerAdapterImpl(FFlist* results) +const char* ffDetectPowerAdapter(FF_MAYBE_UNUSED FFlist* results) { - FF_UNUSED(results); return "Not supported on this platform"; } diff --git a/src/modules/poweradapter/poweradapter.c b/src/modules/poweradapter/poweradapter.c index 3ce00a771..a4f599d4b 100644 --- a/src/modules/poweradapter/poweradapter.c +++ b/src/modules/poweradapter/poweradapter.c @@ -11,7 +11,7 @@ void ffPrintPowerAdapter(FFPowerAdapterOptions* options) { FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFPowerAdapterResult)); - const char* error = ffDetectPowerAdapterImpl(&results); + const char* error = ffDetectPowerAdapter(&results); if (error) { @@ -99,7 +99,7 @@ void ffGeneratePowerAdapterJsonResult(FF_MAYBE_UNUSED FFPowerAdapterOptions* opt { FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFPowerAdapterResult)); - const char* error = ffDetectPowerAdapterImpl(&results); + const char* error = ffDetectPowerAdapter(&results); if (error) {