udev mode enabled in battery module (--enable-device-udev) with polling time supported. udev times are extremely accurate AT THE TIME THAT THEY POLL.

I have added what I call "fuzzy mode", which (in udev mode only) averages the past 10 polling times to give a somewhat more readable measurement.
bugs: none that I know of?
todo: make fuzzy mode average the previous 10 times without resetting except on state change, fix "fuzzy mode" checkbox to only enable when udev is selected


SVN revision: 48973
This commit is contained in:
Mike Blumenkrantz 2010-05-18 10:39:30 +00:00
parent 7c2df0efc6
commit f7f417298b
7 changed files with 435 additions and 217 deletions

View File

@ -23,3 +23,4 @@ k-s (Gustavo Sverzut Barbieri) <barbieri@profusion.mobi>
Peter van de Werken <pwerken-e@a-eskwadraat.nl>
Florian Hackenberger <florian@hackenberger.at>
Hannes Janetzek <hannes.janetzek@gmail.com>
Mike Blumenkrantz (discomfitor/zmike) <mike@zentific.com>

View File

@ -253,9 +253,7 @@ else
fi
AC_MSG_RESULT($device_backend)
#will uncomment once this works
#AM_CONDITIONAL([HAVE_EEZE_UDEV], [test "x${device_backend}" = "xeeze_udev"])
AM_CONDITIONAL([HAVE_EEZE_UDEV], [test "x${device_backend}" = "x"])
AM_CONDITIONAL([HAVE_EEZE_UDEV], [test "x${device_backend}" = "xeeze_udev"])
# doxygen program for documentation building

View File

@ -5,11 +5,14 @@ struct _E_Config_Dialog_Data
{
int show_alert;
int poll_interval;
#ifdef HAVE_EEZE_UDEV
int fuzzy;
#endif
int alert_time;
int alert_percent;
int dismiss_alert;
int alert_timeout;
int force_mode; // 0 == auto, 1 == batget, 2 == dbus
int force_mode; // 0 == auto, 1 == batget, 2 == subsystem
struct
{
Evas_Object *show_alert_label;
@ -17,6 +20,9 @@ struct _E_Config_Dialog_Data
Evas_Object *show_alert_percent;
Evas_Object *dismiss_alert_label;
Evas_Object *alert_timeout;
#ifdef HAVE_EEZE_UDEV
Evas_Object *fuzzy;
#endif
} ui;
};
@ -65,6 +71,7 @@ _fill_data(E_Config_Dialog_Data *cfdata)
cfdata->poll_interval = battery_config->poll_interval;
cfdata->alert_timeout = battery_config->alert_timeout;
cfdata->force_mode = battery_config->force_mode;
cfdata->fuzzy = battery_config->fuzzy;
if ((cfdata->alert_time > 0) || (cfdata->alert_percent > 0))
cfdata->show_alert = 1;
@ -172,6 +179,17 @@ _cb_dismiss_alert_changed(void *data, Evas_Object *obj __UNUSED__)
e_widget_disabled_set(cfdata->ui.alert_timeout, !dismiss_alert);
}
#ifdef HAVE_EEZE_UDEV
static void
_cb_fuzzy(void *data, Evas_Object *obj __UNUSED__)
{
E_Config_Dialog_Data *cfdata = data;
Eina_Bool fuzzy = (cfdata->force_mode == SUBSYSTEM);
e_widget_disabled_set(cfdata->ui.fuzzy, !fuzzy);
}
#endif
static Evas_Object *
_advanced_create_widgets(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_Dialog_Data *cfdata)
{
@ -225,12 +243,17 @@ _advanced_create_widgets(E_Config_Dialog *cfd __UNUSED__, Evas *evas, E_Config_D
o = e_widget_list_add(evas, 0, 0);
rg = e_widget_radio_group_new(&(cfdata->force_mode));
ob = e_widget_radio_add(evas, _("Auto Detect"), 0, rg);
ob = e_widget_radio_add(evas, _("Auto Detect"), UNKNOWN, rg);
e_widget_list_object_append(o, ob, 1, 0, 0.0);
ob = e_widget_radio_add(evas, _("Internal"), 1, rg);
ob = e_widget_radio_add(evas, _("Internal"), NOSUBSYSTEM, rg);
e_widget_list_object_append(o, ob, 1, 0, 0.0);
#ifdef HAVE_EUDEV
ob = e_widget_radio_add(evas, _("udev"), 2, rg);
#ifdef HAVE_EEZE_UDEV
ob = e_widget_radio_add(evas, _("udev"), SUBSYSTEM, rg);
e_widget_on_change_hook_set(ob, _cb_fuzzy, cfdata);
e_widget_list_object_append(o, ob, 1, 0, 0.0);
ob = e_widget_check_add(evas, _("Fuzzy Mode"),
&(cfdata->fuzzy));
cfdata->ui.fuzzy = ob;
#else
ob = e_widget_radio_add(evas, _("HAL"), 2, rg);
#endif
@ -249,6 +272,7 @@ _advanced_apply_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfda
if (!battery_config) return 0;
battery_config->poll_interval = cfdata->poll_interval;
battery_config->fuzzy = cfdata->fuzzy;
if (cfdata->show_alert)
{
@ -285,6 +309,7 @@ _advanced_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *c
(cfdata->alert_percent != battery_config->alert_p) ||
(cfdata->poll_interval != battery_config->poll_interval) ||
(cfdata->alert_timeout != battery_config->alert_timeout) ||
(cfdata->fuzzy != battery_config->fuzzy) ||
(cfdata->force_mode != battery_config->force_mode) ||
(cfdata->show_alert != old_show_alert) ||
(cfdata->dismiss_alert != old_dismiss_alert));

View File

@ -1,8 +1,49 @@
#include "e.h"
#include "e_mod_main.h"
static void _battery_dbus_battery_props(void *data, void *reply_data, DBusError *error);
static void _battery_dbus_ac_adapter_props(void *data, void *reply_data, DBusError *error);
static void _battery_dbus_battery_property_changed(void *data, DBusMessage *msg);
static void _battery_dbus_battery_add(const char *udi);
static void _battery_dbus_battery_del(const char *udi);
static void _battery_dbus_ac_adapter_add(const char *udi);
static void _battery_dbus_ac_adapter_del(const char *udi);
static void _battery_dbus_find_battery(void *user_data, void *reply_data, DBusError *err);
static void _battery_dbus_find_ac(void *user_data, void *reply_data, DBusError *err);
static void _battery_dbus_is_battery(void *user_data, void *reply_data, DBusError *err);
static void _battery_dbus_is_ac_adapter(void *user_data, void *reply_data, DBusError *err);
static void _battery_dbus_dev_add(void *data, DBusMessage *msg);
static void _battery_dbus_dev_del(void *data, DBusMessage *msg);
void
_battery_dbus_shutdown(void)
_battery_dbus_start(void)
{
E_DBus_Connection *conn;
conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
if (!conn) return;
// FIXME: e_dbus doesnt allow us to track this pending call
e_hal_manager_find_device_by_capability
(conn, "battery", _battery_dbus_find_battery, NULL);
e_hal_manager_find_device_by_capability
(conn, "ac_adapter", _battery_dbus_find_ac, NULL);
battery_config->dbus.dev_add =
e_dbus_signal_handler_add(conn, E_HAL_SENDER,
E_HAL_MANAGER_PATH,
E_HAL_MANAGER_INTERFACE,
"DeviceAdded", _battery_dbus_dev_add, NULL);
battery_config->dbus.dev_del =
e_dbus_signal_handler_add(conn, E_HAL_SENDER,
E_HAL_MANAGER_PATH,
E_HAL_MANAGER_INTERFACE,
"DeviceRemoved", _battery_dbus_dev_del, NULL);
init_time = ecore_time_get();
}
void
_battery_dbus_stop(void)
{
E_DBus_Connection *conn;
Ac_Adapter *ac;
@ -29,30 +70,29 @@ _battery_dbus_shutdown(void)
{
e_dbus_signal_handler_del(conn, ac->prop_change);
eina_stringshare_del(ac->udi);
eina_stringshare_del(ac->product);
eina_stringshare_del(ac->product);
free(ac);
}
EINA_LIST_FREE(device_batteries, bat)
{
e_dbus_signal_handler_del(conn, bat->prop_change);
eina_stringshare_del(bat->udi);
eina_stringshare_del(bat->technology);
eina_stringshare_del(bat->type);
eina_stringshare_del(bat->charge_units);
eina_stringshare_del(bat->model);
eina_stringshare_del(bat->vendor);
eina_stringshare_del(bat->technology);
eina_stringshare_del(bat->type);
eina_stringshare_del(bat->charge_units);
eina_stringshare_del(bat->model);
eina_stringshare_del(bat->vendor);
free(bat);
}
}
void
static void
_battery_dbus_battery_props(void *data, void *reply_data, DBusError *error __UNUSED__)
{
E_Hal_Properties *ret = reply_data;
Battery *bat = data;
int err = 0;
const char *str;
uint64_t tmp;
if (dbus_error_is_set(error))
{
@ -72,7 +112,7 @@ _battery_dbus_battery_props(void *data, void *reply_data, DBusError *error __UNU
str = e_hal_property_string_get(ret, s, &err); \
if (str) \
{ \
bat->val = eina_stringshare_add(str); \
bat->val = eina_stringshare_ref(str); \
}
GET_BOOL(present, "battery.present");
@ -87,18 +127,23 @@ _battery_dbus_battery_props(void *data, void *reply_data, DBusError *error __UNU
GET_INT(charge_rate, "battery.charge_level.rate");
GET_INT(design_charge, "battery.charge_level.design");
GET_INT(last_full_charge, "battery.charge_level.last_full");
GET_INT(time_left, "battery.remaining_time");
GET_INT(time_full, "battery.remaining_time");
/* conform to upower */
if (e_hal_property_bool_get(ret, "battery.rechargeable.is_charging", &err))
bat->state = 1;
{
bat->charging = 1;
GET_INT(time_full, "battery.remaining_time");
bat->time_left = -1;
}
else
bat->state = 2;
{
bat->charging = 0;
GET_INT(time_left, "battery.remaining_time");
bat->time_full = -1;
}
bat->got_prop = 1;
_battery_device_update();
}
void
static void
_battery_dbus_ac_adapter_props(void *data, void *reply_data, DBusError *error __UNUSED__)
{
E_Hal_Properties *ret = reply_data;
@ -122,7 +167,7 @@ _battery_dbus_ac_adapter_props(void *data, void *reply_data, DBusError *error __
str = e_hal_property_string_get(ret, s, &err); \
if (str) \
{ \
ac->val = eina_stringshare_add(str); \
ac->val = eina_stringshare_ref(str); \
}
GET_BOOL(present, "ac_adapter.present");
@ -130,7 +175,7 @@ _battery_dbus_ac_adapter_props(void *data, void *reply_data, DBusError *error __
_battery_device_update();
}
void
static void
_battery_dbus_battery_property_changed(void *data, DBusMessage *msg __UNUSED__)
{
E_DBus_Connection *conn;
@ -142,7 +187,7 @@ _battery_dbus_battery_property_changed(void *data, DBusMessage *msg __UNUSED__)
_battery_dbus_battery_props, data);
}
void
static void
_battery_dbus_ac_adapter_property_changed(void *data, DBusMessage *msg __UNUSED__)
{
E_DBus_Connection *conn;
@ -154,7 +199,7 @@ _battery_dbus_ac_adapter_property_changed(void *data, DBusMessage *msg __UNUSED_
_battery_dbus_ac_adapter_props, data);
}
void
static void
_battery_dbus_battery_add(const char *udi)
{
E_DBus_Connection *conn;
@ -182,7 +227,7 @@ _battery_dbus_battery_add(const char *udi)
_battery_device_update();
}
void
static void
_battery_dbus_battery_del(const char *udi)
{
E_DBus_Connection *conn;
@ -197,6 +242,11 @@ _battery_dbus_battery_del(const char *udi)
e_dbus_signal_handler_del(conn, bat->prop_change);
l = eina_list_data_find(device_batteries, bat);
eina_stringshare_del(bat->udi);
eina_stringshare_del(bat->technology);
eina_stringshare_del(bat->type);
eina_stringshare_del(bat->charge_units);
eina_stringshare_del(bat->model);
eina_stringshare_del(bat->vendor);
free(bat);
device_batteries = eina_list_remove_list(device_batteries, l);
return;
@ -204,7 +254,7 @@ _battery_dbus_battery_del(const char *udi)
_battery_device_update();
}
void
static void
_battery_dbus_ac_adapter_add(const char *udi)
{
E_DBus_Connection *conn;
@ -227,7 +277,7 @@ _battery_dbus_ac_adapter_add(const char *udi)
_battery_device_update();
}
void
static void
_battery_dbus_ac_adapter_del(const char *udi)
{
E_DBus_Connection *conn;
@ -242,6 +292,7 @@ _battery_dbus_ac_adapter_del(const char *udi)
e_dbus_signal_handler_del(conn, ac->prop_change);
l = eina_list_data_find(device_ac_adapters, ac);
eina_stringshare_del(ac->udi);
eina_stringshare_del(ac->product);
free(ac);
device_ac_adapters = eina_list_remove_list(device_ac_adapters, l);
return;
@ -249,7 +300,7 @@ _battery_dbus_ac_adapter_del(const char *udi)
_battery_device_update();
}
void
static void
_battery_dbus_find_battery(void *user_data __UNUSED__, void *reply_data, DBusError *err __UNUSED__)
{
Eina_List *l;
@ -269,7 +320,7 @@ _battery_dbus_find_battery(void *user_data __UNUSED__, void *reply_data, DBusErr
_battery_dbus_battery_add(device);
}
void
static void
_battery_dbus_find_ac(void *user_data __UNUSED__, void *reply_data, DBusError *err __UNUSED__)
{
Eina_List *l;
@ -291,7 +342,7 @@ _battery_dbus_find_ac(void *user_data __UNUSED__, void *reply_data, DBusError *e
}
void
static void
_battery_dbus_is_battery(void *user_data, void *reply_data, DBusError *err)
{
char *udi = user_data;
@ -311,7 +362,7 @@ _battery_dbus_is_battery(void *user_data, void *reply_data, DBusError *err)
eina_stringshare_del(udi);
}
void
static void
_battery_dbus_is_ac_adapter(void *user_data, void *reply_data, DBusError *err)
{
char *udi = user_data;
@ -332,7 +383,7 @@ _battery_dbus_is_ac_adapter(void *user_data, void *reply_data, DBusError *err)
eina_stringshare_del(udi);
}
void
static void
_battery_dbus_dev_add(void *data __UNUSED__, DBusMessage *msg)
{
DBusError err;
@ -351,7 +402,7 @@ _battery_dbus_dev_add(void *data __UNUSED__, DBusMessage *msg)
_battery_dbus_is_ac_adapter, (void*)eina_stringshare_add(udi));
}
void
static void
_battery_dbus_dev_del(void *data __UNUSED__, DBusMessage *msg)
{
DBusError err;
@ -363,29 +414,3 @@ _battery_dbus_dev_del(void *data __UNUSED__, DBusMessage *msg)
_battery_dbus_battery_del(udi);
_battery_dbus_ac_adapter_del(udi);
}
void
_battery_dbus_have_dbus(void)
{
E_DBus_Connection *conn;
conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
if (!conn) return;
// FIXME: e_dbus doesnt allow us to track this pending call
e_hal_manager_find_device_by_capability
(conn, "battery", _battery_dbus_find_battery, NULL);
e_hal_manager_find_device_by_capability
(conn, "ac_adapter", _battery_dbus_find_ac, NULL);
battery_config->dbus.dev_add =
e_dbus_signal_handler_add(conn, E_HAL_SENDER,
E_HAL_MANAGER_PATH,
E_HAL_MANAGER_INTERFACE,
"DeviceAdded", _battery_dbus_dev_add, NULL);
battery_config->dbus.dev_del =
e_dbus_signal_handler_add(conn, E_HAL_SENDER,
E_HAL_MANAGER_PATH,
E_HAL_MANAGER_INTERFACE,
"DeviceRemoved", _battery_dbus_dev_del, NULL);
init_time = ecore_time_get();
}

View File

@ -79,7 +79,7 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
inst->warning = NULL;
inst->popup_battery = NULL;
#ifdef HAVE_EUDEV
#ifdef HAVE_EEZE_UDEV
eeze_udev_init();
#else
e_dbus_init();
@ -100,8 +100,8 @@ _gc_shutdown(E_Gadcon_Client *gcc)
{
Instance *inst;
#ifdef HAVE_EUDEV
e_udev_shutdown();
#ifdef HAVE_EEZE_UDEV
eeze_udev_shutdown();
#else
e_hal_shutdown();
e_dbus_shutdown();
@ -253,8 +253,8 @@ _battery_battery_find(const char *udi)
Eina_List *l;
Battery *bat;
EINA_LIST_FOREACH(device_batteries, l, bat)
{
if (!strcmp(udi, bat->udi)) return bat;
{/* these are always stringshared */
if (udi == bat->udi) return bat;
}
return NULL;
@ -266,8 +266,8 @@ _battery_ac_adapter_find(const char *udi)
Eina_List *l;
Ac_Adapter *ac;
EINA_LIST_FOREACH(device_ac_adapters, l, ac)
{
if (!strcmp(udi, ac->udi)) return ac;
{/* these are always stringshared */
if (udi == ac->udi) return ac;
}
return NULL;
@ -277,40 +277,35 @@ void
_battery_device_update(void)
{
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;
int state = 0;
for (l = device_ac_adapters; l; l = l->next)
{
Battery *ac;
ac = l->data;
EINA_LIST_FOREACH(device_ac_adapters, l, ac)
if (ac->present) acnum++;
}
for (l = device_batteries; l; l = l->next)
EINA_LIST_FOREACH(device_batteries, l, bat)
{
Battery *bat;
bat = l->data;
if (!bat->got_prop)
continue;
if (!bat->got_prop)
continue;
have_battery = 1;
batnum++;
if (bat->state == 1) have_power = 1;
if (bat->charging == 1) have_power = 1;
if (full == -1) full = 0;
if (bat->last_full_charge > 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;
else if (bat->percent >= 0)
full += bat->percent;
if (bat->time_left > 0)
{
if (time_left < 0) time_left = bat->time_left;
@ -321,7 +316,7 @@ _battery_device_update(void)
if (time_full < 0) time_full = bat->time_full;
else time_full += bat->time_full;
}
state += bat->state;
charging += bat->charging;
}
if ((device_batteries) && (batnum == 0))
@ -329,7 +324,6 @@ _battery_device_update(void)
if (batnum > 0) full /= batnum;
if (!state) time_left = -1;
if (time_left < 1) time_left = -1;
if (time_full < 1) time_full = -1;
@ -342,26 +336,29 @@ _battery_device_update(void)
void
_battery_config_updated(void)
{
Eina_List *l = NULL;
Eina_List *l;
Instance *inst;
char buf[4096];
if (!battery_config) return;
if (battery_config->instances)
{
for (l = battery_config->instances; l; l = l->next)
_battery_warning_popup_destroy(l->data);
EINA_LIST_FOREACH(battery_config->instances, l, inst)
_battery_warning_popup_destroy(inst);
}
if (battery_config->have_subsystem == UNKNOWN)
{
#ifndef HAVE_EUDEV
#ifdef HAVE_EEZE_UDEV
battery_config->have_subsystem = SUBSYSTEM;
#else
if (!e_dbus_bus_get(DBUS_BUS_SYSTEM))
#endif
battery_config->have_subsystem = NOSUBSYSTEM;
#endif
}
if ((battery_config->have_subsystem == NOSUBSYSTEM) ||
(battery_config->force_mode == 1))
(battery_config->force_mode == NOSUBSYSTEM))
{
if (battery_config->batget_exe)
{
@ -378,7 +375,7 @@ _battery_config_updated(void)
ECORE_EXE_NOT_LEADER, NULL);
}
else if ((battery_config->have_subsystem == UNKNOWN) ||
(battery_config->force_mode == 2))
(battery_config->force_mode == SUBSYSTEM))
{
if (battery_config->batget_exe)
{
@ -386,7 +383,7 @@ _battery_config_updated(void)
ecore_exe_free(battery_config->batget_exe);
battery_config->batget_exe = NULL;
}
#ifdef HAVE_EUDEV
#ifdef HAVE_EEZE_UDEV
_battery_udev_start();
#else
E_DBus_Connection *conn;
@ -394,12 +391,11 @@ _battery_config_updated(void)
if (conn)
{
battery_config->have_subsystem = SUBSYSTEM;
_battery_dbus_have_dbus();
#endif
_battery_dbus_start();
}
else
battery_config->have_subsystem = NOSUBSYSTEM;
#endif
}
}
@ -514,7 +510,7 @@ _battery_update(int full, int time_left, int time_full, Eina_Bool have_battery,
{
if (have_power != battery_config->have_power)
{
if (have_power)
if (have_power && (full < 100))
edje_object_signal_emit(inst->o_battery,
"e,state,charging",
"e");
@ -549,14 +545,14 @@ _battery_update(int full, int time_left, int time_full, Eina_Bool have_battery,
_("N/A"));
}
if (time_left != battery_config->time_left && !have_power)
if ((time_full < 0) && (time_left != battery_config->time_left))
{
_battery_face_time_set(inst->o_battery, time_left);
if (inst->popup_battery)
_battery_face_time_set(inst->popup_battery,
time_left);
}
else if (time_full != battery_config->time_full && have_power)
else if ((time_left < 0) && (time_full != battery_config->time_full))
{
_battery_face_time_set(inst->o_battery, time_full);
if (inst->popup_battery)
@ -602,60 +598,54 @@ static int
_battery_cb_exe_data(void *data __UNUSED__, int type __UNUSED__, void *event)
{
Ecore_Exe_Event_Data *ev;
Instance *inst;
Eina_List *l;
int i;
ev = event;
if (ev->exe != battery_config->batget_exe) return 1;
if ((ev->lines) && (ev->lines[0].line))
{
int i;
for (i = 0; ev->lines[i].line; i++)
{
if (!strcmp(ev->lines[i].line, "ERROR"))
{
Eina_List *l;
for (l = battery_config->instances; l; l = l->next)
{
Instance *inst;
inst = l->data;
edje_object_signal_emit(inst->o_battery,
"e,state,unknown", "e");
edje_object_part_text_set(inst->o_battery,
"e.text.reading", _("ERROR"));
edje_object_part_text_set(inst->o_battery,
"e.text.time", _("ERROR"));
for (i = 0; ev->lines[i].line; i++)
{
if (!strcmp(ev->lines[i].line, "ERROR"))
EINA_LIST_FOREACH(battery_config->instances, l, inst)
{
edje_object_signal_emit(inst->o_battery,
"e,state,unknown", "e");
edje_object_part_text_set(inst->o_battery,
"e.text.reading", _("ERROR"));
edje_object_part_text_set(inst->o_battery,
"e.text.time", _("ERROR"));
if (inst->popup_battery)
{
edje_object_signal_emit(inst->popup_battery,
"e,state,unknown", "e");
"e,state,unknown", "e");
edje_object_part_text_set(inst->popup_battery,
"e.text.reading", _("ERROR"));
"e.text.reading", _("ERROR"));
edje_object_part_text_set(inst->popup_battery,
"e.text.time", _("ERROR"));
"e.text.time", _("ERROR"));
}
}
}
else
{
int full = 0;
int time_left = 0;
int time_full = 0;
int have_battery = 0;
int have_power = 0;
if (sscanf(ev->lines[i].line, "%i %i %i %i %i",
&full, &time_left, &time_full,
&have_battery, &have_power)
== 5)
}
else
{
int full = 0;
int time_left = 0;
int time_full = 0;
int have_battery = 0;
int have_power = 0;
if (sscanf(ev->lines[i].line, "%i %i %i %i %i", &full, &time_left, &time_full,
&have_battery, &have_power) == 5)
_battery_update(full, time_left, time_full,
have_battery, have_power);
have_battery, have_power);
else
e_powersave_mode_set(E_POWERSAVE_MODE_LOW);
}
}
}
}
}
return 0;
}
@ -771,7 +761,11 @@ e_modapi_shutdown(E_Module *m __UNUSED__)
battery_config->menu = NULL;
}
_battery_dbus_shutdown();
#ifdef HAVE_EEZE_UDEV
_battery_udev_stop();
#else
_battery_dbus_stop();
#endif
free(battery_config);
battery_config = NULL;

View File

@ -41,9 +41,11 @@ struct _Config
int have_battery;
int have_power;
int have_subsystem;
#ifdef HAVE_EUDEV
#ifdef HAVE_EEZE_UDEV
Eeze_Udev_Watch *acwatch;
Eeze_Udev_Watch *batwatch;
Eina_Bool fuzzy;
int fuzzcount;
#else
struct {
// FIXME: on bat_conf del dbus_pending_call_cancel(dbus.have);
@ -62,14 +64,24 @@ typedef struct _Ac_Adapter Ac_Adapter;
struct _Battery
{
const char *udi;
#ifdef HAVE_EUDEV
Eeze_Udev_Watch *watch;
#ifdef HAVE_EEZE_UDEV
Ecore_Poller *poll;
#else
E_DBus_Signal_Handler *prop_change;
Eina_Bool can_charge:1;
#endif
Eina_Bool present:1;
Eina_Bool can_charge:1;
int state;
Eina_Bool charging:1;
#ifdef HAVE_EEZE_UDEV
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;
@ -77,9 +89,10 @@ struct _Battery
int charge_rate;
int time_full;
int time_left;
const char *technology;
const char *type;
const char *charge_units;
#endif
const char *technology;
const char *model;
const char *vendor;
Eina_Bool got_prop:1;
@ -88,9 +101,7 @@ struct _Battery
struct _Ac_Adapter
{
const char *udi;
#ifdef HAVE_EUDEV
Eeze_Udev_Watch *watch;
#else
#ifndef HAVE_EEZE_UDEV
E_DBus_Signal_Handler *prop_change;
#endif
Eina_Bool present:1;
@ -99,26 +110,14 @@ struct _Ac_Adapter
Battery *_battery_battery_find(const char *udi);
Ac_Adapter *_battery_ac_adapter_find(const char *udi);
/* in e_mod_dbus.c */
void _battery_dbus_battery_props(void *data, void *reply_data, DBusError *error);
void _battery_dbus_ac_adapter_props(void *data, void *reply_data, DBusError *error);
void _battery_dbus_battery_property_changed(void *data, DBusMessage *msg);
void _battery_dbus_battery_add(const char *udi);
void _battery_dbus_battery_del(const char *udi);
void _battery_dbus_ac_adapter_add(const char *udi);
void _battery_dbus_ac_adapter_del(const char *udi);
void _battery_dbus_find_battery(void *user_data, void *reply_data, DBusError *err);
void _battery_dbus_find_ac(void *user_data, void *reply_data, DBusError *err);
void _battery_dbus_is_battery(void *user_data, void *reply_data, DBusError *err);
void _battery_dbus_is_ac_adapter(void *user_data, void *reply_data, DBusError *err);
void _battery_dbus_dev_add(void *data, DBusMessage *msg);
void _battery_dbus_dev_del(void *data, DBusMessage *msg);
void _battery_dbus_have_dbus(void);
void _battery_dbus_shutdown(void);
void _battery_device_update(void);
/* in e_mod_dbus.c */
void _battery_dbus_start(void);
void _battery_dbus_stop(void);
/* end e_mod_dbus.c */
/* in e_mod_udev.c */
void _battery_udev_start(void);
void _battery_udev_stop(void);
/* end e_mod_udev.c */
Eina_List *device_batteries;
Eina_List *device_ac_adapters;

View File

@ -1,20 +1,69 @@
#include "e.h"
#include "e_mod_main.h"
void
_battery_udev_start()
{
device_batteries = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_BAT, NULL);
device_ac_adapters = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_AC, NULL);
static void _battery_udev_event_battery(const char *syspath, const char *event, void *data, Eeze_Udev_Watch *watch);
static void _battery_udev_event_ac(const char *syspath, const char *event, void *data, Eeze_Udev_Watch *watch);
static void _battery_udev_battery_add(const char *syspath);
static void _battery_udev_ac_add(const char *syspath);
static void _battery_udev_battery_del(const char *syspath);
static void _battery_udev_ac_del(const char *syspath);
static int _battery_udev_battery_update_poll(void *data);
static void _battery_udev_battery_update(const char *syspath, Battery *bat);
static void _battery_udev_ac_update(const char *syspath, Ac_Adapter *ac);
battery_config->batwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_BAT, _battery_udev_event_battery, NULL);
battery_config->acwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_AC, _battery_udev_event_ac, NULL);
void
_battery_udev_start(void)
{
Eina_List *l, *devices;
const char *dev;
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_BAT, NULL);
EINA_LIST_FOREACH(devices, l, dev)
_battery_udev_battery_add(dev);
eina_list_free(devices);
devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_AC, NULL);
EINA_LIST_FOREACH(devices, l, dev)
_battery_udev_ac_add(dev);
eina_list_free(devices);
if (!battery_config->batwatch)
battery_config->batwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_BAT, _battery_udev_event_battery, NULL);
if (!battery_config->batwatch)
battery_config->acwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_AC, _battery_udev_event_ac, NULL);
init_time = ecore_time_get();
}
void
_battery_udev_event_battery(const char syspath, const char *event, void *data, Eeze_Udev_Watch *watch)
void
_battery_udev_stop(void)
{
Ac_Adapter *ac;
Battery *bat;
if (battery_config->batwatch)
eeze_udev_watch_del(battery_config->batwatch);
if (battery_config->acwatch)
eeze_udev_watch_del(battery_config->acwatch);
EINA_LIST_FREE(device_ac_adapters, ac)
{
free(ac);
}
EINA_LIST_FREE(device_batteries, bat)
{
eina_stringshare_del(bat->udi);
eina_stringshare_del(bat->technology);
eina_stringshare_del(bat->model);
eina_stringshare_del(bat->vendor);
ecore_poller_del(bat->poll);
free(bat);
}
}
static void
_battery_udev_event_battery(const char *syspath, const char *event, void *data, Eeze_Udev_Watch *watch)
{
if ((!strcmp(event, "add")) || (!strcmp(event, "online")))
_battery_udev_battery_add(syspath);
@ -24,8 +73,8 @@ _battery_udev_event_battery(const char syspath, const char *event, void *data, E
_battery_udev_battery_update(syspath, data);
}
void
_battery_udev_event_ac(const char syspath, const char *event, void *data, Eeze_Udev_Watch *watch)
static void
_battery_udev_event_ac(const char *syspath, const char *event, void *data, Eeze_Udev_Watch *watch)
{
if ((!strcmp(event, "add")) || (!strcmp(event, "online")))
_battery_udev_ac_add(syspath);
@ -35,79 +84,206 @@ _battery_udev_event_ac(const char syspath, const char *event, void *data, Eeze_U
_battery_udev_ac_update(syspath, data);
}
void
static void
_battery_udev_battery_add(const char *syspath)
{
Battery *bat;
if (!(bat = _battery_battery_find(syspath)))
if ((bat = _battery_battery_find(syspath)))
{
if (!(bat = E_NEW(Battery, 1);
{
eina_stringshare_del(syspath);
return;
}
bat->udi = syspath; /* already stringshared */
device_batteries = eina_list_append(device_batteries, bat);
bat->watch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_BAT, _battery_udev_event_battery, bat);
_battery_udev_battery_init(bat);
eina_stringshare_del(syspath);
_battery_udev_battery_update(NULL, bat);
return;
}
_battery_device_update();
if (!(bat = E_NEW(Battery, 1)))
{
eina_stringshare_del(syspath);
return;
}
bat->last_update = ecore_time_get();
bat->udi = eina_stringshare_add(syspath);
bat->poll = ecore_poller_add(ECORE_POLLER_CORE, battery_config->poll_interval, _battery_udev_battery_update_poll, bat);
device_batteries = eina_list_append(device_batteries, bat);
_battery_udev_battery_update(syspath, bat);
}
void
static void
_battery_udev_ac_add(const char *syspath)
{
Ac_Adapter *ac;
if (!(ac = _battery_ac_adapter_find(syspath)))
if ((ac = _battery_ac_adapter_find(syspath)))
{
if (!(ac = E_NEW(Ac_Adapter, 1);
{
eina_stringshare_del(syspath);
return;
}
ac->udi = syspath; /* already stringshared */
device_ac_adapters = eina_list_append(device_ac_adapters, ac);
ac->watch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_AC, _battery_udev_event_ac, ac);
_battery_udev_ac_init(ac);
eina_stringshare_del(syspath);
_battery_udev_ac_update(NULL, ac);
return;
}
_battery_device_update();
if (!(ac = E_NEW(Ac_Adapter, 1)))
{
eina_stringshare_del(syspath);
return;
}
ac->udi = eina_stringshare_add(syspath);
device_ac_adapters = eina_list_append(device_ac_adapters, ac);
_battery_udev_ac_update(syspath, ac);
}
void
static void
_battery_udev_battery_del(const char *syspath)
{
Eina_List *l;
Battery *bat;
if ((battery = _battery_battery_find(syspath)))
if (!(bat = _battery_battery_find(syspath)))
{
eeze_udev_watch_del(bat->watch);
l = eina_list_data_find(device_batteries, bat);
eina_stringshare_del(bat->udi);
free(bat);
device_batteries = eina_list_remove_list(device_batteries, l);
eina_stringshare_del(syspath);
_battery_device_update();
return;
}
_battery_device_update();
l = eina_list_data_find(device_batteries, bat);
eina_stringshare_del(bat->udi);
eina_stringshare_del(bat->technology);
eina_stringshare_del(bat->model);
eina_stringshare_del(bat->vendor);
ecore_poller_del(bat->poll);
free(bat);
device_batteries = eina_list_remove_list(device_batteries, l);
}
void
static void
_battery_udev_ac_del(const char *syspath)
{
Eina_List *l;
Ac_Adapter *ac;
if ((ac = _battery_ac_adapter_find(syspath)))
if (!(ac = _battery_ac_adapter_find(syspath)))
{
eeze_udev_watch_del(ac->watch);
l = eina_list_data_find(device_ac_adapters, ac);
eina_stringshare_del(ac->udi);
free(ac);
device_ac_adapters = eina_list_remove_list(device_ac_adapters, l);
eina_stringshare_del(syspath);
_battery_device_update();
return;
}
_battery_device_update();
l = eina_list_data_find(device_ac_adapters, ac);
eina_stringshare_del(ac->udi);
free(ac);
device_ac_adapters = eina_list_remove_list(device_ac_adapters, l);
}
static int
_battery_udev_battery_update_poll(void *data)
{
_battery_udev_battery_update(NULL, data);
return 1;
}
#define GET_NUM(TYPE, VALUE, PROP) test = eeze_udev_syspath_get_property(TYPE->udi, #PROP); \
do \
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
_battery_udev_battery_update(const char *syspath, Battery *bat)
{
const char *test;
double time, charge;
if (!bat)
{
if (!(bat = _battery_battery_find(syspath)))
return _battery_udev_battery_add(syspath);
}
/* reset the poller */
ecore_poller_del(bat->poll);
bat->poll = ecore_poller_add(ECORE_POLLER_CORE, battery_config->poll_interval, _battery_udev_battery_update_poll, bat);
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);
GET_NUM(bat, last_full_charge, POWER_SUPPLY_ENERGY_FULL);
}
test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_ENERGY_NOW");
if (test)
{
charge = strtod(test, NULL);
eina_stringshare_del(test);
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->got_prop)
{
if (bat->charge_rate > 0)
{
if (battery_config->fuzzy && (++battery_config->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 (battery_config->fuzzy && (battery_config->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 (battery_config->fuzzcount > 10) battery_config->fuzzcount = 0;
test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_STATUS");
if (test)
{
if (!strcmp(test, "Charging"))
{
bat->charging = 1;
}
else
bat->charging = 0;
eina_stringshare_del(test);
}
else
bat->charging = 0;
if (bat->got_prop)
_battery_device_update();
bat->got_prop = 1;
}
static void
_battery_udev_ac_update(const char *syspath, Ac_Adapter *ac)
{
const char *test;
if (!ac)
{
if (!(ac = _battery_ac_adapter_find(syspath)))
return _battery_udev_ac_add(syspath);
}
GET_NUM(ac, present, POWER_SUPPLY_ONLINE);
/* yes, it's really that simple. */
_battery_device_update();
}