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.

Reply via email to