X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fprint_battery_info.c;h=3e904844302a24bc75b0eb580c0a43159db68a7c;hb=0390dbf2e01470c0ec13f9e4f33cecabd2e3001e;hp=85b0a75a5d097d369d956162e80628bc5a3436ce;hpb=f8c11c31b2f8b98d8b879c446da0c7860e703beb;p=i3%2Fi3status diff --git a/src/print_battery_info.c b/src/print_battery_info.c index 85b0a75..3e90484 100644 --- a/src/print_battery_info.c +++ b/src/print_battery_info.c @@ -12,6 +12,7 @@ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) #include #include +#include #endif #if defined(__OpenBSD__) @@ -33,12 +34,10 @@ * worn off your battery is. * */ -void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, const char *status_chr, const char *status_bat, const char *status_full, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity, bool hide_seconds) { +void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, const char *status_chr, const char *status_bat, const char *status_unk, const char *status_full, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity, bool hide_seconds) { time_t empty_time; struct tm *empty_tm; char buf[1024]; - char statusbuf[16]; - char percentagebuf[16]; char remainingbuf[256]; char emptytimebuf[256]; char consumptionbuf[256]; @@ -50,10 +49,9 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char remaining = -1, present_rate = -1, voltage = -1; + float percentage_remaining = -1; charging_status_t status = CS_DISCHARGING; - memset(statusbuf, '\0', sizeof(statusbuf)); - memset(percentagebuf, '\0', sizeof(percentagebuf)); memset(remainingbuf, '\0', sizeof(remainingbuf)); memset(emptytimebuf, '\0', sizeof(emptytimebuf)); memset(consumptionbuf, '\0', sizeof(consumptionbuf)); @@ -62,9 +60,6 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char sprintf(batpath, path, number); INSTANCE(batpath); -#define BATT_STATUS_NAME(status) \ - (status == CS_CHARGING ? status_chr : (status == CS_DISCHARGING ? status_bat : status_full)) - #if defined(LINUX) if (!slurp(batpath, buf, sizeof(buf))) { OUTPUT_FULL_TEXT(format_down); @@ -100,6 +95,10 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char status = CS_CHARGING; else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Full")) status = CS_FULL; + else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Discharging")) + status = CS_DISCHARGING; + else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=")) + status = CS_UNKNOWN; else { /* The only thing left is the full capacity */ if (last_full_capacity) { @@ -134,16 +133,17 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char return; } - (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(status)); - - float percentage_remaining = (((float)remaining / (float)full_design) * 100); - if (integer_battery_capacity) { - (void)snprintf(percentagebuf, sizeof(percentagebuf), "%.00f%%", percentage_remaining); - } else { - (void)snprintf(percentagebuf, sizeof(percentagebuf), "%.02f%%", percentage_remaining); + percentage_remaining = (((float)remaining / (float)full_design) * 100); + /* Some batteries report POWER_SUPPLY_CHARGE_NOW= when fully + * charged, even though that’s plainly wrong. For people who chose to see + * the percentage calculated based on the last full capacity, we clamp the + * value to 100%, as that makes more sense. + * See http://bugs.debian.org/785398 */ + if (last_full_capacity && percentage_remaining > 100) { + percentage_remaining = 100; } - if (present_rate > 0) { + if (present_rate > 0 && status != CS_FULL) { float remaining_time; int seconds, hours, minutes, seconds_remaining; if (status == CS_CHARGING) @@ -213,7 +213,8 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char return; } - present_rate = sysctl_rslt; + integer_battery_capacity = true; + percentage_remaining = sysctl_rslt; if (sysctlbyname(BATT_TIME, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { OUTPUT_FULL_TEXT(format_down); return; @@ -226,28 +227,23 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char } state = sysctl_rslt; - if (state == 0 && present_rate == 100) + if (state == 0 && percentage_remaining == 100) status = CS_FULL; - else if (state == 0 && present_rate < 100) + else if ((state & ACPI_BATT_STAT_CHARGING) && percentage_remaining < 100) status = CS_CHARGING; else status = CS_DISCHARGING; full_design = sysctl_rslt; - (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(status)); - - (void)snprintf(percentagebuf, sizeof(percentagebuf), "%02d%%", - present_rate); - - if (state == 1) { + if (state == ACPI_BATT_STAT_DISCHARG) { int hours, minutes; minutes = remaining; hours = minutes / 60; minutes -= (hours * 60); (void)snprintf(remainingbuf, sizeof(remainingbuf), "%02d:%02d", max(hours, 0), max(minutes, 0)); - if (strcasecmp(threshold_type, "percentage") == 0 && present_rate < low_threshold) { + if (strcasecmp(threshold_type, "percentage") == 0 && percentage_remaining < low_threshold) { START_COLOR("color_bad"); colorful_output = true; } else if (strcasecmp(threshold_type, "time") == 0 && remaining < (u_int)low_threshold) { @@ -294,9 +290,8 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char break; } - (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(status)); - /* integer_battery_capacity is implied as battery_life is already in whole numbers. */ - (void)snprintf(percentagebuf, sizeof(percentagebuf), "%.00d%%", apm_info.battery_life); + integer_battery_capacity = true; + percentage_remaining = apm_info.battery_life; if (status == CS_DISCHARGING && low_threshold > 0) { if (strcasecmp(threshold_type, "percentage") == 0 && apm_info.battery_life < low_threshold) { @@ -480,20 +475,9 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char full_design = (((float)voltage / 1000.0) * ((float)full_design / 1000.0)); } - float percentage_remaining = + percentage_remaining = (((float)remaining / (float)full_design) * 100); - if (integer_battery_capacity) - (void)snprintf(percentagebuf, - sizeof(percentagebuf), - "%d%%", - (int)percentage_remaining); - else - (void)snprintf(percentagebuf, - sizeof(percentagebuf), - "%.02f%%", - percentage_remaining); - /* * Handle percentage low_threshold here, and time low_threshold when * we have it. @@ -506,9 +490,7 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char } if (is_full) - (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(CS_FULL)); - else - (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(status)); + status = CS_FULL; /* * The envsys(4) ACPI routines do not appear to provide a 'time @@ -589,10 +571,29 @@ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char } if (BEGINS_WITH(walk + 1, "status")) { - outwalk += sprintf(outwalk, "%s", statusbuf); + const char *statusstr; + switch (status) { + case CS_CHARGING: + statusstr = status_chr; + break; + case CS_DISCHARGING: + statusstr = status_bat; + break; + case CS_FULL: + statusstr = status_full; + break; + default: + statusstr = status_unk; + } + + outwalk += sprintf(outwalk, "%s", statusstr); walk += strlen("status"); } else if (BEGINS_WITH(walk + 1, "percentage")) { - outwalk += sprintf(outwalk, "%s", percentagebuf); + if (integer_battery_capacity) { + outwalk += sprintf(outwalk, "%.00f%s", percentage_remaining, pct_mark); + } else { + outwalk += sprintf(outwalk, "%.02f%s", percentage_remaining, pct_mark); + } walk += strlen("percentage"); } else if (BEGINS_WITH(walk + 1, "remaining")) { outwalk += sprintf(outwalk, "%s", remainingbuf);