Well, I'll just paste the code here to show you what I did to make things easier for me to figure out things. I am still trying to figure it all out.
Basically I haven't figured out the ones that don't have long names...
there are a few things I didn't translate into a longer name yet that I already know... but certain things like:
sz... I understand this is the size, but it is not immediately clear which size.
Just some minor things. I tried to name things here in the normal c naming convention...
Code: Select all
/*
* proc2imgd.c
*
* Copyright 2014 Brad Conroy - released to public domain
*
*/
#include <fcntl.h> //open
#include <unistd.h> //read,write
#include <string.h> //strstr, strlen
#include <stdlib.h> //getenv
#include <sys/stat.h> //mkdir
#include <sys/statfs.h> //for statfs
#include <stdint.h> //for *int*_t
#include <libgen.h> //basename
#define strcpyALL(buf, l, ...) do{ \
char *bp=(char*)(buf); \
const char *s, *a[] = { __VA_ARGS__,NULL}, **ss=a; \
while((s=*ss++)) \
while((*s)&&((--l) >0)) \
*bp++=*s++; \
*bp=0; \
}while(0)
static inline int ispad(int X){return (X)==' '||(unsigned)(X)-'\t'<5;}
#define isnum(X) ((unsigned)(X)-'0' < 10)
int stod(const char *s){ //like atoi but no negatives and only for small numbers
int r=0;
while (ispad(*s))s++;
while (isnum(*s)) r = 10*r + (*s++ - '0');
return r;
}
static void dtos(int64_t d, char *buf){ //like itoa, but you pass the buffer
int p=0;
if (0>d) {
buf[p++]='-';
d=-d;
}
if (0==d){
buf[p++]='0';
buf[p]=0;
return;
}
int64_t i=1000000000000000000;
while (i > d) i/=10;
while (0<i){
buf[p++]=('0'+(d/i));
if (i<=d) d=d%i;
i/=10;
}
buf[p]=0;
return;
}
//GLOBALs
static char //default colors TODO read from config file
*line_color="#000", //lines, outlines, strokes, etc...
*foreground_color="#AAA", //foreground items ... usually the actual image
*background_color="#444", //background color ... todo match with theme
*text_color="#FFF", //use a text color that will work with both the bg and fg
*charge_color="#0F0", //usually green indicates a preferred status
*discharge_color="#F00", //usually red denotes less preferred status
*icon_width="22px", //set for standard tray size
*icon_height="22px",
buf[4096]={0},
HOME[64];
static const char
svg_header[]="<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" \tviewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" ",
svg_footer[]="</svg>\n",
svg_width[]=" width=\"",
svg_height[]=" height=\"",
svg_x[]=" x=\"",
svg_y[]=" y=\"",
svg_quote[]="\" ",
svg_tag_end[]=">\n",
svg_tag_close[]="/>\n",
svg_rect[]="\t<rect ",
svg_fill[]=" fill=\"",
svg_text[]="\t<text ",
center[]=" text-anchor=\"middle\"",
rotate[]=" transform=\"rotate(90 50,50)\"",
svg_font_size[]=" font-size=\"",
svg_text_close[]="</text>\n";
#if 0
static inline void do_wifi(const char *wlan){
const char upload[]="M71,29L99,2L99,27L92,18,75,34",
download[] = "M98,0L70,27L70,5L77,12,90,0",
updown[] = "<path d=\"%s\" fill=\"%s\" stroke=\"%s\"/>\n",
sigqual[] = "<circle cx=\"0\" cy=\"100\" r=\"%d\" stroke=\"%s\" stroke-width=\"%d\" fill=\"%s\" fill-opacity=\"0.5\" />\n";
static int lastrcv=0, lastxmt=0;
int rcv,xmt,quality;
FILE *wireless = fopen("/proc/net/wireless", "r");
char dev[8], status[8], link[8], level[8], noise[8];
fgets(dummy, 99, wireless);
fgets(dummy, 99, wireless);
while (fscanf(fp, "%s %s %s %s %s %s\n", ip, hw, flags, mac, mask, dev) != EOF)
if (!strcmp(argv[1],ip))
printf("%s\n",dev);
return 0;
}
#endif
static inline void do_fs(char *fname, int *lastsz){
char extensions[]=" kMGTE", sz[8], *bp, outfile[64];
size_t ext=0, len=sizeof(outfile);
int fd;
if (!fname) return;
struct statfs st;
if ((statfs(fname, &st))<0) return;
uint64_t left = st.f_bfree * st.f_bsize;
while(left>1024){
left>>=10; //same as /=1024
++ext;
}
if ((int)left == *lastsz) return; //try not to trigger unnecessary redraw
else *lastsz=left;
dtos(left,sz);
bp=sz+strlen(sz);
if (ext) *bp++=extensions[ext];
*bp++='b';*bp++='\n';*bp++=0;
strcpyALL(outfile, len,HOME,(const char *)basename(fname),".svg");
if (( fd = open(outfile,O_WRONLY|O_CREAT|O_TRUNC,0644 ))<0) return;
len=sizeof(buf);
strcpyALL(buf, len,
svg_header,
svg_width,
icon_width,
svg_quote, svg_height,icon_height, svg_quote, svg_tag_end,
svg_rect, svg_width, "100%\"", svg_height, "100%\"",
svg_fill, background_color, svg_quote,
svg_tag_close,
svg_text, svg_x, "50\"", svg_y, "50\"",
svg_fill, text_color, svg_quote, svg_font_size, "30",
svg_quote, center, svg_tag_end, "\t\t",
sz, "\n",
svg_text_close,
svg_footer
);
write(fd,buf,strlen(buf));
close(fd);
return;
}
static inline void do_bat(char *batt, int *percent){
const char BAT[]="/proc/acpi/battery/";
char *bp=(char *)buf, fname[32], dy[24], ht[24];
int i, fd, len=sizeof(buf), chg=0, full_capacity=-1, discharging_capacity=-1, remaining_capacity=-1;
/* We _could_ just do this block once, but last full capacity may change */
i=sizeof(fname);
strcpyALL(fname, i, BAT, batt, "/info");
if (( fd = open(fname,O_RDONLY,0644 ))<0) return;
len = read(fd,buf,len);
close(fd);
if (len < 0) return;
buf[len]=0; //for strstr
if (!(bp = strstr(buf,"design capacity:"))) return;
else discharging_capacity = stod(&bp[25]);
if ((bp = strstr(buf,"last ful"))) full_capacity = stod(&bp[25]);
else full_capacity = discharging_capacity;
i=sizeof(fname);
strcpyALL(fname,i,BAT,batt,"/state");
if (( fd = open(fname,O_RDONLY,0644 ))<0) return;
i = read(fd,&(buf[len]),sizeof(buf)-len);
close(fd);
if (i < 0) return;
else buf[(len+=i)]=0;
if ((bp = strstr(buf,"remain")) && (i = stod(&bp[25])) == remaining_capacity) return;
else remaining_capacity = i;
if ((bp = strstr(buf,"charging st"))) chg=bp[25]-'c';
i=sizeof(fname);
i=(100*remaining_capacity)/((remaining_capacity>full_capacity)?discharging_capacity:full_capacity);
if (*percent==((chg)?-i:i)) return; //try not to trigger unnecessary redraw
else *percent = i;
strcpyALL(fname,i,HOME, batt, ".tt");
if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644 ))<0) return;
len=write(fd,buf,len);
close(fd);
i=sizeof(fname);
strcpyALL(fname,i,HOME, batt, ".svg");
if (( fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644))<0) return;
dtos(100-*percent,dy);
dtos(*percent,ht);
if (chg) *percent=-*percent;
len=sizeof(buf);
strcpyALL(buf, len,
svg_header, svg_width, icon_width, svg_quote,
svg_height, icon_height, svg_quote, svg_tag_end,
svg_rect, svg_x, "20%\"",
svg_width, "60%\"",
svg_height, "100%\"",
svg_fill, background_color, svg_quote, svg_tag_close,
svg_rect, svg_x, "20%\"",
svg_width, "60%\"",
svg_y, dy, svg_quote,
svg_height, ht, svg_quote,
svg_fill, (chg)?discharge_color:charge_color, svg_quote, svg_tag_close,
svg_text, svg_x, "50\"",
svg_y, "50\"",
svg_fill, text_color, svg_quote,
svg_font_size, "30", svg_quote,
center, rotate, svg_tag_end, "\t\t", batt, "\n",
svg_text_close,
svg_footer
);
write(fd,buf,sizeof(buf)-len);
}
int main(int argc, char **argv){
int len=sizeof(HOME),
state[argc/2];
strcpyALL(HOME,len,getenv("HOME"),"/.sit/");
mkdir(HOME,0422);
do{
do_fs("/mnt/save",&state[0]);
do_bat("BAT0",&state[1]);
//do_wifi("wlan0",&state[2]); //todo
}while(!sleep(1));
return 0;
}