parent
cd24662e9f
commit
b51b591171
24 changed files with 5872 additions and 0 deletions
@ -0,0 +1,561 @@ |
||||
#include "batman.h" |
||||
|
||||
Eina_Bool upower; |
||||
Eina_List *batman_device_batteries; |
||||
Eina_List *batman_device_ac_adapters; |
||||
double batman_init_time; |
||||
|
||||
static Eina_Bool _batman_cb_warning_popup_timeout(void *data); |
||||
static void _batman_cb_warning_popup_hide(void *data, Evas *e, Evas_Object *obj, void *event); |
||||
static void _batman_warning_popup_destroy(Instance *inst); |
||||
static void _batman_warning_popup(Instance *inst, int time, double percent); |
||||
|
||||
Battery * |
||||
_batman_battery_find(const char *udi) |
||||
{ |
||||
Eina_List *l; |
||||
Battery *bat; |
||||
EINA_LIST_FOREACH(batman_device_batteries, l, bat) |
||||
{ /* these are always stringshared */ |
||||
if (udi == bat->udi) return bat; |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
Ac_Adapter * |
||||
_batman_ac_adapter_find(const char *udi) |
||||
{ |
||||
Eina_List *l; |
||||
Ac_Adapter *ac; |
||||
EINA_LIST_FOREACH(batman_device_ac_adapters, l, ac) |
||||
{ /* these are always stringshared */ |
||||
if (udi == ac->udi) return ac; |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static void |
||||
_batman_face_level_set(Evas_Object *battery, double level) |
||||
{ |
||||
Edje_Message_Float msg; |
||||
char buf[256]; |
||||
|
||||
snprintf(buf, sizeof(buf), "%i", (int)(level * 100.0)); |
||||
elm_layout_text_set(battery, "e.text.reading", buf); |
||||
if (level < 0.0) level = 0.0; |
||||
else if (level > 1.0) |
||||
level = 1.0; |
||||
msg.val = level; |
||||
edje_object_message_send(elm_layout_edje_get(battery), EDJE_MESSAGE_FLOAT, 1, &msg); |
||||
} |
||||
|
||||
static void |
||||
_batman_face_time_set(Evas_Object *battery, int t) |
||||
{ |
||||
char buf[256]; |
||||
int hrs, mins; |
||||
|
||||
if (t < 0) return; |
||||
|
||||
hrs = (t / 3600); |
||||
mins = ((t) / 60 - (hrs * 60)); |
||||
if (mins < 0) mins = 0; |
||||
snprintf(buf, sizeof(buf), "%i:%02i", hrs, mins);
|
||||
elm_layout_text_set(battery, "e.text.time", buf); |
||||
} |
||||
|
||||
void |
||||
_batman_update(Instance *inst, int full, int time_left, int time_full, Eina_Bool have_battery, Eina_Bool have_power) |
||||
{ |
||||
static double debounce_time = 0.0; |
||||
|
||||
if (!inst) return; |
||||
if (inst->cfg->esm != E_SYSINFO_MODULE_BATMAN && inst->cfg->esm != E_SYSINFO_MODULE_SYSINFO) return; |
||||
if (!inst->cfg) return; |
||||
if (have_power != inst->cfg->batman.have_power) |
||||
{ |
||||
if (have_power && (full < 100)) |
||||
elm_layout_signal_emit(inst->cfg->batman.o_gadget, |
||||
"e,state,charging", |
||||
"e"); |
||||
else |
||||
{ |
||||
elm_layout_signal_emit(inst->cfg->batman.o_gadget, |
||||
"e,state,discharging", |
||||
"e"); |
||||
if (inst->popup_battery) |
||||
elm_layout_signal_emit(inst->popup_battery, |
||||
"e,state,discharging", "e"); |
||||
} |
||||
} |
||||
if (have_battery) |
||||
{ |
||||
if (inst->cfg->batman.full != full) |
||||
{ |
||||
double val; |
||||
|
||||
if (full >= 100) val = 1.0; |
||||
else val = (double)full / 100.0; |
||||
_batman_face_level_set(inst->cfg->batman.o_gadget, val); |
||||
if (inst->popup_battery) |
||||
_batman_face_level_set(inst->popup_battery, val); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
_batman_face_level_set(inst->cfg->batman.o_gadget, 0.0); |
||||
elm_layout_text_set(inst->cfg->batman.o_gadget, |
||||
"e.text.reading", |
||||
_("N/A")); |
||||
} |
||||
|
||||
if ((time_full < 0) && (time_left != inst->cfg->batman.time_left)) |
||||
{ |
||||
_batman_face_time_set(inst->cfg->batman.o_gadget, time_left); |
||||
if (inst->popup_battery) |
||||
_batman_face_time_set(inst->popup_battery, |
||||
time_left); |
||||
} |
||||
else if ((time_left < 0) && (time_full != inst->cfg->batman.time_full)) |
||||
{ |
||||
_batman_face_time_set(inst->cfg->batman.o_gadget, time_full); |
||||
if (inst->popup_battery) |
||||
_batman_face_time_set(inst->popup_battery, |
||||
time_full); |
||||
} |
||||
if (have_battery && |
||||
(!have_power) && |
||||
(full < 100) && |
||||
( |
||||
( |
||||
(time_left > 0) && |
||||
inst->cfg->batman.alert && |
||||
((time_left / 60) <= inst->cfg->batman.alert) |
||||
) || |
||||
( |
||||
inst->cfg->batman.alert_p && |
||||
(full <= inst->cfg->batman.alert_p) |
||||
) |
||||
) |
||||
) |
||||
{ |
||||
double t; |
||||
|
||||
printf("-------------------------------------- bat warn .. why below\n"); |
||||
printf("have_battery = %i\n", (int)have_battery); |
||||
printf("have_power = %i\n", (int)have_power); |
||||
printf("full = %i\n", (int)full); |
||||
printf("time_left = %i\n", (int)time_left); |
||||
printf("inst->cfg->batman.alert = %i\n", (int)inst->cfg->batman.alert); |
||||
printf("inst->cfg->batman.alert_p = %i\n", (int)inst->cfg->batman.alert_p); |
||||
t = ecore_time_get(); |
||||
if ((t - debounce_time) > 30.0) |
||||
{ |
||||
printf("t-debounce = %3.3f\n", (t - debounce_time)); |
||||
debounce_time = t; |
||||
if ((t - batman_init_time) > 5.0) |
||||
_batman_warning_popup(inst, time_left, (double)full / 100.0); |
||||
} |
||||
} |
||||
else if (have_power || ((time_left / 60) > inst->cfg->batman.alert)) |
||||
_batman_warning_popup_destroy(inst); |
||||
if ((have_battery) && (!have_power) && (full >= 0) && |
||||
(inst->cfg->batman.suspend_below > 0) && |
||||
(full < inst->cfg->batman.suspend_below)) |
||||
{ |
||||
if (inst->cfg->batman.suspend_method == SUSPEND) |
||||
e_sys_action_do(E_SYS_SUSPEND, NULL); |
||||
else if (inst->cfg->batman.suspend_method == HIBERNATE) |
||||
e_sys_action_do(E_SYS_HIBERNATE, NULL); |
||||
else if (inst->cfg->batman.suspend_method == SHUTDOWN) |
||||
e_sys_action_do(E_SYS_HALT, NULL); |
||||
} |
||||
inst->cfg->batman.full = full; |
||||
inst->cfg->batman.time_left = time_left; |
||||
inst->cfg->batman.have_battery = have_battery; |
||||
inst->cfg->batman.have_power = have_power; |
||||
|
||||
if (!have_battery) |
||||
e_powersave_mode_set(E_POWERSAVE_MODE_LOW); |
||||
else |
||||
{ |
||||
if (have_power) |
||||
e_powersave_mode_set(E_POWERSAVE_MODE_LOW); |
||||
else if (full > 95) |
||||
e_powersave_mode_set(E_POWERSAVE_MODE_MEDIUM); |
||||
else if (full > 30) |
||||
e_powersave_mode_set(E_POWERSAVE_MODE_HIGH); |
||||
else |
||||
e_powersave_mode_set(E_POWERSAVE_MODE_EXTREME); |
||||
} |
||||
} |
||||
|
||||
void |
||||
_batman_device_update(Instance *inst) |
||||
{ |
||||
Eina_List *l; |
||||
Battery *bat; |
||||
Ac_Adapter *ac; |
||||
int full = -1; |
||||
int time_left = -1; |
||||
int time_full = -1; |
||||
int have_battery = 0; |
||||
int have_power = 0; |
||||
int charging = 0; |
||||
|
||||
int batnum = 0; |
||||
int acnum = 0; |
||||
|
||||
EINA_LIST_FOREACH(batman_device_ac_adapters, l, ac) |
||||
if (ac->present) acnum++; |
||||
|
||||
EINA_LIST_FOREACH(batman_device_batteries, l, bat) |
||||
{ |
||||
if (!bat->got_prop) |
||||
continue; |
||||
have_battery = 1; |
||||
batnum++; |
||||
if (bat->charging == 1) have_power = 1; |
||||
if (full == -1) full = 0; |
||||
if (bat->percent >= 0) |
||||
full += bat->percent; |
||||
else if (bat->last_full_charge > 0) |
||||
full += (bat->current_charge * 100) / bat->last_full_charge; |
||||
else if (bat->design_charge > 0) |
||||
full += (bat->current_charge * 100) / bat->design_charge; |
||||
if (bat->time_left > 0) |
||||
{ |
||||
if (time_left < 0) time_left = bat->time_left; |
||||
else time_left += bat->time_left; |
||||
} |
||||
if (bat->time_full > 0) |
||||
{ |
||||
if (time_full < 0) time_full = bat->time_full; |
||||
else time_full += bat->time_full; |
||||
} |
||||
charging += bat->charging; |
||||
} |
||||
|
||||
if ((batman_device_batteries) && (batnum == 0)) |
||||
return; /* not ready yet, no properties received for any battery */ |
||||
|
||||
if (batnum > 0) full /= batnum; |
||||
if ((full == 100) && have_power) |
||||
{ |
||||
time_left = -1; |
||||
time_full = -1; |
||||
} |
||||
if (time_left < 1) time_left = -1; |
||||
if (time_full < 1) time_full = -1; |
||||
|
||||
_batman_update(inst, full, time_left, time_full, have_battery, have_power); |
||||
} |
||||
|
||||
void |
||||
_batman_config_updated(Instance *inst) |
||||
{ |
||||
int ok = 0; |
||||
|
||||
if (!inst->cfg) return; |
||||
|
||||
if ((inst->cfg->batman.force_mode == UNKNOWN) || |
||||
(inst->cfg->batman.force_mode == SUBSYSTEM)) |
||||
{ |
||||
#ifdef HAVE_EEZE |
||||
ok = _batman_udev_start(inst); |
||||
#elif defined __OpenBSD__ || defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__ |
||||
ok = _batman_sysctl_start(inst); |
||||
#else |
||||
ok = _batman_upower_start(); |
||||
if (ok) |
||||
upower = EINA_TRUE; |
||||
#endif |
||||
} |
||||
if (ok) return; |
||||
|
||||
if ((inst->cfg->batman.force_mode == UNKNOWN) || |
||||
(inst->cfg->batman.force_mode == NOSUBSYSTEM)) |
||||
{ |
||||
ok = _batman_fallback_start(inst); |
||||
} |
||||
} |
||||
|
||||
static void _warning_popup_dismissed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) |
||||
{ |
||||
Instance *inst = data; |
||||
|
||||
E_FREE_FUNC(inst->popup_battery, evas_object_del); |
||||
E_FREE_FUNC(inst->warning, evas_object_del); |
||||
} |
||||
|
||||
|
||||
static Eina_Bool |
||||
_batman_cb_warning_popup_timeout(void *data) |
||||
{ |
||||
Instance *inst; |
||||
|
||||
inst = data; |
||||
elm_ctxpopup_dismiss(inst->warning); |
||||
inst->cfg->batman.alert_timer = NULL; |
||||
return ECORE_CALLBACK_CANCEL; |
||||
} |
||||
|
||||
static void |
||||
_batman_cb_warning_popup_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) |
||||
{ |
||||
Instance *inst = NULL; |
||||
|
||||
inst = (Instance *)data; |
||||
if ((!inst) || (!inst->warning)) return; |
||||
elm_ctxpopup_dismiss(inst->warning); |
||||
} |
||||
|
||||
static void |
||||
_batman_warning_popup_destroy(Instance *inst) |
||||
{ |
||||
if (inst->cfg->batman.alert_timer) |
||||
{ |
||||
ecore_timer_del(inst->cfg->batman.alert_timer); |
||||
inst->cfg->batman.alert_timer = NULL; |
||||
} |
||||
if ((!inst) || (!inst->warning)) return; |
||||
elm_ctxpopup_dismiss(inst->warning); |
||||
} |
||||
|
||||
static void |
||||
_batman_warning_popup_cb(void *data, unsigned int id) |
||||
{ |
||||
Instance *inst = data; |
||||
|
||||
inst->notification_id = id; |
||||
} |
||||
|
||||
static void |
||||
_batman_warning_popup(Instance *inst, int t, double percent) |
||||
{ |
||||
Evas_Object *popup_bg = NULL; |
||||
int x, y, w, h; |
||||
|
||||
if ((!inst) || (inst->warning)) return; |
||||
|
||||
if (inst->cfg->batman.desktop_notifications) |
||||
{ |
||||
E_Notification_Notify n; |
||||
memset(&n, 0, sizeof(E_Notification_Notify)); |
||||
n.app_name = _("Battery"); |
||||
n.replaces_id = 0; |
||||
n.icon.icon = "battery-low"; |
||||
n.summary = _("Your battery is low!"); |
||||
n.body = _("AC power is recommended."); |
||||
n.timeout = inst->cfg->batman.alert_timeout * 1000; |
||||
e_notification_client_send(&n, _batman_warning_popup_cb, inst); |
||||
return; |
||||
} |
||||
|
||||
inst->warning = elm_ctxpopup_add(e_comp->elm); |
||||
elm_object_style_set(inst->warning, "noblock"); |
||||
evas_object_smart_callback_add(inst->warning, "dismissed", _warning_popup_dismissed, inst); |
||||
if (!inst->warning) return; |
||||
|
||||
popup_bg = elm_layout_add(inst->warning); |
||||
inst->popup_battery = elm_layout_add(popup_bg); |
||||
|
||||
if ((!popup_bg) || (!inst->popup_battery)) |
||||
{ |
||||
elm_ctxpopup_dismiss(inst->warning); |
||||
inst->warning = NULL; |
||||
return; |
||||
} |
||||
|
||||
e_theme_edje_object_set(popup_bg, "base/theme/modules/battery/popup", |
||||
"e/modules/battery/popup"); |
||||
e_theme_edje_object_set(inst->popup_battery, "base/theme/modules/battery", |
||||
"e/modules/battery/main"); |
||||
if (edje_object_part_exists(elm_layout_edje_get(popup_bg), "e.swallow.battery")) |
||||
elm_layout_content_set(popup_bg, "e.swallow.battery", inst->popup_battery); |
||||
else |
||||
elm_layout_content_set(popup_bg, "battery", inst->popup_battery); |
||||
|
||||
elm_layout_text_set(popup_bg, "e.text.title", |
||||
_("Your battery is low!")); |
||||
elm_layout_text_set(popup_bg, "e.text.label", |
||||
_("AC power is recommended.")); |
||||
evas_object_show(inst->popup_battery); |
||||
evas_object_show(popup_bg); |
||||
|
||||
elm_object_content_set(inst->warning, popup_bg); |
||||
e_gadget_util_ctxpopup_place(inst->o_main, inst->warning, inst->cfg->batman.o_gadget); |
||||
evas_object_layer_set(inst->warning, E_LAYER_POPUP); |
||||
evas_object_show(inst->warning); |
||||
|
||||
evas_object_geometry_get(inst->warning, &x, &y, &w, &h); |
||||
evas_object_event_callback_add(inst->warning, EVAS_CALLBACK_MOUSE_DOWN, |
||||
_batman_cb_warning_popup_hide, inst); |
||||
|
||||
_batman_face_time_set(inst->popup_battery, t); |
||||
_batman_face_level_set(inst->popup_battery, percent); |
||||
edje_object_signal_emit(inst->popup_battery, "e,state,discharging", "e"); |
||||
|
||||
if ((inst->cfg->batman.alert_timeout > 0) && |
||||
(!inst->cfg->batman.alert_timer)) |
||||
{ |
||||
inst->cfg->batman.alert_timer = |
||||
ecore_timer_add(inst->cfg->batman.alert_timeout, |
||||
_batman_cb_warning_popup_timeout, inst); |
||||
} |
||||
} |
||||
|
||||
static void |
||||
_batman_removed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_data) |
||||
{ |
||||
Instance *inst = data; |
||||
|
||||
if (inst->o_main != event_data) return; |
||||
|
||||
#ifdef HAVE_EEZE |
||||
_batman_udev_stop(inst); |
||||
#elif defined __OpenBSD__ || defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__ |
||||
_batman_sysctl_stop(); |
||||
#elif upower |
||||
_batman_upower_stop(); |
||||
#else |
||||
_batman_fallback_stop(); |
||||
#endif |
||||
|
||||
#ifdef HAVE_EEZE |
||||
eeze_shutdown(); |
||||
#endif |
||||
|
||||
sysinfo_config->items = eina_list_remove(sysinfo_config->items, inst->cfg); |
||||
E_FREE(inst->cfg); |
||||
} |
||||
|
||||
void |
||||
sysinfo_batman_remove(Instance *inst) |
||||
{ |
||||
#ifdef HAVE_EEZE |
||||
_batman_udev_stop(inst); |
||||
#elif defined __OpenBSD__ || defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__ |
||||
_batman_sysctl_stop(); |
||||
#elif upower |
||||
_batman_upower_stop(); |
||||
#else |
||||
_batman_fallback_stop(); |
||||
#endif |
||||
|
||||
#ifdef HAVE_EEZE |
||||
eeze_shutdown(); |
||||
#endif |
||||
} |
||||
|
||||
static void |
||||
_batman_created_cb(void *data, Evas_Object *obj, void *event_data EINA_UNUSED) |
||||
{ |
||||
Instance *inst = data; |
||||
|
||||
inst->cfg->batman.full = -2; |
||||
inst->cfg->batman.time_left = -2; |
||||
inst->cfg->batman.time_full = -2; |
||||
inst->cfg->batman.have_battery = -2; |
||||
inst->cfg->batman.have_power = -2; |
||||
|
||||
inst->cfg->batman.o_gadget = elm_layout_add(inst->o_main); |
||||
e_theme_edje_object_set(inst->cfg->batman.o_gadget, "base/theme/modules/battery", |
||||
"e/modules/battery/main"); |
||||
E_EXPAND(inst->cfg->batman.o_gadget); |
||||
E_FILL(inst->cfg->batman.o_gadget); |
||||
elm_box_pack_end(inst->o_main, inst->cfg->batman.o_gadget); |
||||
evas_object_show(inst->cfg->batman.o_gadget); |
||||
evas_object_smart_callback_del_full(obj, "gadget_created", _batman_created_cb, data); |
||||
_batman_config_updated(inst); |
||||
} |
||||
|
||||
Evas_Object * |
||||
sysinfo_batman_create(Evas_Object *parent, Instance *inst) |
||||
{ |
||||
inst->cfg->batman.full = -2; |
||||
inst->cfg->batman.time_left = -2; |
||||
inst->cfg->batman.time_full = -2; |
||||
inst->cfg->batman.have_battery = -2; |
||||
inst->cfg->batman.have_power = -2; |
||||
|
||||
inst->cfg->batman.o_gadget = elm_layout_add(parent); |
||||
e_theme_edje_object_set(inst->cfg->batman.o_gadget, "base/theme/modules/battery", |
||||
"e/modules/battery/main"); |
||||
E_EXPAND(inst->cfg->batman.o_gadget); |
||||
E_FILL(inst->cfg->batman.o_gadget); |
||||
evas_object_show(inst->cfg->batman.o_gadget); |
||||
_batman_config_updated(inst); |
||||
|
||||
return inst->cfg->batman.o_gadget;
|
||||
} |
||||
|
||||
static Config_Item * |
||||
_conf_item_get(int *id) |
||||
{ |
||||
Config_Item *ci; |
||||
Eina_List *l; |
||||
|
||||
if (*id > 0) |
||||
{ |
||||
EINA_LIST_FOREACH(sysinfo_config->items, l, ci) |
||||
if (*id == ci->id && ci->esm == E_SYSINFO_MODULE_BATMAN) return ci; |
||||
} |
||||
|
||||
ci = E_NEW(Config_Item, 1); |
||||
|
||||
if (*id != -1) |
||||
ci->id = eina_list_count(sysinfo_config->items)+1; |
||||
else |
||||
ci->id = -1; |
||||
|
||||
ci->esm = E_SYSINFO_MODULE_BATMAN; |
||||
ci->batman.poll_interval = 512; |
||||
ci->batman.alert = 30; |
||||
ci->batman.alert_p = 10; |
||||
ci->batman.alert_timeout = 0; |
||||
ci->batman.suspend_below = 0; |
||||
ci->batman.force_mode = 0; |
||||
ci->batman.full = -2; |
||||
ci->batman.time_left = -2; |
||||
ci->batman.time_full = -2; |
||||
ci->batman.have_battery = -2; |
||||
ci->batman.have_power = -2; |
||||
#if defined HAVE_EEZE || defined __OpenBSD__ || defined __NetBSD__ |
||||
ci->batman.fuzzy = 0; |
||||
#endif |
||||
ci->batman.desktop_notifications = 0; |
||||
|
||||
sysinfo_config->items = eina_list_append(sysinfo_config->items, ci); |
||||
|
||||
return ci; |
||||
} |
||||
|
||||
Evas_Object * |
||||
batman_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient EINA_UNUSED) |
||||
{ |
||||
Instance *inst; |
||||
|
||||
inst = E_NEW(Instance, 1); |
||||
inst->cfg = _conf_item_get(id); |
||||
*id = inst->cfg->id; |
||||
inst->o_main = elm_box_add(parent); |
||||
E_EXPAND(inst->o_main); |
||||
evas_object_size_hint_aspect_set(inst->o_main, EVAS_ASPECT_CONTROL_BOTH, 1, 1); |
||||
evas_object_smart_callback_add(parent, "gadget_created", _batman_created_cb, inst); |
||||
evas_object_smart_callback_add(parent, "gadget_removed", _batman_removed_cb, inst); |
||||
evas_object_show(inst->o_main); |
||||
|
||||
#ifdef HAVE_EEZE |
||||
eeze_init(); |
||||
#endif |
||||
|
||||
if (inst->cfg->id < 0) return inst->o_main; |
||||
|
||||
sysinfo_instances = |
||||
eina_list_append(sysinfo_instances, inst); |
||||
|
||||
return inst->o_main; |
||||
} |
@ -0,0 +1,107 @@ |
||||
#ifndef BATMAN_H |
||||
#define BATMAN_H |
||||
|
||||
#include "../sysinfo.h" |
||||
|
||||
#define CHECK_NONE 0 |
||||
#define CHECK_ACPI 1 |
||||
#define CHECK_APM 2 |
||||
#define CHECK_PMU 3 |
||||
#define CHECK_SYS_ACPI 4 |
||||
|
||||
#define UNKNOWN 0 |
||||
#define NOSUBSYSTEM 1 |
||||
#define SUBSYSTEM 2 |
||||
|
||||
#define SUSPEND 0 |
||||
#define HIBERNATE 1 |
||||
#define SHUTDOWN 2 |
||||
|
||||
#define POPUP_DEBOUNCE_CYCLES 2 |
||||
|
||||
typedef struct _Battery Battery; |
||||
typedef struct _Ac_Adapter Ac_Adapter; |
||||
typedef struct _Battery_Config Battery_Config; |
||||
|
||||
struct _Battery |
||||
{ |
||||
Instance *inst; |
||||
const char *udi; |
||||
#if defined HAVE_EEZE || defined __OpenBSD__ || defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__ |
||||
Ecore_Poller *poll; |
||||
#endif |
||||
Eina_Bool present:1; |
||||
Eina_Bool charging:1; |
||||
#if defined HAVE_EEZE || defined __OpenBSD__ || defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__ |
||||
double last_update; |
||||
double percent; |
||||
double current_charge; |
||||
double design_charge; |
||||
double last_full_charge; |
||||
double charge_rate; |
||||
double time_full; |
||||
double time_left; |
||||
#else |
||||
int percent; |
||||
int current_charge; |
||||
int design_charge; |
||||
int last_full_charge; |
||||
int charge_rate; |
||||
int time_full; |
||||
int time_left; |
||||
const char *type; |
||||
const char *charge_units; |
||||
#endif |
||||
const char *technology; |
||||
const char *model; |
||||
const char *vendor; |
||||
Eina_Bool got_prop:1; |
||||
Eldbus_Proxy *proxy; |
||||
int * mib; |
||||
#if defined(__FreeBSD__) || defined(__DragonFly__) |
||||
int * mib_state; |
||||
int * mib_units; |
||||
int * mib_time; |
||||
int batteries; |
||||
int time_min; |
||||
#endif |
||||
}; |
||||
|
||||
struct _Ac_Adapter |
||||
{ |
||||
Instance *inst; |
||||
const char *udi; |
||||
Eina_Bool present:1; |
||||
const char *product; |
||||
Eldbus_Proxy *proxy; |
||||
int * mib; |
||||
}; |
||||
|
||||
Battery *_batman_battery_find(const char *udi); |
||||
Ac_Adapter *_batman_ac_adapter_find(const char *udi); |
||||
void _batman_update(Instance *inst, int full, int time_left, int time_full, Eina_Bool have_battery, Eina_Bool have_power); |
||||
void _batman_device_update(Instance *inst); |
||||
/* in batman_fallback.c */ |
||||
int _batman_fallback_start(Instance *inst); |
||||
void _batman_fallback_stop(void); |
||||
/* end batman_fallback.c */ |
||||
#ifdef HAVE_EEZE |
||||
/* in batman_udev.c */ |
||||
int _batman_udev_start(Instance *inst); |
||||
void _batman_udev_stop(Instance *inst); |
||||
/* end batman_udev.c */ |
||||
#elif !defined __OpenBSD__ && !defined __DragonFly__ && !defined __FreeBSD__ && !defined __NetBSD__ |
||||
/* in batman_upower.c */ |
||||
int _batman_upower_start(Instance *inst); |
||||
void _batman_upower_stop(void); |
||||
/* end batman_upower.c */ |
||||
#else |
||||
/* in batman_sysctl.c */ |
||||
int _batman_sysctl_start(Instance *inst); |
||||
void _batman_sysctl_stop(void); |
||||
/* end batman_sysctl.c */ |
||||
#endif |
||||
|
||||
void _batman_config_updated(Instance *inst); |
||||
|
||||
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,347 @@ |
||||
#include <err.h> |
||||
#include <sys/types.h> |
||||
#include <sys/sysctl.h> |
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) |
||||
#include <sys/param.h> |
||||
#include <sys/sensors.h> |
||||
#endif |
||||
|
||||
#include "batman.h" |
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) |
||||
static Eina_Bool _batman_sysctl_battery_update_poll(void *data); |
||||
#endif |
||||
static int _batman_sysctl_battery_update(Instance *inst); |
||||
|
||||
extern Eina_List *batman_device_batteries; |
||||
extern Eina_List *batman_device_ac_adapters; |
||||
extern double batman_init_time; |
||||
|
||||
Ac_Adapter *ac = NULL; |
||||
Battery *bat = NULL; |
||||
|
||||
int |
||||
_batman_sysctl_start(Instance *inst) |
||||
{ |
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) |
||||
int mib[] = {CTL_HW, HW_SENSORS, 0, 0, 0}; |
||||
int devn; |
||||
struct sensordev snsrdev; |
||||
size_t sdlen = sizeof(struct sensordev); |
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) |
||||
int result; |
||||
size_t len; |
||||
#endif |
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) |
||||
for (devn = 0;; devn++) { |
||||
mib[2] = devn; |
||||
if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) |
||||
{ |
||||
if (errno == ENXIO) |
||||
continue; |
||||
if (errno == ENOENT) |
||||
break; |
||||
} |
||||
|
||||
if (!strcmp("acpibat0", snsrdev.xname)) |
||||
{ |
||||
if (!(bat = E_NEW(Battery, 1))) |
||||
return 0; |
||||
bat->inst = inst; |
||||
bat->udi = eina_stringshare_add("acpibat0"), |
||||
bat->mib = malloc(sizeof(int) * 5); |
||||
if (!bat->mib) return 0; |
||||
bat->mib[0] = mib[0]; |
||||
bat->mib[1] = mib[1]; |
||||
bat->mib[2] = mib[2]; |
||||
bat->technology = eina_stringshare_add("Unknown"); |
||||
bat->model = eina_stringshare_add("Unknown"); |
||||
bat->vendor = eina_stringshare_add("Unknown"); |
||||
bat->poll = ecore_poller_add(ECORE_POLLER_CORE, |
||||
inst->cfg->batman.poll_interval, |
||||
_batman_sysctl_battery_update_poll, inst); |
||||
batman_device_batteries = eina_list_append(batman_device_batteries, bat); |
||||
} |
||||
else if (!strcmp("acpiac0", snsrdev.xname)) |
||||
{ |
||||
if (!(ac = E_NEW(Ac_Adapter, 1))) |
||||
return 0; |
||||
ac->inst = inst; |
||||
ac->udi = eina_stringshare_add("acpiac0"); |
||||
ac->mib = malloc(sizeof(int) * 5); |
||||
if (!ac->mib) return 0; |
||||
ac->mib[0] = mib[0]; |
||||
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__) |
||||
if ((sysctlbyname("hw.acpi.battery.life", NULL, &len, NULL, 0)) != -1) |
||||
{ |
||||
if (!(bat = E_NEW(Battery, 1))) |
||||
return 0; |
||||
bat->inst = inst; |
||||
bat->mib = malloc(sizeof(int) * 4); |
||||
if (!bat->mib) return 0; |
||||
sysctlnametomib("hw.acpi.battery.life", bat->mib, &len);
|
||||
|
||||
bat->mib_state = malloc(sizeof(int) * 4); |
||||
if (!bat->mib_state) return 0; |
||||
sysctlnametomib("hw.acpi.battery.state", bat->mib_state, &len); |
||||
|
||||
bat->mib_time = malloc(sizeof(int) * 4); |
||||
if (!bat->mib_time) return 0; |
||||
sysctlnametomib("hw.acpi.battery.time", bat->mib_time, &len); |
||||
|
||||
bat->mib_units = malloc(sizeof(int) * 4); |
||||
if(!bat->mib_units) return 0; |
||||
sysctlnametomib("hw.acpi.battery.units", bat->mib_units, &len); |
||||
|
||||
bat->udi = eina_stringshare_add("hw.acpi.battery"); |
||||
bat->technology = eina_stringshare_add("Unknown"); |
||||
bat->model = eina_stringshare_add("Unknown"); |
||||
bat->vendor = eina_stringshare_add("Unknown"); |
||||
|
||||
bat->poll = ecore_poller_add(ECORE_POLLER_CORE, |
||||
inst->cfg->batman.poll_interval, |
||||
_batman_sysctl_battery_update_poll, inst); |
||||
|
||||
batman_device_batteries = eina_list_append(batman_device_batteries, bat); |
||||
} |
||||
|
||||
if ((sysctlbyname("hw.acpi.acline", NULL, &len, NULL, 0)) != -1) |
||||
{ |
||||
if (!(ac = E_NEW(Ac_Adapter, 1))) |
||||
return 0; |
||||
ac->inst = inst; |
||||
ac->mib = malloc(sizeof(int) * 3); |
||||
if (!ac->mib) return 0; |
||||
len = sizeof(ac->mib); |
||||
sysctlnametomib("hw.acpi.acline", ac->mib, &len); |
||||
|
||||
ac->udi = eina_stringshare_add("hw.acpi.acline"); |
||||
|
||||
batman_device_ac_adapters = eina_list_append(batman_device_ac_adapters, ac); |
||||
} |
||||
#endif |
||||
_batman_sysctl_battery_update(inst); |
||||
|
||||
bat->last_update = ecore_time_get(); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
void |
||||
_batman_sysctl_stop(void) |
||||
{ |
||||
if (ac) |
||||
{ |
||||
E_FREE_FUNC(ac->udi, eina_stringshare_del); |
||||
E_FREE_FUNC(ac->mib, free); |
||||
E_FREE_FUNC(ac, free); |
||||
} |
||||
|
||||
if (bat) |
||||
{ |
||||
E_FREE_FUNC(bat->udi, eina_stringshare_del); |
||||
E_FREE_FUNC(bat->technology, eina_stringshare_del); |
||||
E_FREE_FUNC(bat->model, eina_stringshare_del); |
||||
E_FREE_FUNC(bat->vendor, eina_stringshare_del); |
||||
E_FREE_FUNC(bat->poll, ecore_poller_del); |
||||
#if defined(__FreeBSD__) || defined(__DragonFly__) |
||||
E_FREE_FUNC(bat->mib_state, free); |
||||
E_FREE_FUNC(bat->mib_time, free); |
||||
E_FREE_FUNC(bat->mib_units, free); |
||||
#endif |
||||
E_FREE_FUNC(bat->mib, free); |
||||
E_FREE_FUNC(bat, free); |
||||
} |
||||
} |
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) |
||||
static Eina_Bool |
||||
_batman_sysctl_battery_update_poll(void *data) |
||||
{ |
||||
Instance *inst = data; |
||||
_batman_sysctl_battery_update(inst); |
||||
return EINA_TRUE; |
||||
} |
||||
#endif |
||||
|
||||
static int |
||||
_batman_sysctl_battery_update(Instance *inst) |
||||
{ |
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) |
||||
double _time, charge; |
||||
struct sensor s; |
||||
size_t slen = sizeof(struct sensor); |
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) |
||||
double _time, charge; |
||||
int value; |
||||
size_t len; |
||||
#endif |
||||
|
||||
if (bat) |
||||
{ |
||||
/* update the poller interval */ |
||||
ecore_poller_poller_interval_set(bat->poll, |
||||
inst->cfg->batman.poll_interval); |
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) |
||||
/* last full capacity */ |
||||
bat->mib[3] = 7; |
||||
bat->mib[4] = 0; |
||||
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) |
||||
{ |
||||
bat->last_full_charge = (double)s.value; |
||||
} |
||||
|
||||
/* remaining capacity */ |
||||
bat->mib[3] = 7; |
||||
bat->mib[4] = 3; |
||||
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) |
||||
{ |
||||
charge = (double)s.value; |
||||
} |
||||
|
||||
/* This is a workaround because there's an ACPI bug */
|
||||
if (charge == 0 || bat->last_full_charge == 0) |
||||
{ |
||||
/* last full capacity */ |
||||
bat->mib[3] = 8; |
||||
bat->mib[4] = 0; |
||||
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) |
||||
{ |
||||
bat->last_full_charge = (double)s.value; |
||||
} |
||||
|
||||
/* remaining capacity */ |
||||
bat->mib[3] = 8; |
||||
bat->mib[4] = 3; |
||||
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) != -1) |
||||
{ |
||||
charge = (double)s.value; |
||||
} |
||||
} |
||||
|
||||
_time = ecore_time_get(); |
||||
if ((bat->got_prop) && (charge != bat->current_charge)) |
||||
bat->charge_rate = ((charge - bat->current_charge) / (_time - bat->last_update)); |
||||
bat->last_update = _time; |
||||
bat->current_charge = charge; |
||||
bat->percent = 100 * (bat->current_charge / bat->last_full_charge); |
||||
if (bat->current_charge >= bat->last_full_charge) |
||||
bat->percent = 100; |
||||
|
||||
if (bat->got_prop) |
||||
{ |
||||
if (bat->charge_rate > 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; |
||||
else |
||||
bat->time_full = (bat->last_full_charge - bat->current_charge) / bat->charge_rate; |
||||
bat->time_left = -1; |
||||
} |
||||
else |
||||
{ |
||||
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; |
||||
else |
||||
bat->time_left = (0 - bat->current_charge) / bat->charge_rate; |
||||
bat->time_full = -1; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
bat->time_full = -1; |
||||
bat->time_left = -1; |
||||
} |
||||
|
||||
/* battery state 1: discharge, 2: charge */ |
||||
bat->mib[3] = 10; |
||||
bat->mib[4] = 0; |
||||
if (sysctl(bat->mib, 5, &s, &slen, NULL, 0) == -1) |
||||
{ |
||||
if (s.value == 2) |
||||
bat->charging = 1; |
||||
else |
||||
bat->charging = 0; |
||||
} |
||||
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) |
||||
len = sizeof(value); |
||||
if ((sysctl(bat->mib, 4, &value, &len, NULL, 0)) == -1) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
bat->percent = value; |
||||
|
||||
_time = ecore_time_get(); |
||||
bat->last_update = _time; |
||||
|
||||
len = sizeof(value); |
||||
if ((sysctl(bat->mib_state, 4, &value, &len, NULL, 0)) == -1) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
bat->charging = !value; |
||||
bat->got_prop = 1; |
||||
|
||||
bat->time_full = -1; |
||||
bat->time_left = -1; |
||||
|
||||
len = sizeof(bat->time_min); |
||||
if ((sysctl(bat->mib_time, 4, &bat->time_min, &len, NULL, 0)) == -1) |
||||
{ |
||||
bat->time_min = -1; |
||||
} |
||||
|
||||
len = sizeof(bat->batteries); |
||||
if ((sysctl(bat->mib_units, 4, &bat->batteries, &len, NULL, 0)) == -1) |
||||
{ |
||||
bat->batteries = 1; |
||||
} |
||||
|
||||
if (bat->time_min >= 0) bat->time_left = bat->time_min * 60; |
||||
if (bat->batteries == 1) bat->time_left = -1; |
||||
#endif |
||||
}
|
||||
|
||||
if (ac) |
||||
{ |
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) |
||||
/* AC State */ |
||||
ac->mib[3] = 9; |
||||
ac->mib[4] = 0; |
||||
if (sysctl(ac->mib, 5, &s, &slen, NULL, 0) != -1) |
||||
{ |
||||
if (s.value) |
||||
ac->present = 1; |
||||
else |
||||
ac->present = 0; |
||||
} |
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) |
||||
len = sizeof(value); |
||||
if ((sysctl(ac->mib, 3, &value, &len, NULL, 0)) != -1) |
||||
{ |
||||
ac->present = value; |
||||
} |
||||
#endif |
||||
}
|
||||
|
||||
if (bat) |
||||
{ |
||||
if (bat->got_prop) |
||||
_batman_device_update(bat->inst); |
||||
bat->got_prop = 1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
|
@ -0,0 +1,320 @@ |
||||
#include "batman.h" |
||||
|
||||
static void _batman_udev_event_battery(const char *syspath, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch); |
||||
static void _batman_udev_event_ac(const char *syspath, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch); |
||||
static void _batman_udev_battery_add(const char *syspath, Instance *inst); |
||||
static void _batman_udev_ac_add(const char *syspath, Instance *inst); |
||||
static void _batman_udev_battery_del(const char *syspath); |
||||
static void _batman_udev_ac_del(const char *syspath); |
||||
static Eina_Bool _batman_udev_battery_update_poll(void *data); |
||||
static void _batman_udev_battery_update(const char *syspath, Battery *bat, Instance *inst); |
||||
static void _batman_udev_ac_update(const char *syspath, Ac_Adapter *ac, Instance *inst); |
||||
|
||||
extern Eina_List *batman_device_batteries; |
||||
extern Eina_List *batman_device_ac_adapters; |
||||
extern double batman_init_time; |
||||
|
||||
int |
||||
_batman_udev_start(Instance *inst) |
||||
{ |
||||
Eina_List *devices; |
||||
const char *dev; |
||||
|
||||
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_BAT, NULL); |
||||
EINA_LIST_FREE(devices, dev) |
||||
_batman_udev_battery_add(dev, inst); |
||||
|
||||
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_AC, NULL); |
||||
EINA_LIST_FREE(devices, dev) |
||||
_batman_udev_ac_add(dev, inst); |
||||
|
||||
if (!inst->cfg->batman.batwatch) |
||||
inst->cfg->batman.batwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_BAT, EEZE_UDEV_EVENT_NONE, _batman_udev_event_battery, inst); |
||||
if (!inst->cfg->batman.acwatch) |
||||
inst->cfg->batman.acwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_AC, EEZE_UDEV_EVENT_NONE, _batman_udev_event_ac, inst); |
||||
|
||||
batman_init_time = ecore_time_get(); |
||||
return 1; |
||||
} |
||||
|
||||
void |
||||
_batman_udev_stop(Instance *inst) |
||||
{ |
||||
Ac_Adapter *ac; |
||||
Battery *bat; |
||||
|
||||
if (inst->cfg->batman.batwatch) |
||||
E_FREE_FUNC(inst->cfg->batman.batwatch, eeze_udev_watch_del); |
||||
if (inst->cfg->batman.acwatch) |
||||
E_FREE_FUNC(inst->cfg->batman.acwatch, eeze_udev_watch_del); |
||||
|
||||
EINA_LIST_FREE(batman_device_ac_adapters, ac) |
||||
{ |
||||
E_FREE_FUNC(ac, free); |
||||
} |
||||
EINA_LIST_FREE(batman_device_batteries, bat) |
||||
{ |
||||
eina_stringshare_del(bat->udi); |
||||
eina_stringshare_del(bat->technology); |
||||
eina_stringshare_del(bat->model); |
||||
eina_stringshare_del(bat->vendor); |
||||
E_FREE_FUNC(bat->poll, ecore_poller_del); |
||||
E_FREE_FUNC(bat, free); |
||||
} |
||||
} |
||||
|
||||
static void |
||||
_batman_udev_event_battery(const char *syspath, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch EINA_UNUSED) |
||||
{ |
||||
Instance *inst = data; |
||||
|
||||
if ((event & EEZE_UDEV_EVENT_ADD) || |
||||
(event & EEZE_UDEV_EVENT_ONLINE)) |
||||
_batman_udev_battery_add(syspath, inst); |
||||
else if ((event & EEZE_UDEV_EVENT_REMOVE) || |
||||
(event & EEZE_UDEV_EVENT_OFFLINE)) |
||||
_batman_udev_battery_del(syspath); |
||||
else /* must be change */ |
||||
_batman_udev_battery_update(syspath, NULL, inst); |
||||
} |
||||
|
||||
static void |
||||
_batman_udev_event_ac(const char *syspath, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch EINA_UNUSED) |
||||
{ |
||||
Instance *inst = data; |
||||
|
||||
if ((event & EEZE_UDEV_EVENT_ADD) || |
||||
(event & EEZE_UDEV_EVENT_ONLINE)) |
||||
_batman_udev_ac_add(syspath, inst); |
||||
else if ((event & EEZE_UDEV_EVENT_REMOVE) || |
||||
(event & EEZE_UDEV_EVENT_OFFLINE)) |
||||
_batman_udev_ac_del(syspath); |
||||
else /* must be change */ |
||||
_batman_udev_ac_update(syspath, NULL, inst); |
||||
} |
||||
|
||||
static void |
||||
_batman_udev_battery_add(const char *syspath, Instance *inst) |
||||
{ |
||||
Battery *bat; |
||||
|
||||
if ((bat = _batman_battery_find(syspath))) |
||||
{ |
||||
eina_stringshare_del(syspath); |
||||
bat->inst = inst; |
||||
_batman_udev_battery_update(NULL, bat, inst); |
||||
return; |
||||
} |
||||
|
||||
if (!(bat = E_NEW(Battery, 1))) |
||||
{ |
||||
eina_stringshare_del(syspath); |
||||
return; |
||||
} |
||||
bat->inst = inst; |
||||
bat->last_update = ecore_time_get(); |
||||
bat->udi = eina_stringshare_add(syspath); |
||||
bat->poll = ecore_poller_add(ECORE_POLLER_CORE,
|
||||
bat->inst->cfg->batman.poll_interval,
|
||||
_batman_udev_battery_update_poll, bat); |
||||
batman_device_batteries = eina_list_append(batman_device_batteries, bat); |
||||
_batman_udev_battery_update(syspath, bat, inst); |
||||
} |
||||
|
||||
static void |
||||
_batman_udev_ac_add(const char *syspath, Instance *inst) |
||||
{ |
||||
Ac_Adapter *ac; |
||||
|
||||
if ((ac = _batman_ac_adapter_find(syspath))) |
||||
{ |
||||
eina_stringshare_del(syspath); |
||||
_batman_udev_ac_update(NULL, ac, inst); |
||||
return; |
||||
} |
||||
|
||||
if (!(ac = E_NEW(Ac_Adapter, 1))) |
||||
{ |
||||
eina_stringshare_del(syspath); |
||||
return; |
||||
} |
||||
ac->inst = inst; |
||||
ac->udi = eina_stringshare_add(syspath); |
||||
batman_device_ac_adapters = eina_list_append(batman_device_ac_adapters, ac); |
||||
_batman_udev_ac_update(syspath, ac, inst); |
||||
} |
||||
|
||||
static void |
||||
_batman_udev_battery_del(const char *syspath) |
||||
{ |
||||
Battery *bat; |
||||
|
||||
if (!(bat = _batman_battery_find(syspath))) |
||||
{ |
||||
eina_stringshare_del(syspath); |
||||
return; |
||||
} |
||||
|
||||
batman_device_batteries = eina_list_remove(batman_device_batteries, bat); |
||||
eina_stringshare_del(bat->udi); |
||||
eina_stringshare_del(bat->technology); |
||||
eina_stringshare_del(bat->model); |
||||
eina_stringshare_del(bat->vendor); |
||||
E_FREE_FUNC(bat->poll, ecore_poller_del); |
||||
E_FREE_FUNC(bat, free); |
||||
} |
||||
|
||||
static void |
||||
_batman_udev_ac_del(const char *syspath) |
||||
{ |
||||
Ac_Adapter *ac; |
||||
|
||||
if (!(ac = _batman_ac_adapter_find(syspath))) |
||||
{ |
||||
eina_stringshare_del(syspath); |
||||
_batman_device_update(ac->inst); |
||||
return; |
||||
} |
||||
|
||||
batman_device_ac_adapters = eina_list_remove(batman_device_ac_adapters, ac); |
||||
eina_stringshare_del(ac->udi); |
||||
E_FREE_FUNC(ac, free); |
||||
} |
||||
|
||||
static Eina_Bool
|
||||
_batman_udev_battery_update_poll(void *data) |
||||
{ |
||||
Battery *bat = data; |
||||
|
||||
_batman_udev_battery_update(NULL, bat, bat->inst); |
||||
|
||||
return EINA_TRUE; |
||||
} |
||||
|
||||
#define GET_NUM(TYPE, VALUE, PROP) \ |
||||
do \
|
||||
{ \
|
||||
test = eeze_udev_syspath_get_property(TYPE->udi, #PROP); \
|
||||
if (test) \
|
||||
{ \
|
||||
TYPE->VALUE = strtod(test, NULL); \
|
||||
eina_stringshare_del(test); \
|
||||
} \
|
||||
} \
|
||||
while (0) |
||||
|
||||
#define GET_STR(TYPE, VALUE, PROP) TYPE->VALUE = eeze_udev_syspath_get_property(TYPE->udi, #PROP) |
||||
|
||||
static void |
||||
_batman_udev_battery_update(const char *syspath, Battery *bat, Instance *inst) |
||||
{ |
||||
const char *test; |
||||
double t, charge; |
||||
|
||||
if (!bat) |
||||
{ |
||||
if (!(bat = _batman_battery_find(syspath))) |
||||
{ |
||||
_batman_udev_battery_add(syspath, inst); |
||||
return; |
||||
} |
||||
} |
||||
/* update the poller interval */ |
||||
ecore_poller_poller_interval_set(bat->poll, bat->inst->cfg->batman.poll_interval); |
||||
|
||||
GET_NUM(bat, present, POWER_SUPPLY_PRESENT); |
||||
if (!bat->got_prop) /* only need to get these once */ |
||||
{ |
||||
GET_STR(bat, technology, POWER_SUPPLY_TECHNOLOGY); |
||||
GET_STR(bat, model, POWER_SUPPLY_MODEL_NAME); |
||||
GET_STR(bat, vendor, POWER_SUPPLY_MANUFACTURER); |
||||
GET_NUM(bat, design_charge, POWER_SUPPLY_ENERGY_FULL_DESIGN); |
||||
if (!bat->design_charge) |
||||
GET_NUM(bat, design_charge, POWER_SUPPLY_CHARGE_FULL_DESIGN); |
||||
} |
||||
GET_NUM(bat, last_full_charge, POWER_SUPPLY_ENERGY_FULL); |
||||
if (!bat->last_full_charge) |
||||
GET_NUM(bat, last_full_charge, POWER_SUPPLY_CHARGE_FULL); |
||||
test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_ENERGY_NOW"); |
||||
if (!test) |
||||
test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_CHARGE_NOW"); |
||||
if (test) |
||||
{ |
||||
double charge_rate = 0; |
||||
|
||||
charge = strtod(test, NULL); |
||||
eina_stringshare_del(test); |
||||
t = ecore_time_get(); |
||||
if ((bat->got_prop) && (charge != bat->current_charge) && bat->current_charge != 0) |
||||
charge_rate = ((charge - bat->current_charge) / (t - bat->last_update)); |
||||
if (charge_rate != 0 || bat->last_update == 0 || bat->current_charge == 0) |
||||
{ |
||||
bat->last_update = t; |
||||
bat->current_charge = charge; |
||||
bat->charge_rate = charge_rate; |
||||
} |
||||
bat->percent = 100 * (bat->current_charge / bat->last_full_charge); |
||||
if (bat->got_prop) |
||||
{ |
||||
if (bat->charge_rate > 0) |
||||
{ |
||||
if (bat->inst->cfg->batman.fuzzy && (++bat->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; |
||||
else |
||||
bat->time_full = (bat->last_full_charge - bat->current_charge) / bat->charge_rate; |
||||
bat->time_left = -1; |
||||
} |
||||
else |
||||
{ |
||||
if (bat->inst->cfg->batman.fuzzy && (bat->inst->cfg->batman.fuzzcount <= 10) && (bat->time_left > 0)) |
||||
bat->time_left = (((0 - bat->current_charge) / bat->charge_rate) + bat->time_left) / 2; |
||||
else |
||||
bat->time_left = (0 - bat->current_charge) / bat->charge_rate; |
||||
bat->time_full = -1; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
bat->time_full = -1; |
||||
bat->time_left = -1; |
||||
} |
||||
} |
||||
if (bat->inst->cfg->batman.fuzzcount > 10) bat->inst->cfg->batman.fuzzcount = 0; |
||||
test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_STATUS"); |
||||
if (test) |
||||
{ |
||||
if (!strcmp(test, "Charging")) |
||||
bat->charging = 1; |
||||
else if ((!strcmp(test, "Unknown")) && (bat->charge_rate > 0)) |
||||
bat->charging = 1; |
||||
else |
||||
bat->charging = 0; |
||||
eina_stringshare_del(test); |
||||
} |
||||
else |
||||
bat->charging = 0; |
||||
if (bat->got_prop) |
||||
_batman_device_update(bat->inst); |
||||
bat->got_prop = 1; |
||||
} |
||||
|
||||
static void |
||||
_batman_udev_ac_update(const char *syspath, Ac_Adapter *ac, Instance *inst) |
||||
{ |
||||
const char *test; |
||||
|
||||
if (!ac) |
||||
{ |
||||
if (!(ac = _batman_ac_adapter_find(syspath))) |
||||
{ |
||||
_batman_udev_ac_add(syspath, inst); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
GET_NUM(ac, present, POWER_SUPPLY_ONLINE); |
||||
/* yes, it's really that simple. */ |
||||
|
||||
_batman_device_update(inst); |
||||
} |
||||
|
@ -0,0 +1,376 @@ |
||||
#include "batman.h" |
||||
|
||||
#define BUS "org.freedesktop.UPower" |
||||
#define PATH "/org/freedesktop/UPower" |
||||
#define IFACE "org.freedesktop.UPower" |
||||
|
||||
extern Eina_List *batman_device_batteries; |
||||
extern Eina_List *batman_device_ac_adapters; |
||||
extern double batman_init_time; |
||||
|
||||
static Eldbus_Connection *conn; |
||||
static Eldbus_Proxy *upower_proxy; |
||||
|
||||
typedef struct _Upower_Data Upower_Data; |
||||
struct _Upower_Data |
||||
{ |
||||
Eldbus_Proxy *proxy; |
||||
Instance *inst; |
||||
}; |
||||
|
||||
static void |
||||
_battery_free(Battery *bat) |
||||
{ |
||||
Eldbus_Object *obj = eldbus_proxy_object_get(bat->proxy); |
||||
eldbus_proxy_unref(bat->proxy); |
||||
eldbus_object_unref(obj); |
||||
|
||||
batman_device_batteries = eina_list_remove(batman_device_batteries, bat); |
||||
eina_stringshare_del(bat->udi); |
||||
|