Batman: Add multi-battery support for bsd based distros.

Differential was D4670
This commit is contained in:
Al 'netstar' Poole 2017-03-13 14:59:39 -05:00 committed by Stephen 'Okra' Houston
parent 4549bf2f77
commit 4e1d079aa8
1 changed files with 219 additions and 214 deletions

View File

@ -1,41 +1,36 @@
#include <err.h> #include "batman.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#if defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__OpenBSD__) || defined(__NetBSD__)
#include <sys/param.h> # include <sys/param.h>
#include <sys/sensors.h> # include <sys/sensors.h>
#endif #endif
#include "batman.h"
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
static Eina_Bool _batman_sysctl_battery_update_poll(void *data EINA_UNUSED);
#endif
static int _batman_sysctl_battery_update(Instance *inst);
extern Eina_List *batman_device_batteries; extern Eina_List *batman_device_batteries;
extern Eina_List *batman_device_ac_adapters; extern Eina_List *batman_device_ac_adapters;
extern double batman_init_time;
static Ac_Adapter *ac = NULL; #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
static Battery *bat = NULL; static Eina_Bool _batman_sysctl_battery_update_poll(void *data);
static int _batman_sysctl_battery_update(Instance *inst);
#endif
int int
_batman_sysctl_start(Instance *inst) _batman_sysctl_start(Instance *inst)
{ {
#if defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__OpenBSD__) || defined(__NetBSD__)
int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0}; int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0};
int devn; int devn, i = 0;
struct sensordev snsrdev; struct sensordev snsrdev;
size_t sdlen = sizeof(struct sensordev); size_t sdlen = sizeof(struct sensordev);
char name[256];
#elif defined(__FreeBSD__) || defined(__DragonFly__) #elif defined(__FreeBSD__) || defined(__DragonFly__)
int result;
size_t len; size_t len;
#endif #endif
#if defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__OpenBSD__) || defined(__NetBSD__)
for (devn = 0;; devn++) { for (devn = 0;; devn++)
{
mib[2] = devn; mib[2] = devn;
if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1)
{ {
@ -45,12 +40,14 @@ _batman_sysctl_start(Instance *inst)
break; break;
} }
if (!strcmp("acpibat0", snsrdev.xname)) snprintf(name, sizeof(name), "acpibat%d", i);
if (!strcmp(name, snsrdev.xname))
{ {
if (!(bat = E_NEW(Battery, 1))) Battery *bat = E_NEW(Battery, 1);
if (!bat)
return 0; return 0;
bat->inst = inst; bat->inst = inst;
bat->udi = eina_stringshare_add("acpibat0"), bat->udi = eina_stringshare_add(name),
bat->mib = malloc(sizeof(int) * 5); bat->mib = malloc(sizeof(int) * 5);
if (!bat->mib) return 0; if (!bat->mib) return 0;
bat->mib[0] = mib[0]; bat->mib[0] = mib[0];
@ -58,93 +55,100 @@ _batman_sysctl_start(Instance *inst)
bat->mib[2] = mib[2]; bat->mib[2] = mib[2];
bat->technology = eina_stringshare_add("Unknown"); bat->technology = eina_stringshare_add("Unknown");
bat->model = eina_stringshare_add("Unknown"); bat->model = eina_stringshare_add("Unknown");
bat->last_update = ecore_time_get();
bat->vendor = eina_stringshare_add("Unknown"); bat->vendor = eina_stringshare_add("Unknown");
bat->poll = ecore_poller_add(ECORE_POLLER_CORE, bat->poll = ecore_poller_add(ECORE_POLLER_CORE,
inst->cfg->batman.poll_interval, inst->cfg->batman.poll_interval,
_batman_sysctl_battery_update_poll, inst); _batman_sysctl_battery_update_poll, inst);
batman_device_batteries = eina_list_append(batman_device_batteries, bat); batman_device_batteries = eina_list_append(batman_device_batteries, bat);
} ++i;
else if (!strcmp("acpiac0", snsrdev.xname)) }
{
if (!(ac = E_NEW(Ac_Adapter, 1))) if (!strcmp("acpiac0", snsrdev.xname))
return 0; {
ac->inst = inst; Ac_Adapter *ac = E_NEW(Ac_Adapter, 1);
ac->udi = eina_stringshare_add("acpiac0"); if (!ac) return 0;
ac->mib = malloc(sizeof(int) * 5); ac->inst = inst;
if (!ac->mib) return 0; ac->udi = eina_stringshare_add("acpiac0");
ac->mib[0] = mib[0]; ac->mib = malloc(sizeof(int) * 5);
ac->mib[1] = mib[1]; if (!ac->mib) return 0;
ac->mib[2] = mib[2]; ac->mib[0] = mib[0];
batman_device_ac_adapters = eina_list_append(batman_device_ac_adapters, ac); ac->mib[1] = mib[1];
} ac->mib[2] = mib[2];
batman_device_ac_adapters = eina_list_append(batman_device_ac_adapters, ac);
}
} }
#elif defined(__FreeBSD__) || defined(__DragonFly__) #elif defined(__FreeBSD__) || defined(__DragonFly__)
if ((sysctlbyname("hw.acpi.battery.life", NULL, &len, NULL, 0)) != -1) if ((sysctlbyname("hw.acpi.battery.life", NULL, &len, NULL, 0)) != -1)
{ {
if (!(bat = E_NEW(Battery, 1))) Battery *bat = E_NEW(Battery, 1);
return 0; if (!bat)
bat->inst = inst; return 0;
bat->mib = malloc(sizeof(int) * 4); bat->inst = inst;
if (!bat->mib) return 0; bat->mib = malloc(sizeof(int) * 4);
sysctlnametomib("hw.acpi.battery.life", bat->mib, &len); if (!bat->mib) return 0;
sysctlnametomib("hw.acpi.battery.life", bat->mib, &len);
bat->mib_state = malloc(sizeof(int) * 4); bat->mib_state = malloc(sizeof(int) * 4);
if (!bat->mib_state) return 0; if (!bat->mib_state) return 0;
sysctlnametomib("hw.acpi.battery.state", bat->mib_state, &len); sysctlnametomib("hw.acpi.battery.state", bat->mib_state, &len);
bat->mib_time = malloc(sizeof(int) * 4); bat->mib_time = malloc(sizeof(int) * 4);
if (!bat->mib_time) return 0; if (!bat->mib_time) return 0;
sysctlnametomib("hw.acpi.battery.time", bat->mib_time, &len); sysctlnametomib("hw.acpi.battery.time", bat->mib_time, &len);
bat->mib_units = malloc(sizeof(int) * 4); bat->mib_units = malloc(sizeof(int) * 4);
if(!bat->mib_units) return 0; if(!bat->mib_units) return 0;
sysctlnametomib("hw.acpi.battery.units", bat->mib_units, &len); sysctlnametomib("hw.acpi.battery.units", bat->mib_units, &len);
bat->udi = eina_stringshare_add("hw.acpi.battery"); bat->last_update = ecore_time_get();
bat->technology = eina_stringshare_add("Unknown"); bat->udi = eina_stringshare_add("hw.acpi.battery");
bat->model = eina_stringshare_add("Unknown"); bat->technology = eina_stringshare_add("Unknown");
bat->vendor = eina_stringshare_add("Unknown"); bat->model = eina_stringshare_add("Unknown");
bat->vendor = eina_stringshare_add("Unknown");
bat->poll = ecore_poller_add(ECORE_POLLER_CORE, bat->poll = ecore_poller_add(ECORE_POLLER_CORE,
inst->cfg->batman.poll_interval, inst->cfg->batman.poll_interval,
_batman_sysctl_battery_update_poll, inst); _batman_sysctl_battery_update_poll, inst);
batman_device_batteries = eina_list_append(batman_device_batteries, bat); batman_device_batteries = eina_list_append(batman_device_batteries, bat);
} }
if ((sysctlbyname("hw.acpi.acline", NULL, &len, NULL, 0)) != -1) if ((sysctlbyname("hw.acpi.acline", NULL, &len, NULL, 0)) != -1)
{ {
if (!(ac = E_NEW(Ac_Adapter, 1))) Ac_Adapter *ac = E_NEW(Ac_Adapter, 1);
return 0; if (!ac)
ac->inst = inst; return 0;
ac->mib = malloc(sizeof(int) * 3); ac->inst = inst;
if (!ac->mib) return 0; ac->mib = malloc(sizeof(int) * 3);
len = sizeof(ac->mib); if (!ac->mib) return 0;
sysctlnametomib("hw.acpi.acline", ac->mib, &len); len = sizeof(ac->mib);
sysctlnametomib("hw.acpi.acline", ac->mib, &len);
ac->udi = eina_stringshare_add("hw.acpi.acline");
ac->udi = eina_stringshare_add("hw.acpi.acline"); batman_device_ac_adapters = eina_list_append(batman_device_ac_adapters, ac);
}
batman_device_ac_adapters = eina_list_append(batman_device_ac_adapters, ac);
}
#endif #endif
_batman_sysctl_battery_update(inst); _batman_sysctl_battery_update(inst);
bat->last_update = ecore_time_get();
return 1; return 1;
} }
void void
_batman_sysctl_stop(void) _batman_sysctl_stop(void)
{ {
if (ac) Battery *bat;
Ac_Adapter *ac;
EINA_LIST_FREE(batman_device_ac_adapters, ac)
{ {
E_FREE_FUNC(ac->udi, eina_stringshare_del); E_FREE_FUNC(ac->udi, eina_stringshare_del);
E_FREE_FUNC(ac->mib, free); E_FREE_FUNC(ac->mib, free);
E_FREE_FUNC(ac, free); E_FREE_FUNC(ac, free);
} }
if (bat) EINA_LIST_FREE(batman_device_batteries, bat)
{ {
E_FREE_FUNC(bat->udi, eina_stringshare_del); E_FREE_FUNC(bat->udi, eina_stringshare_del);
E_FREE_FUNC(bat->technology, eina_stringshare_del); E_FREE_FUNC(bat->technology, eina_stringshare_del);
@ -163,10 +167,12 @@ _batman_sysctl_stop(void)
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
static Eina_Bool static Eina_Bool
_batman_sysctl_battery_update_poll(void *data EINA_UNUSED) _batman_sysctl_battery_update_poll(void *data)
{ {
Instance *inst = data; Instance *inst = data;
_batman_sysctl_battery_update(inst); _batman_sysctl_battery_update(inst);
return EINA_TRUE; return EINA_TRUE;
} }
#endif #endif
@ -174,175 +180,174 @@ _batman_sysctl_battery_update_poll(void *data EINA_UNUSED)
static int static int
_batman_sysctl_battery_update(Instance *inst) _batman_sysctl_battery_update(Instance *inst)
{ {
Battery *bat;
Ac_Adapter *ac;
Eina_List *l;
#if defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__OpenBSD__) || defined(__NetBSD__)
double _time, charge; double _time, charge;
struct sensor s; struct sensor s;
size_t slen = sizeof(struct sensor); size_t slen = sizeof(struct sensor);
#elif defined(__FreeBSD__) || defined(__DragonFly__) #elif defined(__FreeBSD__) || defined(__DragonFly__)
double _time, charge; double _time;
int value; int value;
size_t len; size_t len;
#endif #endif
EINA_LIST_FOREACH(batman_device_batteries, l, bat)
if (bat)
{ {
/* update the poller interval */ /* update the poller interval */
ecore_poller_poller_interval_set(bat->poll, ecore_poller_poller_interval_set(bat->poll,
inst->cfg->batman.poll_interval); inst->cfg->batman.poll_interval);
#if defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__OpenBSD__) || defined(__NetBSD__)
/* last full capacity */ /* last full capacity */
bat->mib[3] = 7; bat->mib[3] = 7;
bat->mib[4] = 0; bat->mib[4] = 0;
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1)
{ {
bat->last_full_charge = (double)s.value; bat->last_full_charge = (double)s.value;
} }
/* remaining capacity */ /* remaining capacity */
bat->mib[3] = 7; bat->mib[3] = 7;
bat->mib[4] = 3; bat->mib[4] = 3;
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1)
{ {
charge = (double)s.value; charge = (double)s.value;
} }
/* This is a workaround because there's an ACPI bug */ /* This is a workaround because there's an ACPI bug */
if ((EINA_FLT_EQ(charge, 0.0)) || (EINA_FLT_EQ(bat->last_full_charge, 0.0))) if ((EINA_FLT_EQ(charge, 0.0)) || (EINA_FLT_EQ(bat->last_full_charge, 0.0)))
{ {
/* last full capacity */ /* last full capacity */
bat->mib[3] = 8; bat->mib[3] = 8;
bat->mib[4] = 0; bat->mib[4] = 0;
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1)
{ {
bat->last_full_charge = (double)s.value; bat->last_full_charge = (double)s.value;
} if (bat->last_full_charge < 0) return EINA_TRUE;
}
/* remaining capacity */ /* remaining capacity */
bat->mib[3] = 8; bat->mib[3] = 8;
bat->mib[4] = 3; bat->mib[4] = 3;
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1)
{ {
charge = (double)s.value; charge = (double)s.value;
} }
} }
bat->got_prop = 1; bat->got_prop = 1;
_time = ecore_time_get(); _time = ecore_time_get();
if ((bat->got_prop) && (!EINA_FLT_EQ(charge, bat->current_charge))) if ((bat->got_prop) && (!EINA_FLT_EQ(charge, bat->current_charge)))
bat->charge_rate = ((charge - bat->current_charge) / (_time - bat->last_update)); bat->charge_rate = ((charge - bat->current_charge) / (_time - bat->last_update));
bat->last_update = _time; bat->last_update = _time;
bat->current_charge = charge; bat->current_charge = charge;
bat->percent = 100 * (bat->current_charge / bat->last_full_charge); bat->percent = 100 * (bat->current_charge / bat->last_full_charge);
if (bat->current_charge >= bat->last_full_charge) if (bat->current_charge >= bat->last_full_charge)
bat->percent = 100; bat->percent = 100;
if (bat->got_prop) if (bat->got_prop)
{ {
if (bat->charge_rate > 0) if (bat->charge_rate > 0)
{ {
if (inst->cfg->batman.fuzzy && (++inst->cfg->batman.fuzzcount <= 10) && (bat->time_full > 0)) if (inst->cfg->batman.fuzzy && (++inst->cfg->batman.fuzzcount <= 10) && (bat->time_full > 0))
bat->time_full = (((bat->last_full_charge - bat->current_charge) / bat->charge_rate) + bat->time_full) / 2; bat->time_full = (((bat->last_full_charge - bat->current_charge) / bat->charge_rate) + bat->time_full) / 2;
else else
bat->time_full = (bat->last_full_charge - bat->current_charge) / bat->charge_rate; bat->time_full = (bat->last_full_charge - bat->current_charge) / bat->charge_rate;
bat->time_left = -1; bat->time_left = -1;
} }
else else
{ {
if (inst->cfg->batman.fuzzy && (inst->cfg->batman.fuzzcount <= 10) && (bat->time_left > 0)) if (inst->cfg->batman.fuzzy && (inst->cfg->batman.fuzzcount <= 10) && (bat->time_left > 0))
bat->time_left = (((0 - bat->current_charge) / bat->charge_rate) + bat->time_left) / 2; bat->time_left = (((0 - bat->current_charge) / bat->charge_rate) + bat->time_left) / 2;
else else
bat->time_left = (0 - bat->current_charge) / bat->charge_rate; bat->time_left = (0 - bat->current_charge) / bat->charge_rate;
bat->time_full = -1; bat->time_full = -1;
} }
} }
else else
{ {
bat->time_full = -1; bat->time_full = -1;
bat->time_left = -1; bat->time_left = -1;
} }
/* battery state 1: discharge, 2: charge */ /* battery state 1: discharge, 2: charge */
bat->mib[3] = 10; bat->mib[3] = 10;
bat->mib[4] = 0; bat->mib[4] = 0;
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) == -1) if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) == -1)
{ {
if (s.value == 2) if (s.value == 2)
bat->charging = 1; bat->charging = 1;
else else
bat->charging = 0; bat->charging = 0;
} }
_batman_device_update(bat->inst);
#elif defined(__FreeBSD__) || defined(__DragonFly__) #elif defined(__FreeBSD__) || defined(__DragonFly__)
len = sizeof(value); len = sizeof(value);
if ((sysctl(bat->mib, 4, &value, &len, NULL, 0)) == -1) if ((sysctl(bat->mib, 4, &value, &len, NULL, 0)) == -1)
{ {
return 0; return EINA_FALSE;
} }
bat->percent = value; bat->percent = value;
_time = ecore_time_get(); _time = ecore_time_get();
bat->last_update = _time; bat->last_update = _time;
len = sizeof(value); len = sizeof(value);
if ((sysctl(bat->mib_state, 4, &value, &len, NULL, 0)) == -1) if ((sysctl(bat->mib_state, 4, &value, &len, NULL, 0)) == -1)
{ {
return 0; return EINA_FALSE;
} }
bat->charging = !value; bat->charging = !value;
bat->got_prop = 1; bat->got_prop = 1;
bat->time_full = -1; bat->time_full = -1;
bat->time_left = -1; bat->time_left = -1;
len = sizeof(bat->time_min); len = sizeof(bat->time_min);
if ((sysctl(bat->mib_time, 4, &bat->time_min, &len, NULL, 0)) == -1) if ((sysctl(bat->mib_time, 4, &bat->time_min, &len, NULL, 0)) == -1)
{ {
bat->time_min = -1; bat->time_min = -1;
} }
len = sizeof(bat->batteries);
if ((sysctl(bat->mib_units, 4, &bat->batteries, &len, NULL, 0)) == -1)
{
bat->batteries = 1;
}
len = sizeof(bat->batteries); if (bat->time_min >= 0) bat->time_left = bat->time_min * 60;
if ((sysctl(bat->mib_units, 4, &bat->batteries, &len, NULL, 0)) == -1) if (bat->batteries == 1) bat->time_left = -1;
{ _batman_device_update(inst);
bat->batteries = 1;
}
if (bat->time_min >= 0) bat->time_left = bat->time_min * 60;
if (bat->batteries == 1) bat->time_left = -1;
#endif #endif
} }
if (ac)
EINA_LIST_FOREACH(batman_device_ac_adapters, l, ac)
{ {
#if defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__OpenBSD__) || defined(__NetBSD__)
/* AC State */ /* AC State */
ac->mib[3] = 9; ac->mib[3] = 9;
ac->mib[4] = 0; ac->mib[4] = 0;
if (sysctl(ac->mib, 5, &s, &slen, NULL, 0) != -1) if (sysctl(ac->mib, 5, &s, &slen, NULL, 0) != -1)
{ {
if (s.value) if (s.value)
ac->present = 1; ac->present = 1;
else else
ac->present = 0; ac->present = 0;
} }
#elif defined(__FreeBSD__) || defined(__DragonFly__) #elif defined(__FreeBSD__) || defined(__DragonFly__)
len = sizeof(value); len = sizeof(value);
if ((sysctl(ac->mib, 3, &value, &len, NULL, 0)) != -1) if ((sysctl(ac->mib, 3, &value, &len, NULL, 0)) != -1)
{ {
ac->present = value; ac->present = value;
} }
#endif #endif
} }
if (bat) return EINA_TRUE;
{
if (bat->got_prop)
_batman_device_update(bat->inst);
bat->got_prop = 1;
}
return 1;
} }