diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f5709dd0..5c0370619 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,6 +229,7 @@ set(LIBFASTFETCH_SRC src/modules/memory.c src/modules/disk.c src/modules/battery.c + src/modules/poweradapter.c src/modules/locale.c src/modules/vulkan.c src/modules/localip.c @@ -259,6 +260,7 @@ endif() if(LINUX OR ANDROID OR BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage_linux.c + src/detection/battery/battery_linux.c ) endif() @@ -268,6 +270,7 @@ if(LINUX OR BSD) src/detection/os/os_linux.c src/detection/gpu/gpu_linux.c src/detection/battery/battery_linux.c + src/detection/poweradapter/poweradapter_linux.c src/detection/displayserver/linux/displayserver_linux.c src/detection/displayserver/linux/wayland.c src/detection/displayserver/linux/xcb.c @@ -288,6 +291,7 @@ if(APPLE) src/detection/cpu/cpu_apple.c src/detection/gpu/gpu_apple.c src/detection/battery/battery_apple.c + src/detection/poweradapter/poweradapter_apple.c src/detection/memory/memory_apple.c src/detection/displayserver/displayserver_apple.c src/detection/terminalfont/terminalfont_apple.c diff --git a/README.md b/README.md index 761fd167d..f83bfe734 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ All categories not listed here should work without needing a specific implementa ##### Available Modules ``` -Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom +Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom ``` ##### Logos diff --git a/completions/bash b/completions/bash index 74e6d10ea..47877db6f 100644 --- a/completions/bash +++ b/completions/bash @@ -30,6 +30,7 @@ __fastfetch_complete_help() "swap-format" "disk-format" "battery-format" + "poweradapter-format" "locale-format" "local-ip-format" "public-ip-format" @@ -284,6 +285,9 @@ __fastfetch_completion() "--battery-key" "--battery-format" "--battery-error" + "--poweradapter-key" + "--poweradapter-format" + "--poweradapter-error" "--locale-key" "--locale-format" "--locale-error" diff --git a/presets/all b/presets/all index 486d03ccd..104f28551 100644 --- a/presets/all +++ b/presets/all @@ -1 +1 @@ ---structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Break:Colors +--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Break:Colors diff --git a/presets/verbose b/presets/verbose index 516e4d6ca..2f9b41438 100644 --- a/presets/verbose +++ b/presets/verbose @@ -21,6 +21,7 @@ --memory-format Used: {}; Total: {}; Percentage: {} --disk-format Used: {}; Total: {}; Files: {}; Percentage: {} --battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {} +--poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {} --player-format Pretty: {}; Name: {}; Bus: {}; Url: {} --media-format Pretty: {}; Name: {}; Artist: {}; Album: {} --datetime-format year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {} diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 5050ba646..c41027baf 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -209,6 +209,7 @@ #--swap-key Swap #--disk-key Disk ({1}) #--battery-key Battery {1} +#--poweradapter-key Power Adapter {1} #--locale-key Locale #--local-ip-key Local IP ({1}) #--public-ip-key Public IP @@ -248,6 +249,7 @@ #--swap-format #--disk-format #--battery-format +#--poweradapter-format #--locale-format #--local-ip-format #--public-ip-format @@ -287,6 +289,7 @@ #--swap-error #--disk-error #--battery-error +#--poweradapter-error #--locale-error #--local-ip-error #--public-ip-error diff --git a/src/data/modules.txt b/src/data/modules.txt index 88528fcc2..0177c4b5d 100644 --- a/src/data/modules.txt +++ b/src/data/modules.txt @@ -24,6 +24,7 @@ Packages Player Processes PublicIP +PowerAdapter Resolution Separator Shell diff --git a/src/data/structure.txt b/src/data/structure.txt index f7b0006a8..e47d27847 100644 --- a/src/data/structure.txt +++ b/src/data/structure.txt @@ -1 +1 @@ -Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Locale:Break:Colors \ No newline at end of file +Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:PowerAdapter:Locale:Break:Colors diff --git a/src/detection/battery/battery.h b/src/detection/battery/battery.h index f1d6c6c28..e7c2a859a 100644 --- a/src/detection/battery/battery.h +++ b/src/detection/battery/battery.h @@ -12,8 +12,6 @@ typedef struct BatteryResult FFstrbuf technology; FFstrbuf capacity; FFstrbuf status; - FFstrbuf adapterName; - int adapterWatts; } BatteryResult; const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results); diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index f918b075f..8fa956c77 100644 --- a/src/detection/battery/battery_apple.c +++ b/src/detection/battery/battery_apple.c @@ -69,16 +69,6 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) else ffStrbufAppendS(&battery->status, ""); - ffStrbufInit(&battery->adapterName); - battery->adapterWatts = -1; - - CFDictionaryRef adapter; - if(!ffCfDictGetDict(properties, CFSTR("AdapterDetails"), &adapter)) - { - ffCfDictGetInt(adapter, CFSTR("Watts"), &battery->adapterWatts); - ffCfDictGetString(adapter, CFSTR("Name"), &battery->adapterName); - } - CFRelease(properties); IOObjectRelease(registryEntry); } diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c index d3de381b4..909ed493f 100644 --- a/src/detection/battery/battery_linux.c +++ b/src/detection/battery/battery_linux.c @@ -70,9 +70,6 @@ static void parseBattery(FFstrbuf* dir, FFlist* results) ffStrbufAppendS(dir, "/status"); ffReadFileBuffer(dir->chars, &result->status); ffStrbufSubstrBefore(dir, dirLength); - - ffStrbufInitA(&result->adapterName, 0); - result->adapterWatts = -1; } const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) { diff --git a/src/detection/poweradapter/poweradapter.h b/src/detection/poweradapter/poweradapter.h new file mode 100644 index 000000000..c7f5ee7dc --- /dev/null +++ b/src/detection/poweradapter/poweradapter.h @@ -0,0 +1,22 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_poweradapter_poweradapter +#define FF_INCLUDED_detection_poweradapter_poweradapter + +#include "fastfetch.h" + +typedef struct PowerAdapterResult +{ + FFstrbuf description; + FFstrbuf name; + FFstrbuf modelName; + FFstrbuf manufacturer; + int watts; +} PowerAdapterResult; + +const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results); + +#define FF_POWER_ADAPTER_UNSET -2 +#define FF_POWER_ADAPTER_NOT_CONNECTED -1 + +#endif diff --git a/src/detection/poweradapter/poweradapter_apple.c b/src/detection/poweradapter/poweradapter_apple.c new file mode 100644 index 000000000..c14ff8c4e --- /dev/null +++ b/src/detection/poweradapter/poweradapter_apple.c @@ -0,0 +1,58 @@ +#include "fastfetch.h" +#include "poweradapter.h" +#include "util/apple/cf_helpers.h" + +#include + +const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results) +{ + FF_UNUSED(instance); + + CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery"); + if (matchDict == NULL) + return "IOServiceMatching(\"AppleSmartBattery\") failed"; + + io_iterator_t iterator; + if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess) + return "IOServiceGetMatchingServices() failed"; + + io_registry_entry_t registryEntry; + while((registryEntry = IOIteratorNext(iterator)) != 0) + { + CFMutableDictionaryRef properties; + if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) + { + IOObjectRelease(registryEntry); + continue; + } + + PowerAdapterResult* adapter = ffListAdd(results); + + ffStrbufInit(&adapter->name); + ffStrbufInit(&adapter->description); + ffStrbufInit(&adapter->manufacturer); + ffStrbufInit(&adapter->modelName); + adapter->watts = FF_POWER_ADAPTER_UNSET; + + CFDictionaryRef adapterDict; + if(!ffCfDictGetDict(properties, CFSTR("AdapterDetails"), &adapterDict)) + { + if (ffCfDictGetInt(adapterDict, CFSTR("Watts"), &adapter->watts)) + { + adapter->watts = FF_POWER_ADAPTER_NOT_CONNECTED; + continue; + } + ffCfDictGetString(adapterDict, CFSTR("Name"), &adapter->name); + ffCfDictGetString(adapterDict, CFSTR("Description"), &adapter->description); + ffCfDictGetString(adapterDict, CFSTR("Manufacturer"), &adapter->manufacturer); + ffCfDictGetString(adapterDict, CFSTR("Model"), &adapter->modelName); + } + + CFRelease(properties); + IOObjectRelease(registryEntry); + } + + IOObjectRelease(iterator); + + return NULL; +} diff --git a/src/detection/poweradapter/poweradapter_linux.c b/src/detection/poweradapter/poweradapter_linux.c new file mode 100644 index 000000000..4e5bebd80 --- /dev/null +++ b/src/detection/poweradapter/poweradapter_linux.c @@ -0,0 +1,7 @@ +#include "fastfetch.h" + +const char* ffDetectPowerAdapterImpl(FFinstance* instance, FFlist* results) +{ + FF_UNUSED(instance, results); + return "Unimplemented"; +} diff --git a/src/fastfetch.c b/src/fastfetch.c index a6f3f1cfa..6c43171be 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -318,6 +318,16 @@ static inline void printCommandHelp(const char* command) "Battery status" ); } + else if(strcasecmp(command, "poweradapter-format") == 0) + { + constructAndPrintCommandHelpFormat("poweradapter", "{}%, {}", 5, + "PowerAdapter watts", + "PowerAdapter name", + "PowerAdapter manufacturer", + "PowerAdapter model", + "PowerAdapter description" + ); + } else if(strcasecmp(command, "locale-format") == 0) { constructAndPrintCommandHelpFormat("locale", "{}", 1, @@ -1117,11 +1127,11 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.battery.outputFormat); else if(strcasecmp(key, "--battery-error") == 0) optionParseString(key, value, &instance->config.battery.errorFormat); - else if(strcasecmp(key, "--power-adapter-key") == 0) + else if(strcasecmp(key, "--poweradapter-key") == 0) optionParseString(key, value, &instance->config.powerAdapter.key); - else if(strcasecmp(key, "--power-adapter-format") == 0) + else if(strcasecmp(key, "--poweradapter-format") == 0) optionParseString(key, value, &instance->config.powerAdapter.outputFormat); - else if(strcasecmp(key, "--power-adapter-error") == 0) + else if(strcasecmp(key, "--poweradapter-error") == 0) optionParseString(key, value, &instance->config.powerAdapter.errorFormat); else if(strcasecmp(key, "--locale-key") == 0) optionParseString(key, value, &instance->config.locale.key); @@ -1388,6 +1398,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char ffPrintDisk(instance); else if(strcasecmp(line, "battery") == 0) ffPrintBattery(instance); + else if(strcasecmp(line, "poweradapter") == 0) + ffPrintPowerAdapter(instance); else if(strcasecmp(line, "locale") == 0) ffPrintLocale(instance); else if(strcasecmp(line, "localip") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index eee04061d..21f2920e7 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -255,6 +255,7 @@ void ffPrintMemory(FFinstance* instance); void ffPrintSwap(FFinstance* instance); //Also in modules/memory.c void ffPrintDisk(FFinstance* instance); void ffPrintBattery(FFinstance* instance); +void ffPrintPowerAdapter(FFinstance* instance); void ffPrintLocale(FFinstance* instance); void ffPrintPlayer(FFinstance* instance); void ffPrintSong(FFinstance* instance); diff --git a/src/flashfetch.c b/src/flashfetch.c index ee345bdd5..8688b918c 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -40,6 +40,7 @@ int main(int argc, char** argv) //ffPrintSwap(&instance); ffPrintDisk(&instance); ffPrintBattery(&instance); + ffPrintPowerAdapter(&instance); //ffPrintPlayer(&instance); //ffPrintSong(&instance); //ffPrintLocalIp(&instance); diff --git a/src/modules/battery.c b/src/modules/battery.c index 4c1a46f92..8900ef2ec 100644 --- a/src/modules/battery.c +++ b/src/modules/battery.c @@ -5,9 +5,6 @@ #define FF_BATTERY_MODULE_NAME "Battery" #define FF_BATTERY_NUM_FORMAT_ARGS 5 -#define FF_POWER_ADAPTER_MODULE_NAME "Power Adapter" -#define FF_POWER_ADAPTER_MODULE_ARGS 2 - static void printBattery(FFinstance* instance, const BatteryResult* result, uint8_t index) { if(instance->config.battery.outputFormat.length == 0) @@ -47,26 +44,6 @@ static void printBattery(FFinstance* instance, const BatteryResult* result, uint {FF_FORMAT_ARG_TYPE_STRBUF, &result->status} }); } - - if(result->adapterWatts != -1) - { - if(instance->config.powerAdapter.outputFormat.length == 0) - { - ffPrintLogoAndKey(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter.key); - - if(result->adapterName.length > 0) - puts(result->adapterName.chars); - else - printf("%dW\n", result->adapterWatts); - } - else - { - ffPrintFormat(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter, FF_POWER_ADAPTER_MODULE_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_INT, &result->adapterWatts}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->adapterName}, - }); - } - } } void ffPrintBattery(FFinstance* instance) diff --git a/src/modules/poweradapter.c b/src/modules/poweradapter.c new file mode 100644 index 000000000..c2cd7550d --- /dev/null +++ b/src/modules/poweradapter.c @@ -0,0 +1,66 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/poweradapter/poweradapter.h" + +#define FF_POWER_ADAPTER_MODULE_NAME "Power Adapter" +#define FF_POWER_ADAPTER_MODULE_ARGS 5 + +static void printPowerAdapter(FFinstance* instance, const PowerAdapterResult* result, uint8_t index) +{ + if(result->watts != FF_POWER_ADAPTER_UNSET) + { + if(instance->config.powerAdapter.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter.key); + + if(result->name.length > 0) + puts(result->name.chars); + else if(result->watts == FF_POWER_ADAPTER_NOT_CONNECTED) + puts("not connected"); + else + printf("%dW\n", result->watts); + } + else + { + ffPrintFormat(instance, FF_POWER_ADAPTER_MODULE_NAME, index, &instance->config.powerAdapter, FF_POWER_ADAPTER_MODULE_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_INT, &result->watts}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->description}, + }); + } + } +} + +void ffPrintPowerAdapter(FFinstance* instance) +{ + FFlist results; + ffListInitA(&results, sizeof(PowerAdapterResult), 0); + + const char* error = ffDetectPowerAdapterImpl(instance, &results); + + if (error) + { + ffPrintError(instance, FF_POWER_ADAPTER_MODULE_NAME, 0, &instance->config.powerAdapter, "%s", error); + } + else if(results.length == 0) + { + ffPrintError(instance, FF_POWER_ADAPTER_MODULE_NAME, 0, &instance->config.powerAdapter, "No power adapters found"); + } + else + { + for(uint8_t i = 0; i < (uint8_t) results.length; i++) + { + PowerAdapterResult* result = ffListGet(&results, i); + printPowerAdapter(instance, result, i); + + ffStrbufDestroy(&result->manufacturer); + ffStrbufDestroy(&result->description); + ffStrbufDestroy(&result->modelName); + ffStrbufDestroy(&result->name); + } + } + + ffListDestroy(&results); +} diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index d08e91434..e6f705f52 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -549,6 +549,8 @@ uint16_t ffStrbufToUInt16(const FFstrbuf* strbuf, uint16_t defaultValue) void ffStrbufDestroy(FFstrbuf* strbuf) { + if(strbuf->allocated == 0) return; + //Avoid free-after-use. These 3 assignments are cheap so don't remove them strbuf->allocated = strbuf->length = 0; free(strbuf->chars); diff --git a/tests/strbuf.c b/tests/strbuf.c index a096498fb..a82180d60 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -24,6 +24,10 @@ int main(int argc, char** argv) FFstrbuf strbuf; + //destroy 0 + ffStrbufInitA(&strbuf, 0); + ffStrbufDestroy(&strbuf); + //initA ffStrbufInitA(&strbuf, 0);