master ohmu/fastfetch-openbsd / src / detection / battery / battery_obsd.c
ohmu  ·  2026-10-15
 1#include "battery.h"
 2#include "common/debug.h"
 3#include "common/io.h"
 4
 5#include <string.h>
 6#include <machine/apmvar.h>
 7#include <sys/ioctl.h>
 8#include <unistd.h>
 9#include <fcntl.h>
10
11const char* ffDetectBattery([[maybe_unused]] FFBatteryOptions* options, FFlist* result) {
12    FF_AUTO_CLOSE_FD int devfd = open("/dev/apm", O_RDONLY | O_CLOEXEC);
13
14    if (devfd < 0) {
15        FF_DEBUG("open(\"/dev/apm\") failed: %s", strerror(errno));
16        return "open(dev/apm, O_RDONLY | O_CLOEXEC) failed";
17    }
18
19    struct apm_power_info info = {};
20
21    if (ioctl(devfd, APM_IOC_GETPOWER, &info) < 0) {
22        FF_DEBUG("ioctl(APM_IOC_GETPOWER) failed: %s", strerror(errno));
23        return "ioctl(APM_IOC_GETPOWER) failed";
24    }
25
26    if (info.battery_state == APM_BATTERY_ABSENT) {
27        return nullptr;
28    }
29
30    FFBatteryResult* battery = FF_LIST_ADD(FFBatteryResult, *result);
31    battery->temperature = FF_BATTERY_TEMP_UNSET;
32    battery->cycleCount = 0;
33    battery->timeRemaining = -1;
34    battery->capacity = info.battery_life;
35    ffStrbufInit(&battery->manufacturer);
36    ffStrbufInit(&battery->modelName);
37    ffStrbufInit(&battery->technology);
38    ffStrbufInit(&battery->serial);
39    ffStrbufInit(&battery->manufactureDate);
40    battery->status = FF_BATTERY_STATUS_NONE;
41
42    if (info.ac_state == APM_AC_ON || info.ac_state == APM_AC_BACKUP) {
43        battery->status |= FF_BATTERY_STATUS_AC_CONNECTED;
44    } else if (info.ac_state == APM_AC_OFF) {
45        battery->timeRemaining = (int) info.minutes_left * 60;
46        battery->status |= FF_BATTERY_STATUS_DISCHARGING;
47    }
48
49    if (info.battery_state == APM_BATT_CRITICAL || info.battery_state == APM_BATT_CHARGING || info.battery_state == APM_BATT_UNKNOWN) {
50        switch (info.battery_state) {
51            case APM_BATT_UNKNOWN:
52                battery->status |= FF_BATTERY_STATUS_UNKNOWN;
53                break;
54            case APM_BATT_CHARGING:
55                battery->status |= FF_BATTERY_STATUS_CHARGING;
56                break;
57            case APM_BATT_CRITICAL:
58                battery->status |= FF_BATTERY_STATUS_CRITICAL;
59                break;
60        }
61    }
62
63    return nullptr;
64}