wmbattery: Add -x option to run a command when battery is critical.

This is based on the patch by Cristoph Fritz submitted to Debian.  See
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=543674
This commit is contained in:
Doug Torrance 2014-10-05 10:30:01 -05:00 committed by Carlos R. Mafra
parent 77dabcc884
commit 8e5aa5c7e4
3 changed files with 95 additions and 1 deletions

View file

@ -104,7 +104,17 @@ estimating time. (Implies \-e)
Play the specified au file (by sending it to /dev/audio) when the battery Play the specified au file (by sending it to /dev/audio) when the battery
is low. is low.
.TP .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 .B \-i
Display as icon. 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 .SH AUTHOR
Joey Hess <joey@kitenet.net> Joey Hess <joey@kitenet.net>

View file

@ -39,6 +39,7 @@ int pos[2] = {0, 0};
char *crit_audio_fn = NULL; char *crit_audio_fn = NULL;
char *crit_audio; char *crit_audio;
int crit_audio_size; int crit_audio_size;
char *crit_command = NULL;
int battnum = 1; int battnum = 1;
#ifdef HAL #ifdef HAL
@ -207,6 +208,78 @@ void load_audio() {
close(fd); 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). */ /* Returns the display to run on (or NULL for default). */
char *parse_commandline(int argc, char *argv[]) { char *parse_commandline(int argc, char *argv[]) {
int c=0; int c=0;
@ -215,7 +288,7 @@ char *parse_commandline(int argc, char *argv[]) {
extern char *optarg; extern char *optarg;
while (c != -1) { 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) { switch (c) {
case 'h': case 'h':
printf("Usage: wmbattery [options]\n"); 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-e\t\tuse own time estimates\n");
printf("\t-s granularity\tignore fluctuations less than granularity%% (implies -e)\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-a file\t\twhen critical send file to /dev/audio\n");
printf("\t-x command\twhen critical execute this command\n");
exit(0); exit(0);
break; break;
case 'd': case 'd':
@ -272,6 +346,9 @@ char *parse_commandline(int argc, char *argv[]) {
case 'a': case 'a':
crit_audio_fn = strdup(optarg); crit_audio_fn = strdup(optarg);
break; 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) { else if (cur_info.battery_status == BATTERY_STATUS_CRITICAL) {
snd_crit(); snd_crit();
cmd_crit(crit_command, cur_info.battery_percentage,
cur_info.battery_time);
} }
alarm(delay); alarm(delay);

View file

@ -68,3 +68,8 @@ static struct image_info_type image_info[] = {
#define COLON_OFFSET 30 #define COLON_OFFSET 30
#define MINUTES_TENS_OFFSET 34 #define MINUTES_TENS_OFFSET 34
#define MINUTES_ONES_OFFSET 41 #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%"