This is based on the patch by Cristoph Fritz submitted to Debian. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=543674 --- wmbattery/wmbattery.1x | 10 +++++++ wmbattery/wmbattery.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++- wmbattery/wmbattery.h | 5 ++++ 3 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/wmbattery/wmbattery.1x b/wmbattery/wmbattery.1x index 75a66fc..78644d7 100644 --- a/wmbattery/wmbattery.1x +++ b/wmbattery/wmbattery.1x @@ -104,7 +104,17 @@ estimating time. (Implies \-e) Play the specified au file (by sending it to /dev/audio) when the battery is low. .TP +.B \-x command +Execute the specified command when the battery is below critical. The +strings \fI%percent%\fR, \fI%minutes%\fR and \fI%seconds%\fR will be +translated into the appropriate values. +.TP .B \-i Display as icon. +.SH EXAMPLE +Start at 10% battery to execute 'echo' including status information: +.RS +wmbattery -c 10 -x "echo Status: %percent%% - %minutes% minutes, %seconds% seconds left" +.RE .SH AUTHOR Joey Hess <j...@kitenet.net> diff --git a/wmbattery/wmbattery.c b/wmbattery/wmbattery.c index cecb90e..82ba4fe 100644 --- a/wmbattery/wmbattery.c +++ b/wmbattery/wmbattery.c @@ -39,6 +39,7 @@ int pos[2] = {0, 0}; char *crit_audio_fn = NULL; char *crit_audio; int crit_audio_size; +char *crit_command = NULL; int battnum = 1; #ifdef HAL @@ -207,6 +208,78 @@ void load_audio() { close(fd); } +/* string replacement function by Laird Shaw, in public domain + * http://creativeandcritical.net/str-replace-c */ +char *replace_str(const char *str, const char *old, const char *new) +{ + char *ret, *r; + const char *p, *q; + size_t oldlen = strlen(old); + size_t count, retlen, newlen = strlen(new); + + if (oldlen != newlen) { + for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen) + count++; + /* this is undefined if p - str > PTRDIFF_MAX */ + retlen = p - str + strlen(p) + count * (newlen - oldlen); + } else + retlen = strlen(str); + + if ((ret = malloc(retlen + 1)) == NULL) + return NULL; + + for (r = ret, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen) { + /* this is undefined if q - p > PTRDIFF_MAX */ + ptrdiff_t l = q - p; + memcpy(r, p, l); + r += l; + memcpy(r, new, newlen); + r += newlen; + } + strcpy(r, p); + + return ret; +} + +void cmd_crit(const char *cmd, int percentage, int time) { + char prc_str[255] = ""; + char min_str[255] = ""; + char sec_str[255] = ""; + char *tmp_a = NULL; + char *tmp_b = NULL; + char *command = NULL; + int ret; + + if (!cmd) + return; + if (percentage > 100 || percentage < 0) + return; + if (time > 65535 || time < 0) + return; + + sprintf(prc_str, "%i", percentage); + sprintf(min_str, "%i", time / 60); + sprintf(sec_str, "%i", time % 60); + + tmp_a = replace_str(cmd, STR_SUB_PERCENT, prc_str); + if (!tmp_a) + return; + tmp_b = replace_str(tmp_a, STR_SUB_MINUTES, min_str); + if (!tmp_b) + return; + command = replace_str(tmp_b, STR_SUB_SECONDS, sec_str); + if (!command) + return; + + ret = system(command); + if (ret == -1) + error("unable to run command: %s", command); + + free(tmp_a); + free(tmp_b); + free(command); +} + /* Returns the display to run on (or NULL for default). */ char *parse_commandline(int argc, char *argv[]) { int c=0; @@ -215,7 +288,7 @@ char *parse_commandline(int argc, char *argv[]) { extern char *optarg; while (c != -1) { - c=getopt(argc, argv, "hd:g:if:b:w:c:l:es:a:"); + c=getopt(argc, argv, "hd:g:if:b:w:c:l:es:a:x:"); switch (c) { case 'h': printf("Usage: wmbattery [options]\n"); @@ -230,6 +303,7 @@ char *parse_commandline(int argc, char *argv[]) { printf("\t-e\t\tuse own time estimates\n"); printf("\t-s granularity\tignore fluctuations less than granularity%% (implies -e)\n"); printf("\t-a file\t\twhen critical send file to /dev/audio\n"); + printf("\t-x command\twhen critical execute this command\n"); exit(0); break; case 'd': @@ -272,6 +346,9 @@ char *parse_commandline(int argc, char *argv[]) { case 'a': crit_audio_fn = strdup(optarg); break; + case 'x': + crit_command = strdup(optarg); + break; } } @@ -585,6 +662,8 @@ void alarmhandler(int sig) { } else if (cur_info.battery_status == BATTERY_STATUS_CRITICAL) { snd_crit(); + cmd_crit(crit_command, cur_info.battery_percentage, + cur_info.battery_time); } alarm(delay); diff --git a/wmbattery/wmbattery.h b/wmbattery/wmbattery.h index 4936957..1453462 100644 --- a/wmbattery/wmbattery.h +++ b/wmbattery/wmbattery.h @@ -68,3 +68,8 @@ static struct image_info_type image_info[] = { #define COLON_OFFSET 30 #define MINUTES_TENS_OFFSET 34 #define MINUTES_ONES_OFFSET 41 + +/* Replacement strings used by -x option */ +#define STR_SUB_PERCENT "%percent%" +#define STR_SUB_MINUTES "%minutes%" +#define STR_SUB_SECONDS "%seconds%" -- 1.9.1 -- To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.