This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository enlightenment.
View the commit online.
commit 7c0201778c375b99582599e045240b716e650684
Author: Carsten Haitzler <[email protected]>
AuthorDate: Tue Dec 2 09:40:24 2025 +0000
battery - move udev battery/ac polling to thread
this should fix slow battery/ac firmware responses by dedicating a
thread to this instead of the main loop
fixes #123
---
src/modules/battery/e_mod_main.c | 6 +-
src/modules/battery/e_mod_main.h | 1 -
src/modules/battery/e_mod_udev.c | 862 ++++++++++++++++++++++-----------------
3 files changed, 500 insertions(+), 369 deletions(-)
diff --git a/src/modules/battery/e_mod_main.c b/src/modules/battery/e_mod_main.c
index 6ab95e827..c7edb37f7 100644
--- a/src/modules/battery/e_mod_main.c
+++ b/src/modules/battery/e_mod_main.c
@@ -12,9 +12,9 @@ static const char *_gc_label(const E_Gadcon_Client_Class *client_class);
static Evas_Object *_gc_icon(const E_Gadcon_Client_Class *client_class, Evas *evas);
static const char *_gc_id_new(const E_Gadcon_Client_Class *client_class);
-Eina_List *device_batteries;
-Eina_List *device_ac_adapters;
-double init_time;
+Eina_List *device_batteries = NULL;
+Eina_List *device_ac_adapters = NULL;
+double init_time = 0.0;
/* and actually define the gadcon class that this module provides (just 1) */
static const E_Gadcon_Client_Class _gadcon_class =
diff --git a/src/modules/battery/e_mod_main.h b/src/modules/battery/e_mod_main.h
index 03cb86e3e..c91021b00 100644
--- a/src/modules/battery/e_mod_main.h
+++ b/src/modules/battery/e_mod_main.h
@@ -96,7 +96,6 @@ struct _Battery
{
const char *udi;
#if defined HAVE_EEZE || defined __OpenBSD__ || defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__
- Ecore_Timer *timer;
Eina_Bool present E_BITFIELD;
Eina_Bool charging E_BITFIELD;
Eina_Bool is_micro_watts E_BITFIELD;
diff --git a/src/modules/battery/e_mod_udev.c b/src/modules/battery/e_mod_udev.c
index 046740565..a99cdf0fe 100644
--- a/src/modules/battery/e_mod_udev.c
+++ b/src/modules/battery/e_mod_udev.c
@@ -10,165 +10,504 @@ 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 Eina_Bool _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);
extern Eina_List *device_batteries;
extern Eina_List *device_ac_adapters;
extern double init_time;
+static Ecore_Timer *_poll_timer = NULL;
+static Ecore_Thread *_poll_thread = NULL;
+static Ecore_Pipe *_poll_pipe = NULL;
+static Eina_Lock _poll_lock;
+
+typedef struct
+{
+ const char *udi;
+
+ const char *technology;
+ const char *model;
+ const char *vendor;
+ double power_now;
+ double design_charge;
+ double last_full_charge;
+ double charge;
+ int charge_lim;
+ Eina_Bool present E_BITFIELD;
+ Eina_Bool charging E_BITFIELD;
+ Eina_Bool is_micro_watts E_BITFIELD;
+
+ Eina_Bool is_bat E_BITFIELD;
+ Eina_Bool is_ac E_BITFIELD;
+} Bat_Poll_Info;
+
+# define GET_NUM(TYPE, VALUE, PROP) \
+ do \
+ { \
+ const char *_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)
+
+//////////////////////////////////////////////////////////////////////////////
+////////// in thread
+static void
+_cb_poll_pipe(void *data EINA_UNUSED, void *buf EINA_UNUSED, unsigned int bytes EINA_UNUSED)
+{ // called in thread when data arrives from main loop in thread loop
+ // don't care about the data - it just woke us up
+}
+
+static void
+_cb_poll_thread(void *data EINA_UNUSED, Ecore_Thread *thread)
+{ // thread loop function sitting there waiting on input
+ while (!ecore_thread_check(thread))
+ {
+ if (ecore_pipe_wait(_poll_pipe, 1, 3600.0) < 1)
+ { // timeout waiting for msg from main loop
+ printf("BAT: timeout waiting for mainloop poll message in udev thread\n");
+ }
+ else
+ { // poll bat data and send results back to mainloop
+ Eina_List *l;
+ Battery *bat;
+ Ac_Adapter *ac;
+
+ eina_lock_take(&_poll_lock);
+ // we only read bat and ac - don't write
+ EINA_LIST_FOREACH(device_batteries, l, bat)
+ {
+ Bat_Poll_Info *bi = calloc(1, sizeof(Bat_Poll_Info));
+
+ if (bi)
+ {
+ const char *test;
+ double voltage_now;
+
+ bi->udi = eina_stringshare_add(bat->udi);
+ bi->is_bat = EINA_TRUE;
+ GET_NUM(bi, present, POWER_SUPPLY_PRESENT);
+ if (!bat->got_prop) /* only need to get these once */
+ {
+ GET_STR(bi, technology, POWER_SUPPLY_TECHNOLOGY);
+ GET_STR(bi, model, POWER_SUPPLY_MODEL_NAME);
+ GET_STR(bi, vendor, POWER_SUPPLY_MANUFACTURER);
+ GET_NUM(bi, design_charge, POWER_SUPPLY_ENERGY_FULL_DESIGN);
+ if (eina_dbl_exact(bi->design_charge, 0))
+ {
+ GET_NUM(bi, design_charge, POWER_SUPPLY_CHARGE_FULL_DESIGN);
+ if (bat->design_voltage > 0.0)
+ {
+ bi->design_charge = bi->design_charge * bat->design_voltage / 1000000.0;
+ bi->is_micro_watts = EINA_TRUE;
+ }
+ }
+ }
+ voltage_now = bat->design_voltage;
+ test = eeze_udev_syspath_get_property(bi->udi, "POWER_SUPPLY_VOLTAGE_NOW");
+ if (test)
+ {
+ voltage_now = (double)strtod(test, NULL);
+ eina_stringshare_del(test);
+ }
+ GET_NUM(bi, power_now, POWER_SUPPLY_POWER_NOW);
+ if (eina_dbl_exact(bi->power_now, 0))
+ {
+ test = eeze_udev_syspath_get_property(bi->udi, "POWER_SUPPLY_CURRENT_NOW");
+ if (test)
+ {
+ double current_now = strtod(test, NULL);
+
+ eina_stringshare_del(test);
+ if (voltage_now > 0.0)
+ bi->power_now = current_now * voltage_now / 1000000.0;
+ }
+ }
+ GET_NUM(bi, last_full_charge, POWER_SUPPLY_ENERGY_FULL);
+ if (eina_dbl_exact(bi->last_full_charge, 0))
+ {
+ GET_NUM(bi, last_full_charge, POWER_SUPPLY_CHARGE_FULL);
+ if (bat->design_voltage > 0.0)
+ {
+ bi->last_full_charge = bi->last_full_charge * bat->design_voltage / 1000000.0;
+ bi->is_micro_watts = EINA_TRUE;
+ }
+ }
+ else bi->is_micro_watts = EINA_TRUE;
+ test = eeze_udev_syspath_get_property(bi->udi, "POWER_SUPPLY_STATUS");
+ if (test)
+ {
+ if (!strcmp(test, "Charging"))
+ bi->charging = 1;
+ else if ((!strcmp(test, "Unknown")) && (bat->charge_rate > 0))
+ bi->charging = 1;
+ else
+ bi->charging = 0;
+ eina_stringshare_del(test);
+ }
+ else bi->charging = 0;
+
+ test = eeze_udev_syspath_get_sysattr(bi->udi, "charge_control_end_threshold");
+ if (!test) bi->charge_lim = -1;
+ else bi->charge_lim = atoi(test);
+
+ bi->charge = -1.0;
+ test = eeze_udev_syspath_get_property(bi->udi, "POWER_SUPPLY_ENERGY_NOW");
+ if (!test)
+ test = eeze_udev_syspath_get_property(bi->udi, "POWER_SUPPLY_CHARGE_NOW");
+ if (!test)
+ {
+ if (eina_dbl_exact(bi->last_full_charge, 0))
+ {
+ bi->last_full_charge = 10000;
+ bi->design_charge = 10000;
+ }
+ test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_CAPACITY");
+ }
+ if (test) bi->charge = strtod(test, NULL);
+ ecore_thread_feedback(thread, bi); // send poll info to mainloop
+ }
+ }
+ EINA_LIST_FOREACH(device_ac_adapters, l, ac)
+ {
+ Bat_Poll_Info *bi = calloc(1, sizeof(Bat_Poll_Info));
+
+ if (bi)
+ {
+ bi->udi = eina_stringshare_add(ac->udi);
+ bi->is_ac = EINA_TRUE;
+ GET_NUM(bi, present, POWER_SUPPLY_ONLINE);
+ ecore_thread_feedback(thread, bi); // send poll info to mainloop
+ }
+ }
+ eina_lock_release(&_poll_lock);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+////////// in main loop
+static void
+_poll_wakeup(void)
+{ // in main loop
+ int dummy = 1;
+ ecore_pipe_write(_poll_pipe, &dummy, sizeof(dummy));
+}
+
+static void
+_devices_timer_clean(void)
+{ // in main loop
+ if ((!device_batteries) && (!device_ac_adapters))
+ {
+ if (_poll_timer)
+ {
+ ecore_timer_del(_poll_timer);
+ _poll_timer = NULL;
+ }
+ }
+}
+
+static void
+_devices_timer_ensure(void)
+{ // in main loop
+ if (_poll_timer) return;
+ _poll_timer = ecore_timer_add(10.0, _battery_udev_battery_update_poll, NULL);
+}
+
+static void
+_cb_poll_thread_reply(void *data EINA_UNUSED, Ecore_Thread *thread EINA_UNUSED, void *msg)
+{ // in main loop
+ // feedback reply from thread loop called in main loop
+ Bat_Poll_Info *bi = msg;
+
+ eina_lock_take(&_poll_lock);
+ if (bi->is_bat)
+ {
+ Battery *bat = _battery_battery_find(bi->udi);
+
+ if (bat)
+ {
+ int pcharging = bat->charging;
+
+ if (!bat->got_prop)
+ {
+#define REPSTR(_x) if (bi->_x) eina_stringshare_replace(&(bat->_x), bi->_x);
+ REPSTR(technology);
+ REPSTR(model);
+ REPSTR(vendor);
+ bat->design_charge = bi->design_charge;
+ }
+ bat->power_now = bi->power_now;
+ bat->last_full_charge = bi->last_full_charge;
+ bat->charge_lim = bi->charge_lim;
+ bat->present = bi->present;
+ bat->charging = bi->charging;
+ bat->is_micro_watts = bi->is_micro_watts;
+ if (bi->charge >= 0.0)
+ {
+ double charge;
+ double charge_rate = 0;
+ double last_charge_rate;
+ double t, td;
+
+ charge = bi->charge;
+ last_charge_rate = bat->charge_rate;
+ if (bat->design_voltage > 0.0)
+ charge = charge * bat->design_voltage / 1000000.0;
+ t = ecore_time_get();
+ td = t - bat->last_update;
+ if (td <= 0.0) td = 0.001;
+ if ((bat->is_micro_watts) && (!eina_dbl_exact(bat->power_now, 0)))
+ {
+ if (!bat->charging) charge_rate = -bat->power_now / 3600.0;
+ else charge_rate = bat->power_now / 3600.0;
+ }
+ else if ((bat->got_prop) &&
+ (!eina_dbl_exact(charge, bat->current_charge)) &&
+ (!eina_dbl_exact(bat->current_charge, 0)))
+ charge_rate = ((charge - bat->current_charge) / td);
+ if ((!eina_dbl_exact(charge_rate, 0)) ||
+ eina_dbl_exact(bat->last_update, 0) ||
+ eina_dbl_exact(bat->current_charge, 0))
+ {
+ bat->last_update = t;
+ bat->current_charge = charge;
+ bat->charge_rate = charge_rate;
+ }
+ bat->percent = (10000.0 * bat->current_charge) / bat->last_full_charge;
+ if (bat->got_prop)
+ {
+ if ((!((bat->is_micro_watts) && (!eina_dbl_exact(bat->power_now, 0)))) &&
+ ((pcharging == bat->charging)))
+ charge_rate = (charge_rate + last_charge_rate) / 2.0;
+ if ((!bat->charging) && (!eina_dbl_exact(charge_rate, 0)))
+ {
+ if (battery_config->fuzzy && (battery_config->fuzzcount <= 10) && (bat->time_left > 0))
+ bat->time_left = (((0 - bat->current_charge) / charge_rate) + bat->time_left) / 2;
+ else
+ bat->time_left = (0 - bat->current_charge) / charge_rate;
+ bat->time_full = -1;
+ }
+ else if (!eina_dbl_exact(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) / charge_rate) + bat->time_full) / 2;
+ else
+ bat->time_full = (bat->last_full_charge - bat->current_charge) / charge_rate;
+ bat->time_left = -1;
+ }
+ if (pcharging == bat->charging)
+ bat->charge_rate = charge_rate;
+ }
+ else
+ {
+ bat->time_full = -1;
+ bat->time_left = -1;
+ }
+ }
+ if (battery_config->fuzzcount > 10) battery_config->fuzzcount = 0;
+ if (bat->got_prop) _battery_device_update();
+ bat->got_prop = EINA_TRUE;
+ }
+ }
+ else if (bi->is_ac)
+ {
+ Ac_Adapter *ac = _battery_ac_adapter_find(bi->udi);
+
+ if (ac)
+ {
+ ac->present = bi->present;
+ _battery_device_update();
+ }
+ }
+ eina_lock_release(&_poll_lock);
+ eina_stringshare_replace(&(bi->udi), NULL);
+ eina_stringshare_replace(&(bi->technology), NULL);
+ eina_stringshare_replace(&(bi->vendor), NULL);
+ eina_stringshare_replace(&(bi->model), NULL);
+ free(bi);
+}
+
+static void
+_cb_poll_thread_end(void *data EINA_UNUSED, Ecore_Thread *thread EINA_UNUSED)
+{ // in main loop
+ // when feedback thread exits and finishes inn main loop
+ ecore_pipe_del(_poll_pipe);
+ _poll_pipe = NULL;
+ _poll_thread = NULL;
+ eina_lock_free(&_poll_lock);
+}
+
int
_battery_udev_start(void)
-{
- Eina_List *devices;
- const char *dev;
+{ // in main loop
+ Eina_List *devices;
+ const char *dev;
- devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_BAT, NULL);
- EINA_LIST_FREE(devices, dev)
- _battery_udev_battery_add(dev);
+ devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_BAT, NULL);
+ EINA_LIST_FREE(devices, dev)
+ {
+ _battery_udev_battery_add(dev);
+ eina_stringshare_del(dev);
+ }
- devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_AC, NULL);
- EINA_LIST_FREE(devices, dev)
- _battery_udev_ac_add(dev);
+ devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_POWER_AC, NULL);
+ EINA_LIST_FREE(devices, dev)
+ {
+ _battery_udev_ac_add(dev);
+ eina_stringshare_del(dev);
+ }
- if (!battery_config->batwatch)
- battery_config->batwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_BAT, EEZE_UDEV_EVENT_NONE, _battery_udev_event_battery, NULL);
- if (!battery_config->acwatch)
- battery_config->acwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_AC, EEZE_UDEV_EVENT_NONE, _battery_udev_event_ac, NULL);
+ if (!battery_config->batwatch)
+ battery_config->batwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_BAT, EEZE_UDEV_EVENT_NONE, _battery_udev_event_battery, NULL);
+ if (!battery_config->acwatch)
+ battery_config->acwatch = eeze_udev_watch_add(EEZE_UDEV_TYPE_POWER_AC, EEZE_UDEV_EVENT_NONE, _battery_udev_event_ac, NULL);
- init_time = ecore_time_get();
- return 1;
+ init_time = ecore_time_get();
+ eina_lock_new(&_poll_lock);
+ _poll_pipe = ecore_pipe_add(_cb_poll_pipe, NULL);
+ ecore_pipe_freeze(_poll_pipe);
+ _poll_thread = ecore_thread_feedback_run
+ (_cb_poll_thread, _cb_poll_thread_reply, _cb_poll_thread_end,
+ NULL, NULL, EINA_TRUE);
+ _poll_wakeup();
+ return 1;
}
void
_battery_udev_stop(void)
-{
- Ac_Adapter *ac;
- Battery *bat;
+{ // in main loop
+ 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);
+ 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_timer_del(bat->timer);
- _battery_history_close(bat);
- free(bat);
- }
+ eina_lock_take(&_poll_lock);
+ 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);
+ _battery_history_close(bat);
+ free(bat);
+ }
+ _devices_timer_clean();
+ eina_lock_release(&_poll_lock);
+ if (_poll_thread) ecore_thread_cancel(_poll_thread);
+ _poll_wakeup();
}
static void
-_battery_udev_event_battery(const char *syspath, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch EINA_UNUSED)
-{
- if ((event & EEZE_UDEV_EVENT_ADD) ||
- (event & EEZE_UDEV_EVENT_ONLINE))
- _battery_udev_battery_add(syspath);
- else if ((event & EEZE_UDEV_EVENT_REMOVE) ||
- (event & EEZE_UDEV_EVENT_OFFLINE))
- _battery_udev_battery_del(syspath);
- else /* must be change */
- _battery_udev_battery_update(syspath, data);
+_battery_udev_event_battery(const char *syspath, Eeze_Udev_Event event, void *data EINA_UNUSED, Eeze_Udev_Watch *watch EINA_UNUSED)
+{ // in main loop
+ eina_lock_take(&_poll_lock);
+ if ((event & EEZE_UDEV_EVENT_ADD) ||
+ (event & EEZE_UDEV_EVENT_ONLINE))
+ _battery_udev_battery_add(syspath);
+ else if ((event & EEZE_UDEV_EVENT_REMOVE) ||
+ (event & EEZE_UDEV_EVENT_OFFLINE))
+ _battery_udev_battery_del(syspath);
+ else /* must be change */
+ _poll_wakeup();
+ eina_lock_release(&_poll_lock);
+ eina_stringshare_del(syspath); // yes - eeze wants us to do this
}
static void
-_battery_udev_event_ac(const char *syspath, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch EINA_UNUSED)
-{
- if ((event & EEZE_UDEV_EVENT_ADD) ||
- (event & EEZE_UDEV_EVENT_ONLINE))
- _battery_udev_ac_add(syspath);
- else if ((event & EEZE_UDEV_EVENT_REMOVE) ||
- (event & EEZE_UDEV_EVENT_OFFLINE))
- _battery_udev_ac_del(syspath);
- else /* must be change */
- _battery_udev_ac_update(syspath, data);
+_battery_udev_event_ac(const char *syspath, Eeze_Udev_Event event, void *data EINA_UNUSED, Eeze_Udev_Watch *watch EINA_UNUSED)
+{ // in main loop
+ eina_lock_take(&_poll_lock);
+ if ((event & EEZE_UDEV_EVENT_ADD) ||
+ (event & EEZE_UDEV_EVENT_ONLINE))
+ _battery_udev_ac_add(syspath);
+ else if ((event & EEZE_UDEV_EVENT_REMOVE) ||
+ (event & EEZE_UDEV_EVENT_OFFLINE))
+ _battery_udev_ac_del(syspath);
+ else /* must be change */
+ _poll_wakeup();
+ eina_lock_release(&_poll_lock);
+ eina_stringshare_del(syspath); // yes - eeze wants us to do this
}
static void
_battery_udev_battery_add(const char *syspath)
-{
- Battery *bat;
- const char *type, *test;
- double full_design = 0.0;
- double voltage_min_design = 0.0;
- double full = 0.0;
- Config_Battery *cb;
- Eina_List *l;
+{ // in main loop
+ Battery *bat;
+ const char *type, *test;
+ double full_design = 0.0;
+ double voltage_min_design = 0.0;
+ double full = 0.0;
+ Config_Battery *cb;
+ Eina_List *l;
- if ((bat = _battery_battery_find(syspath)))
- {
- eina_stringshare_del(syspath);
- _battery_udev_battery_update(NULL, bat);
- return;
- }
- type = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_TYPE");
- if (type)
- {
- if ((!strcmp(type, "USB")) || (!strcmp(type, "Mains")))
- {
- _battery_udev_ac_add(syspath);
- eina_stringshare_del(type);
- return;
- }
- if (!!strcmp(type, "Battery"))
- {
- eina_stringshare_del(type);
- return;
- }
- eina_stringshare_del(type);
- }
- // filter out dummy batteries with no design and no full charge level
- test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_ENERGY_FULL_DESIGN");
- if (!test)
- test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_CHARGE_FULL_DESIGN");
- if (test)
+ if ((bat = _battery_battery_find(syspath)))
+ {
+ _poll_wakeup();
+ return;
+ }
+ type = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_TYPE");
+ if (type)
+ {
+ if ((!strcmp(type, "USB")) || (!strcmp(type, "Mains")))
+ {
+ _battery_udev_ac_add(syspath);
+ eina_stringshare_del(type);
+ return;
+ }
+ if (!!strcmp(type, "Battery"))
+ {
+ eina_stringshare_del(type);
+ return;
+ }
+ eina_stringshare_del(type);
+ }
+ // filter out dummy batteries with no design and no full charge level
+ test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_ENERGY_FULL_DESIGN");
+ if (!test)
+ test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_CHARGE_FULL_DESIGN");
+ if (test)
{
full_design = strtod(test, NULL);
eina_stringshare_del(test);
}
- test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_ENERGY_FULL");
- if (!test)
+ test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_ENERGY_FULL");
+ if (!test)
{
test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_VOLTAGE_MIN_DESIGN");
if (test)
voltage_min_design = strtod(test, NULL);
test = eeze_udev_syspath_get_property(syspath, "POWER_SUPPLY_CHARGE_FULL");
}
- if (test)
+ if (test)
{
full = strtod(test, NULL);
eina_stringshare_del(test);
}
- if ((eina_dbl_exact(full_design, 0)) &&
- (eina_dbl_exact(full, 0)))
- { // ignore this battery - no full and no full design
- return;
- }
+ // ignore this battery - no full and no full design
+ if ((eina_dbl_exact(full_design, 0)) && (eina_dbl_exact(full, 0))) return;
- if (!(bat = E_NEW(Battery, 1)))
- {
- eina_stringshare_del(syspath);
- return;
- }
- bat->design_voltage = voltage_min_design;
- bat->last_update = ecore_time_get();
- bat->udi = eina_stringshare_add(syspath);
- bat->timer = ecore_timer_add(10.0, _battery_udev_battery_update_poll, bat);
+ if (!(bat = E_NEW(Battery, 1))) return;
+ bat->design_voltage = voltage_min_design;
+ bat->last_update = ecore_time_get();
+ bat->udi = eina_stringshare_add(syspath);
+ _devices_timer_ensure();
- test = eeze_udev_syspath_get_sysattr(syspath, "charge_control_end_threshold");
- if (!test) bat->charge_lim = -1;
- else
+ test = eeze_udev_syspath_get_sysattr(syspath, "charge_control_end_threshold");
+ if (!test) bat->charge_lim = -1;
+ else
{
bat->charge_lim = atoi(test);
// find a matching battery config entry and retore from there
@@ -183,275 +522,68 @@ _battery_udev_battery_add(const char *syspath)
}
}
}
-
- device_batteries = eina_list_append(device_batteries, bat);
- _battery_udev_battery_update(syspath, bat);
+ device_batteries = eina_list_append(device_batteries, bat);
+ _poll_wakeup();
}
static void
_battery_udev_ac_add(const char *syspath)
-{
- Ac_Adapter *ac;
+{ // in main loop
+ Ac_Adapter *ac;
- if ((ac = _battery_ac_adapter_find(syspath)))
- {
- eina_stringshare_del(syspath);
- _battery_udev_ac_update(NULL, ac);
- return;
- }
-
- 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);
+ if ((ac = _battery_ac_adapter_find(syspath)))
+ {
+ _poll_wakeup();
+ return;
+ }
+ if (!(ac = E_NEW(Ac_Adapter, 1))) return;
+ ac->udi = eina_stringshare_add(syspath);
+ _devices_timer_ensure();
+ device_ac_adapters = eina_list_append(device_ac_adapters, ac);
+ _poll_wakeup();
}
static void
_battery_udev_battery_del(const char *syspath)
-{
- Battery *bat;
+{ // in main loop
+ Battery *bat;
- if (!(bat = _battery_battery_find(syspath)))
- {
- eina_stringshare_del(syspath);
- _battery_device_update();
- return;
- }
-
- device_batteries = eina_list_remove(device_batteries, bat);
- eina_stringshare_del(bat->udi);
- eina_stringshare_del(bat->technology);
- eina_stringshare_del(bat->model);
- eina_stringshare_del(bat->vendor);
- ecore_timer_del(bat->timer);
- free(bat);
+ if (!(bat = _battery_battery_find(syspath)))
+ {
+ _poll_wakeup();
+ return;
+ }
+ device_batteries = eina_list_remove(device_batteries, bat);
+ eina_stringshare_del(bat->udi);
+ eina_stringshare_del(bat->technology);
+ eina_stringshare_del(bat->model);
+ eina_stringshare_del(bat->vendor);
+ free(bat);
+ _poll_wakeup();
+ _devices_timer_clean();
}
static void
_battery_udev_ac_del(const char *syspath)
-{
- Ac_Adapter *ac;
+{ // in main loop
+ Ac_Adapter *ac;
- if (!(ac = _battery_ac_adapter_find(syspath)))
- {
- eina_stringshare_del(syspath);
- _battery_device_update();
- return;
- }
-
- device_ac_adapters = eina_list_remove(device_ac_adapters, ac);
- eina_stringshare_del(ac->udi);
- free(ac);
+ if (!(ac = _battery_ac_adapter_find(syspath)))
+ {
+ _poll_wakeup();
+ return;
+ }
+ device_ac_adapters = eina_list_remove(device_ac_adapters, ac);
+ eina_stringshare_del(ac->udi);
+ free(ac);
+ _poll_wakeup();
+ _devices_timer_clean();
}
static Eina_Bool
-_battery_udev_battery_update_poll(void *data)
-{
- _battery_udev_battery_update(NULL, data);
-
- 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
-_battery_udev_battery_update(const char *syspath, Battery *bat)
-{
- int pcharging;
- const char *test;
- double t, charge, voltage_now;
-
- if (!bat)
- {
- if (!(bat = _battery_battery_find(syspath)))
- {
- _battery_udev_battery_add(syspath);
- return;
- }
- }
- 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 (eina_dbl_exact(bat->design_charge, 0))
- {
- GET_NUM(bat, design_charge, POWER_SUPPLY_CHARGE_FULL_DESIGN);
- if (bat->design_voltage > 0.0)
- {
- bat->design_charge = bat->design_charge * bat->design_voltage / 1000000.0;
- bat->is_micro_watts = EINA_TRUE;
- }
- }
- }
- bat->power_now = 0;
- voltage_now = bat->design_voltage;
- test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_VOLTAGE_NOW");
- if (test)
- {
- voltage_now = (double)strtod(test, NULL);
- eina_stringshare_del(test);
- }
- GET_NUM(bat, power_now, POWER_SUPPLY_POWER_NOW);
- if (eina_dbl_exact(bat->power_now, 0))
- {
- test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_CURRENT_NOW");
- if (test)
- {
- double current_now = strtod(test, NULL);
-
- eina_stringshare_del(test);
- if (voltage_now > 0.0)
- {
- bat->power_now = current_now * voltage_now / 1000000.0;
- }
- }
- }
- GET_NUM(bat, last_full_charge, POWER_SUPPLY_ENERGY_FULL);
- if (eina_dbl_exact(bat->last_full_charge, 0))
- {
- GET_NUM(bat, last_full_charge, POWER_SUPPLY_CHARGE_FULL);
- if (bat->design_voltage > 0.0)
- {
- bat->last_full_charge = bat->last_full_charge * bat->design_voltage / 1000000.0;
- bat->is_micro_watts = EINA_TRUE;
- }
- }
- else
- bat->is_micro_watts = EINA_TRUE;
- pcharging = bat->charging;
- 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;
-
- test = eeze_udev_syspath_get_sysattr(bat->udi, "charge_control_end_threshold");
- if (!test) bat->charge_lim = -1;
- else bat->charge_lim = atoi(test);
-
- 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)
- {
- if (eina_dbl_exact(bat->last_full_charge, 0))
- {
- bat->last_full_charge = 10000;
- bat->design_charge = 10000;
- }
- test = eeze_udev_syspath_get_property(bat->udi, "POWER_SUPPLY_CAPACITY");
- }
- if (test)
- {
- double charge_rate = 0;
- double last_charge_rate;
- double td;
-
- last_charge_rate = bat->charge_rate;
- charge = strtod(test, NULL);
- if (bat->design_voltage > 0.0)
- charge = charge * bat->design_voltage / 1000000.0;
- eina_stringshare_del(test);
- t = ecore_time_get();
- td = t - bat->last_update;
- if (td <= 0.0) td = 0.001;
- if ((bat->is_micro_watts) && (!eina_dbl_exact(bat->power_now, 0)))
- {
- if (!bat->charging) charge_rate = -bat->power_now / 3600.0;
- else charge_rate = bat->power_now / 3600.0;
- }
- else if ((bat->got_prop) &&
- (!eina_dbl_exact(charge, bat->current_charge)) &&
- (!eina_dbl_exact(bat->current_charge, 0)))
- charge_rate =
- ((charge - bat->current_charge) / td);
- if ((!eina_dbl_exact(charge_rate, 0)) ||
- eina_dbl_exact(bat->last_update, 0) ||
- eina_dbl_exact(bat->current_charge, 0))
- {
- bat->last_update = t;
- bat->current_charge = charge;
- bat->charge_rate = charge_rate;
- }
- bat->percent = (10000.0 * bat->current_charge) / bat->last_full_charge;
- if (bat->got_prop)
- {
- if ((!((bat->is_micro_watts) && (!eina_dbl_exact(bat->power_now, 0)))) &&
- ((pcharging == bat->charging)))
- charge_rate = (charge_rate + last_charge_rate) / 2.0;
- if ((!bat->charging) && (!eina_dbl_exact(charge_rate, 0)))
- {
- if (battery_config->fuzzy && (battery_config->fuzzcount <= 10) && (bat->time_left > 0)) bat->time_left = (((0 - bat->current_charge) / charge_rate) + bat->time_left) / 2;
- else
- bat->time_left = (0 - bat->current_charge) / charge_rate;
- bat->time_full = -1;
- }
- else if (!eina_dbl_exact(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) / charge_rate) + bat->time_full) / 2;
- else
- bat->time_full = (bat->last_full_charge - bat->current_charge) / charge_rate;
- bat->time_left = -1;
- }
- if (pcharging == bat->charging) bat->charge_rate = charge_rate;
- }
- else
- {
- bat->time_full = -1;
- bat->time_left = -1;
- }
- }
- if (battery_config->fuzzcount > 10) battery_config->fuzzcount = 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)))
- {
- _battery_udev_ac_add(syspath);
- return;
- }
- }
-
- GET_NUM(ac, present, POWER_SUPPLY_ONLINE);
- /* yes, it's really that simple. */
-
- _battery_device_update();
+_battery_udev_battery_update_poll(void *data EINA_UNUSED)
+{ // in main loop
+ _poll_wakeup();
+ return EINA_TRUE;
}
#endif
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.