diff options
author | Mike Blumenkrantz <michael.blumenkrantz@gmail.com> | 2010-05-18 10:39:30 +0000 |
---|---|---|
committer | Mike Blumenkrantz <michael.blumenkrantz@gmail.com> | 2010-05-18 10:39:30 +0000 |
commit | f7f417298ba44499852e1267adbfb6c38265bc9b (patch) | |
tree | 79d4ab37b46e537959756b4888cefb4b1310d43c /src/modules/battery/e_mod_udev.c | |
parent | 7c2df0efc675865d222e7cead5b1620d782a4f64 (diff) | |
download | enlightenment-f7f417298ba44499852e1267adbfb6c38265bc9b.tar.gz enlightenment-f7f417298ba44499852e1267adbfb6c38265bc9b.tar.xz enlightenment-f7f417298ba44499852e1267adbfb6c38265bc9b.zip |
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
Diffstat (limited to 'src/modules/battery/e_mod_udev.c')
-rw-r--r-- | src/modules/battery/e_mod_udev.c | 276 |
1 files changed, 226 insertions, 50 deletions
diff --git a/src/modules/battery/e_mod_udev.c b/src/modules/battery/e_mod_udev.c index 31bd68cb0..be0f3ab20 100644 --- a/src/modules/battery/e_mod_udev.c +++ b/src/modules/battery/e_mod_udev.c @@ -1,20 +1,69 @@ #include "e.h" #include "e_mod_main.h" -void -_battery_udev_start() +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); + +void +_battery_udev_start(void) { - 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); + 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); - 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); + 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(); +} |