From fdcdc54ec45d4512ec8ad9524362e808d1928569 Mon Sep 17 00:00:00 2001 From: nia Date: Mon, 26 Jul 2021 19:04:44 +0200 Subject: netbsd: Add battery support This uses proplib and sysmon_envsys to determine the total charge percentage of any number of connected batteries as well as the AC adapter state. Should work with ACPI and non-ACPI systems. --- netbsd/Platform.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- netbsd/README.md | 1 - 2 files changed, 103 insertions(+), 4 deletions(-) (limited to 'netbsd') diff --git a/netbsd/Platform.c b/netbsd/Platform.c index d3840ad1..d26c29cb 100644 --- a/netbsd/Platform.c +++ b/netbsd/Platform.c @@ -3,6 +3,7 @@ htop - netbsd/Platform.c (C) 2014 Hisham H. Muhammad (C) 2015 Michael McConville (C) 2021 Santhosh Raju +(C) 2021 Nia Alarie (C) 2021 htop dev team Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. @@ -11,12 +12,18 @@ in the source distribution for its full text. #include "netbsd/Platform.h" #include +#include +#include +#include #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -323,7 +330,100 @@ bool Platform_getNetworkIO(NetworkIOData* data) { } void Platform_getBattery(double* percent, ACPresence* isOnAC) { - // TODO - (void)percent; - (void)isOnAC; + int fd; + bool isACAD, isBattery; + int64_t isPresent, isConnected; + int64_t curCharge, maxCharge; + int64_t totalCharge, totalCapacity; + prop_dictionary_t dict, fields, props; + prop_object_iterator_t devIter, fieldsIter; + prop_object_t device, class, fieldsArray, curValue, maxValue, descField; + + totalCharge = 0; + totalCapacity = 0; + + *percent = NAN; + *isOnAC = AC_ERROR; + + fd = open(_PATH_SYSMON, O_RDONLY); + if (fd == -1) + goto error; + + if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &dict) != 0) + goto error; + + devIter = prop_dictionary_iterator(dict); + if (devIter == NULL) + goto error; + + while ((device = prop_object_iterator_next(devIter)) != NULL) { + fieldsArray = prop_dictionary_get_keysym(dict, device); + if (fieldsArray == NULL) + goto error; + + fieldsIter = prop_array_iterator(fieldsArray); + if (fieldsIter == NULL) + goto error; + + isACAD = false; + isBattery = false; + + /* only assume battery is not present if explicitly stated */ + isPresent = 1; + isConnected = 0; + curCharge = 0; + maxCharge = 0; + + while ((fields = prop_object_iterator_next(fieldsIter)) != NULL) { + props = prop_dictionary_get(fields, "device-properties"); + if (props != NULL) { + class = prop_dictionary_get(props, "device-class"); + + /* + * After NetBSD 11's release NetBSD 9 will no longer be supported + * and these should be converted to prop_string_equals_string. + */ + + if (prop_string_equals_cstring(class, "ac-adapter")) { + isACAD = true; + } else if (prop_string_equals_cstring(class, "battery")) { + isBattery = true; + } + continue; + } + + curValue = prop_dictionary_get(fields, "cur-value"); + maxValue = prop_dictionary_get(fields, "max-value"); + descField = prop_dictionary_get(fields, "description"); + + if (descField == NULL || curValue == NULL) + continue; + + if (prop_string_equals_cstring(descField, "connected")) { + isConnected = prop_number_integer_value(curValue); + } else if (prop_string_equals_cstring(descField, "present")) { + isPresent = prop_number_integer_value(curValue); + } else if (prop_string_equals_cstring(descField, "charge")) { + if (maxValue == NULL) + continue; + curCharge = prop_number_integer_value(curValue); + maxCharge = prop_number_integer_value(maxValue); + } + } + + if (isBattery && isPresent) { + totalCharge += curCharge; + totalCapacity += maxCharge; + } + + if (isACAD) { + *isOnAC = isConnected ? AC_PRESENT : AC_ABSENT; + } + } + + *percent = ((double)totalCharge / (double)totalCapacity) * 100.0; + +error: + if (fd != -1) + close(fd); } diff --git a/netbsd/README.md b/netbsd/README.md index 1d13e76e..ed7be0a3 100644 --- a/netbsd/README.md +++ b/netbsd/README.md @@ -27,7 +27,6 @@ What needs improvement * Kernel and userspace threads are not displayed or counted - maybe look at NetBSD top(1). -* Battery display - use envsys(4). * Support for compiling using libcurses's Unicode support. * Support for fstat(1) (view open files, like lsof(8) on Linux). * Support for ktrace(1) (like strace(1) on Linux). -- cgit v1.2.3