mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-29 00:03:58 +01:00
91 lines
3.3 KiB
C
91 lines
3.3 KiB
C
#include "fastfetch.h"
|
|
#include "common/sysctl.h"
|
|
#include "common/io.h"
|
|
#include "battery.h"
|
|
|
|
#include <dev/acpica/acpiio.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
const char* ffDetectBattery([[maybe_unused]] FFBatteryOptions* options, FFlist* results) {
|
|
// https://www.freebsd.org/cgi/man.cgi?acpi_battery(4)
|
|
// https://gitlab.xfce.org/panel-plugins/xfce4-battery-plugin/-/blob/master/panel-plugin/libacpi.c
|
|
|
|
int units = ffSysctlGetInt("hw.acpi.battery.units", -100);
|
|
if (units < 0) {
|
|
return "sysctlbyname(\"hw.acpi.battery.units\") failed";
|
|
}
|
|
|
|
if (units == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
FF_AUTO_CLOSE_FD int acpifd = open("/dev/acpi", O_RDONLY | O_CLOEXEC);
|
|
if (acpifd < 0) {
|
|
return "open(\"/dev/acpi\", O_RDONLY | O_CLOEXEC) failed";
|
|
}
|
|
|
|
for (int i = 0; i < units; ++i) {
|
|
union acpi_battery_ioctl_arg battio;
|
|
battio.unit = i;
|
|
|
|
if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) < 0 || (battio.battinfo.state == ACPI_BATT_STAT_NOT_PRESENT)) {
|
|
continue;
|
|
}
|
|
|
|
FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *results);
|
|
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
|
battery->cycleCount = 0;
|
|
ffStrbufInit(&battery->manufacturer);
|
|
ffStrbufInit(&battery->modelName);
|
|
ffStrbufInit(&battery->technology);
|
|
ffStrbufInit(&battery->serial);
|
|
ffStrbufInit(&battery->manufactureDate);
|
|
battery->status = FF_BATTERY_STATUS_NONE;
|
|
battery->timeRemaining = -1;
|
|
if (battio.battinfo.min > 0) {
|
|
battery->timeRemaining = battio.battinfo.min * 60;
|
|
}
|
|
battery->capacity = battio.battinfo.cap;
|
|
if (battio.battinfo.state == ACPI_BATT_STAT_INVALID) {
|
|
battery->status |= FF_BATTERY_STATUS_UNKNOWN;
|
|
} else {
|
|
if (battio.battinfo.state & ACPI_BATT_STAT_DISCHARG) {
|
|
battery->status |= FF_BATTERY_STATUS_DISCHARGING;
|
|
}
|
|
if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING) {
|
|
battery->status |= FF_BATTERY_STATUS_CHARGING;
|
|
}
|
|
if (battio.battinfo.state & ACPI_BATT_STAT_CRITICAL) {
|
|
battery->status |= FF_BATTERY_STATUS_CRITICAL;
|
|
}
|
|
}
|
|
|
|
int acadStatus;
|
|
if (ioctl(acpifd, ACPIIO_ACAD_GET_STATUS, &acadStatus) >= 0 && acadStatus) {
|
|
battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
|
|
}
|
|
|
|
#ifdef ACPIIO_BATT_GET_BIX
|
|
battio.unit = i;
|
|
if (ioctl(acpifd, ACPIIO_BATT_GET_BIX, &battio) >= 0) {
|
|
ffStrbufAppendS(&battery->manufacturer, battio.bix.oeminfo);
|
|
ffStrbufAppendS(&battery->modelName, battio.bix.model);
|
|
ffStrbufAppendS(&battery->technology, battio.bix.type);
|
|
ffStrbufAppendS(&battery->serial, battio.bix.serial);
|
|
battery->cycleCount = battio.bix.cycles;
|
|
}
|
|
#elif defined(ACPIIO_BATT_GET_BIF)
|
|
battio.unit = i;
|
|
if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) >= 0) {
|
|
ffStrbufAppendS(&battery->manufacturer, battio.bif.oeminfo);
|
|
ffStrbufAppendS(&battery->modelName, battio.bif.model);
|
|
ffStrbufAppendS(&battery->technology, battio.bif.type);
|
|
ffStrbufAppendS(&battery->serial, battio.bif.serial);
|
|
}
|
|
#endif
|
|
}
|
|
return nullptr;
|
|
}
|