diff --git a/AUTHORS b/AUTHORS index c4d04720..6e95560f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -160,6 +160,7 @@ tyir Vivenzio Pagliari Some useful patches for port monitoring + PowerBook battery patch Walt Nelson $freq fix diff --git a/ChangeLog b/ChangeLog index 6206a5c3..cc35c436 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ # $Id$ +2006-04-23 + * Added support for PowerBook batteries + 2006-04-15 * Added patch from Peter Tarjan to add support for IBM ACPI * Added xmms2 patch from Lassi Selander (sf.net patch 1469523) diff --git a/doc/docs.xml b/doc/docs.xml index 23c8daff..3cad6933 100644 --- a/doc/docs.xml +++ b/doc/docs.xml @@ -16,7 +16,7 @@ Brenden Matthews - 2006-04-15 + 2006-04-23 diff --git a/doc/variables.xml b/doc/variables.xml index 490d4eec..cabedcb2 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -873,6 +873,38 @@ + + + + + + + If running on Apple powerbook/ibook, display + information on battery status. The item parameter + specifies, what information to display. Exactly one item + must be specified. Valid items are: + + status: + Display if battery is fully charged, charging, + discharging or absent (running on AC) + + percent: + Display charge of battery in percent, if + charging or discharging. Nothing will be + displayed, if battery is fully charged + or absent. + + time: + Display the time remaining until the battery + will be fully charged or discharged at current + rate. Nothing is displayed, if battery is + absent or if it's present but fully charged + and not discharging. + + + + + diff --git a/src/conky.c b/src/conky.c index daa7d881..5ab03e74 100644 --- a/src/conky.c +++ b/src/conky.c @@ -808,6 +808,7 @@ enum text_object_type { OBJ_ibm_temps, OBJ_ibm_volume, OBJ_ibm_brightness, + OBJ_pb_battery, #endif /* __linux__ */ OBJ_if_existing, OBJ_if_mounted, @@ -1414,7 +1415,19 @@ static struct text_object *construct_text_object(const char *s, const char *arg, obj->data.sensor = atoi(&arg[0]); END OBJ(ibm_volume, 0) END OBJ(ibm_brightness, 0) - + END OBJ(pb_battery, 0) + if (arg && strcmp(arg, "status") == 0) { + obj->data.i = PB_BATT_STATUS; + } else if (arg && strcmp(arg, "percent") == 0) { + obj->data.i = PB_BATT_PERCENT; + } else if (arg && strcmp(arg, "time") == 0) { + obj->data.i = PB_BATT_TIME; + } else { + ERR("pb_battery: needs one argument: status, percent or time"); + free(obj); + return NULL; + } + #endif /* __linux__ */ END OBJ(buffers, INFO_BUFFERS) END OBJ(cached, INFO_BUFFERS) @@ -2548,6 +2561,9 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * OBJ(ibm_brightness) { get_ibm_acpi_brightness(p, p_max_size); } + OBJ(pb_battery) { + get_powerbook_batt_info(p, p_max_size, obj->data.i); + } #endif /* __linux__ */ #ifdef X11 diff --git a/src/conky.h b/src/conky.h index 9300c02c..90f72eba 100644 --- a/src/conky.h +++ b/src/conky.h @@ -463,6 +463,9 @@ struct ibm_acpi_struct { struct ibm_acpi_struct ibm_acpi; +enum { PB_BATT_STATUS, PB_BATT_PERCENT, PB_BATT_TIME}; +void get_powerbook_batt_info(char* buf, size_t size, int i); + struct process { struct process *next; struct process *previous; diff --git a/src/linux.c b/src/linux.c index 3c27da0d..7ab0372e 100644 --- a/src/linux.c +++ b/src/linux.c @@ -1239,6 +1239,112 @@ void get_battery_stuff(char *buf, unsigned int n, const char *bat) snprintf(buf, n, "%s", last_battery_str); } +/* On Apple powerbook and ibook: +$ cat /proc/pmu/battery_0 +flags : 00000013 +charge : 3623 +max_charge : 3720 +current : 388 +voltage : 16787 +time rem. : 900 +$ cat /proc/pmu/info +PMU driver version : 2 +PMU firmware version : 0c +AC Power : 1 +Battery count : 1 +*/ + +/* defines as in */ +#define PMU_BATT_PRESENT 0x00000001 +#define PMU_BATT_CHARGING 0x00000002 + +static FILE* pmu_battery_fp; +static FILE* pmu_info_fp; +static char pb_battery_info[3][32]; +static double pb_battery_info_update; + +#define PMU_PATH "/proc/pmu" +void get_powerbook_batt_info(char *buf, unsigned int n, int i) +{ + static int rep; + const char* batt_path = PMU_PATH "/battery_0"; + const char* info_path = PMU_PATH "/info"; + int flags, charge, max_charge, ac = -1; + long time = -1; + + /* don't update battery too often */ + if (current_update_time - pb_battery_info_update < 29.5) { + snprintf(buf, n, "%s", pb_battery_info[i]); + return; + } + pb_battery_info_update = current_update_time; + + if (pmu_battery_fp == NULL) + pmu_battery_fp = open_file(batt_path, &rep); + + if (pmu_battery_fp != NULL) { + rewind(pmu_battery_fp); + while (!feof(pmu_battery_fp)) { + char buf[32]; + if (fgets(buf, sizeof(buf), pmu_battery_fp) == NULL) + break; + + if (buf[0] == 'f') + sscanf(buf, "flags : %8x", &flags); + else if (buf[0] == 'c' && buf[1] == 'h') + sscanf(buf, "charge : %d", &charge); + else if (buf[0] == 'm') + sscanf(buf, "max_charge : %d", &max_charge); + else if (buf[0] == 't') + sscanf(buf, "time rem. : %ld", &time); + } + } + if (pmu_info_fp == NULL) + pmu_info_fp = open_file(info_path, &rep); + + if (pmu_info_fp != NULL) { + rewind(pmu_info_fp); + while (!feof(pmu_info_fp)) { + char buf[32]; + if (fgets(buf, sizeof(buf), pmu_info_fp) == NULL) + break; + if (buf[0] == 'A') + sscanf(buf, "AC Power : %d", &ac); + } + } + /* update status string */ + if ((ac && !(flags & PMU_BATT_PRESENT))) + strcpy(pb_battery_info[PB_BATT_STATUS], "AC"); + else if (ac && (flags & PMU_BATT_PRESENT) + && !(flags & PMU_BATT_CHARGING)) + strcpy(pb_battery_info[PB_BATT_STATUS], "charged"); + else if ((flags & PMU_BATT_PRESENT) + && (flags & PMU_BATT_CHARGING)) + strcpy(pb_battery_info[PB_BATT_STATUS], "charging"); + else + strcpy(pb_battery_info[PB_BATT_STATUS], "discharging"); + + /* update percentage string */ + if (time == 0) + pb_battery_info[PB_BATT_PERCENT][0] = 0; + else + snprintf(pb_battery_info[PB_BATT_PERCENT], + sizeof(pb_battery_info[PB_BATT_PERCENT]), + "%d%%", (charge * 100)/max_charge); + + /* update time string */ + if (time == 0) /* fully charged or battery not present */ + pb_battery_info[PB_BATT_TIME][0] = 0; + else if (time < 60*60) /* don't show secs */ + format_seconds_short(pb_battery_info[PB_BATT_TIME], + sizeof(pb_battery_info[PB_BATT_TIME]), time); + else + format_seconds(pb_battery_info[PB_BATT_TIME], + sizeof(pb_battery_info[PB_BATT_TIME]), time); + + snprintf(buf, n, "%s", pb_battery_info[i]); +} + void update_top() { show_nice_processes = 1;