Source obtained from http://sourceforge.net/projects/wmacpi/files/.
2004 September 28 2.0rc1 Added support for switching to capacity mode automatically, on detecting dodgy reports from the battery. Added support for capacity mode on charging, with automatic enabling as per discharging. Various cleanups. Hopefully last release before the final 2.0. --- wmacpi/ChangeLog | 11 +++++ wmacpi/acpi.c | 2 +- wmacpi/libacpi.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++----- wmacpi/libacpi.h | 7 ++- wmacpi/wmacpi.c | 24 ++++++---- 5 files changed, 156 insertions(+), 22 deletions(-) diff --git a/wmacpi/ChangeLog b/wmacpi/ChangeLog index 1a079a1..b54f1e4 100644 --- a/wmacpi/ChangeLog +++ b/wmacpi/ChangeLog @@ -1,3 +1,14 @@ +2004 September 28 2.0rc1 + Added support for switching to capacity mode automatically, on + detecting dodgy reports from the battery. + + Added support for capacity mode on charging, with automatic + enabling as per discharging. + + Various cleanups. + + Hopefully last release before the final 2.0. + 2004 August 18 1.99r7 Implemented the libdockapp port - this seems to close Debian bug #227819, but it hasn't received sufficient testing. diff --git a/wmacpi/acpi.c b/wmacpi/acpi.c index c56b15e..fd3ddda 100644 --- a/wmacpi/acpi.c +++ b/wmacpi/acpi.c @@ -26,7 +26,7 @@ #include "libacpi.h" -#define ACPI_VER "1.99" +#define ACPI_VER "2.0" global_t *globals; diff --git a/wmacpi/libacpi.c b/wmacpi/libacpi.c index ac54326..28557a2 100644 --- a/wmacpi/libacpi.c +++ b/wmacpi/libacpi.c @@ -408,13 +408,48 @@ static int calc_remaining_percentage(int batt) return retval; } +/* check to see if we've been getting bad data from the batteries - if + * we get more than some limit we swith to using the remaining capacity + * for the calculations. */ +static enum rtime_mode check_rt_mode(global_t *globals) +{ + int i; + int bad_limit = 5; + battery_t *binfo; + + /* if we were told what to do, we should keep doing it */ + if(globals->rt_forced) + return globals->rt_mode; + + for(i = 0; i < MAXBATT; i++) { + binfo = &batteries[i]; + if(binfo->present && globals->adapter.power == BATT) { + if(binfo->present_rate <= 0) { + pdebug("Bad report from %s\n", binfo->name); + binfo->bad_count++; + } + } + } + for(i = 0; i < MAXBATT; i++) { + binfo = &batteries[i]; + if(binfo->bad_count > bad_limit) { + if(globals->rt_mode != RT_CAP) + pinfo("More than %d bad reports from %s; " + "Switching to remaining capacity mode\n", + bad_limit, binfo->name); + return RT_CAP; + } + } + return RT_RATE; +} + /* calculate remaining time until the battery is charged. * when charging, the battery state file reports the * current being used to charge the battery. We can use * this and the remaining capacity to work out how long * until it reaches the last full capacity of the battery. * XXX: make sure this is actually portable . . . */ -static int calc_charge_time(int batt) +static int calc_charge_time_rate(int batt) { float rcap, lfcap; battery_t *binfo; @@ -438,6 +473,78 @@ static int calc_charge_time(int batt) return charge_time; } +/* we need to calculate the present rate the same way we do in rt_cap + * mode, and then use that to estimate charge time. This will + * necessarily be even less accurate than it is for remaining time, but + * it's just as neessary . . . */ +#define CAP_SAMPLES (SAMPLES*10) +static int calc_charge_time_cap(int batt) +{ + static float cap_samples[CAP_SAMPLES]; + static int time_samples[CAP_SAMPLES]; + static int sample_count = 0; + static int current = 0; + static int old = 1; + int rtime; + int tdiff; + float cdiff; + float current_rate; + battery_t *binfo = &batteries[batt]; + + cap_samples[current] = (float) binfo->remaining_cap; + time_samples[current] = time(NULL); + + if (sample_count == 0) { + /* we can't do much if we don't have any data . . . */ + current_rate = 0; + } else if (sample_count < CAP_SAMPLES) { + /* if we have less than SAMPLES samples so far, we use the first + * sample and the current one */ + cdiff = cap_samples[current] - cap_samples[0]; + tdiff = time_samples[current] - time_samples[0]; + current_rate = cdiff/tdiff; + } else { + /* if we have more than SAMPLES samples, we use the oldest + * current one, which at this point is current + 1. This will + * wrap the same way that current will wrap, but one cycle + * ahead */ + cdiff = cap_samples[current] - cap_samples[old]; + tdiff = time_samples[current] - time_samples[old]; + current_rate = cdiff/(float)tdiff; + } + if (current_rate == 0) + rtime = 0; + else { + float cap_left = (float)(binfo->last_full_cap - binfo->remaining_cap); + rtime = (int)(cap_left/(current_rate * 60.0)); + } + sample_count++, current++, old++; + if (current >= CAP_SAMPLES) + current = 0; + if (old >= CAP_SAMPLES) + old = 0; + + pdebug("cap charge time rem: %d\n", rtime); + return rtime; +} + +static int calc_charge_time(global_t *globals, int batt) +{ + int ctime = 0; + + globals->rt_mode = check_rt_mode(globals); + + switch(globals->rt_mode) { + case RT_RATE: + ctime = calc_charge_time_rate(batt); + break; + case RT_CAP: + ctime = calc_charge_time_cap(batt); + break; + } + return ctime; +} + void acquire_batt_info(global_t *globals, int batt) { battery_t *binfo; @@ -485,7 +592,7 @@ void acquire_batt_info(global_t *globals, int batt) } } - binfo->charge_time = calc_charge_time(batt); + binfo->charge_time = calc_charge_time(globals, batt); /* and finally, we tell anyone who wants to use this information * that it's now valid . . .*/ @@ -582,7 +689,7 @@ int calc_time_remaining_rate(global_t *globals) if(rtime <= 0) rtime = 0; out: - pdebug("time rem: %d\n", rtime); + pdebug("discharge time rem: %d\n", rtime); return rtime; } @@ -604,8 +711,8 @@ int calc_time_remaining_rate(global_t *globals) */ int calc_time_remaining_cap(global_t *globals) { - static float cap_samples[SAMPLES]; - static int time_samples[SAMPLES]; + static float cap_samples[CAP_SAMPLES]; + static int time_samples[CAP_SAMPLES]; static int sample_count = 0; static int current = 0; static int old = 1; @@ -625,9 +732,12 @@ int calc_time_remaining_cap(global_t *globals) cap_samples[current] = cap; time_samples[current] = time(NULL); - /* if we have less than SAMPLES samples so far, we use the first - * sample and the current one */ - if (sample_count < SAMPLES) { + if (sample_count == 0) { + /* we can't do much if we don't have any data . . . */ + current_rate = 0; + } else if (sample_count < CAP_SAMPLES) { + /* if we have less than SAMPLES samples so far, we use the first + * sample and the current one */ cdiff = cap_samples[0] - cap_samples[current]; tdiff = time_samples[current] - time_samples[0]; current_rate = cdiff/tdiff; @@ -646,12 +756,12 @@ int calc_time_remaining_cap(global_t *globals) rtime = (int)(cap_samples[current]/(current_rate * 60.0)); sample_count++, current++, old++; - if (current >= SAMPLES) + if (current >= CAP_SAMPLES) current = 0; - if (old >= SAMPLES) + if (old >= CAP_SAMPLES) old = 0; - pdebug("time rem: %d\n", rtime); + pdebug("cap discharge time rem: %d\n", rtime); return rtime; } @@ -659,6 +769,8 @@ void acquire_global_info(global_t *globals) { adapter_t *ap = &globals->adapter; + globals->rt_mode = check_rt_mode(globals); + switch(globals->rt_mode) { case RT_RATE: globals->rtime = calc_time_remaining_rate(globals); diff --git a/wmacpi/libacpi.h b/wmacpi/libacpi.h index b28687a..e98dee3 100644 --- a/wmacpi/libacpi.h +++ b/wmacpi/libacpi.h @@ -2,7 +2,7 @@ #define _LIBACPI_H_ -#define LIBACPI_VER "0.91" +#define LIBACPI_VER "0.92" /* Here because we need it for definitions in this file . . . */ #define MAX_NAME 128 @@ -63,6 +63,8 @@ typedef struct { int charge_time; /* time left to charge this battery */ /* and a flag to indicate that this is valid . . . */ int valid; + /* number of times we've gotten bad info on this battery's present rate */ + int bad_count; } battery_t; typedef struct { @@ -82,7 +84,8 @@ typedef struct { int timer; /* how long been on battery? */ int crit_level; /* anything below this is critical low */ int battery_count; /* number of batteries found */ - enum rtime_mode rt_mode; + enum rtime_mode rt_mode; /* remaining time mode */ + int rt_forced; /* was our rt_mode forced? if so, we do what we were told */ battery_t *binfo; /* pointer to the battery being monitored */ adapter_t adapter; } global_t; diff --git a/wmacpi/wmacpi.c b/wmacpi/wmacpi.c index 3473541..07cd80d 100644 --- a/wmacpi/wmacpi.c +++ b/wmacpi/wmacpi.c @@ -37,7 +37,7 @@ #include "libacpi.h" #include "wmacpi.h" -#define WMACPI_VER "1.99r7" +#define WMACPI_VER "2.0rc1" /* main pixmap */ #ifdef LOW_COLOR @@ -541,11 +541,9 @@ static void set_message(global_t *globals) void set_time_display(global_t *globals) { - battery_t *binfo = &batteries[battery_no]; - - if (binfo->charge_state == CHARGE) - display_time(binfo->charge_time); - else if (binfo->charge_state == DISCHARGE) + if (globals->binfo->charge_state == CHARGE) + display_time(globals->binfo->charge_time); + else if (globals->binfo->charge_state == DISCHARGE) display_time(globals->rtime); else invalid_time_display(); @@ -596,7 +594,7 @@ void cli_wmacpi(global_t *globals, int samples) battery_t *binfo; adapter_t *ap; - printf("%d\n", samples); + pdebug("samples: %d\n", samples); if(samples > 1) sleep_time = 1000000/samples; @@ -653,6 +651,7 @@ int main(int argc, char **argv) int sleep_time = 1000000/sleep_rate; int scroll_count = 0; enum rtime_mode rt_mode = RT_RATE; + int rt_forced = 0; battery_t *binfo; global_t *globals; @@ -715,6 +714,7 @@ int main(int argc, char **argv) break; case 'f': rt_mode = RT_CAP; + rt_forced = 1; break; case 'h': usage(argv[0]); @@ -758,6 +758,7 @@ int main(int argc, char **argv) exit(1); globals->rt_mode = rt_mode; + globals->rt_forced = rt_forced; if (battery_no > globals->battery_count) { pfatal("Battery %d not available for monitoring.\n", battery_no); @@ -769,6 +770,13 @@ int main(int argc, char **argv) cli_wmacpi(globals, samples); exit(0); } + /* check to see if we've got a valid DISPLAY env variable, as a simple check to see if + * we're running under X */ + if (!getenv("DISPLAY")) { + pdebug("Not running under X - using cli mode\n"); + cli_wmacpi(globals, samples); + exit(0); + } battery_no--; @@ -812,7 +820,7 @@ int main(int argc, char **argv) battery_no = battery_no % globals->battery_count; globals->binfo = &batteries[battery_no]; binfo = globals->binfo; - pinfo("changing to monitor battery %d\n", battery_no + 1); + pinfo("changing to monitor battery %s\n", binfo->name); set_batt_id_area(battery_no); dockapp->update = 1; break; -- 1.9.1 -- To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.