diff options
Diffstat (limited to '')
-rw-r--r-- | lcd4linux.c | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/lcd4linux.c b/lcd4linux.c new file mode 100644 index 0000000..9dbe92f --- /dev/null +++ b/lcd4linux.c @@ -0,0 +1,499 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> +#include <math.h> + +#include "config.h" +#include "lcd2041.h" +#include "system.h" +#include "isdn.h" + +int tick, tack, tau; +double overload; +double temp_min, temp_max; +char *sensor; +char *row[ROWS]; + +void usage(void) +{ + printf ("LCD4Linux " VERSION " (c) 1999 Michael Reinelt <reinelt@eunet.at>"); + printf ("usage: LCD4Linux [configuration]\n"); +} + +char *parse (char *string) +{ + static char buffer[256]; + char *s=string; + char *p=buffer; + + do { + if (*s=='%') { + if (strchr("orpmlLbtdDnNiI%", *++s)==NULL) { + fprintf (stderr, "WARNING: unknown format <%%%c> in <%s>\n", *s, string); + continue; + } + *p='%'; + *(p+1)=*s; + switch (*s) { + case 'd': + if (strchr("rwmt", *++s)==NULL) { + fprintf (stderr, "WARNING: unknown disk tag <%%i%c> in <%s>\n", *s, string); + continue; + } + *(p+2)=*s; + p+=3; + break; + case 'n': + if (strchr("rwmt", *++s)==NULL) { + fprintf (stderr, "WARNING: unknown net tag <%%i%c> in <%s>\n", *s, string); + continue; + } + *(p+2)=*s; + p+=3; + break; + case 'i': + if (strchr("iomt", *++s)==NULL) { + fprintf (stderr, "WARNING: unknown ISDN tag <%%i%c> in <%s>\n", *s, string); + continue; + } + *(p+2)=*s; + p+=3; + break; + default: + p+=2; + } + + } else if (*s=='$') { + char hv, dir; + int len=0; + hv=*++s; + if (tolower(hv)!='h' && tolower(hv)!='v') { + fprintf (stderr, "invalid bar orientation '%c' in <%s>\n", hv, string); + continue; + } + s++; + if (isdigit(*s)) len=strtol(s, &s, 10); + if (len<1 || len>255) { + fprintf (stderr, "invalid bar length in <%s>\n", string); + continue; + } + dir=*s++; + if ((tolower(hv)=='h' && dir!='l' && dir !='r') || (tolower(hv)=='v' && dir!='u' && dir !='d')) { + fprintf (stderr, "invalid bar direction '%c' in <%s>\n", dir, string); + continue; + } + *p='$'; + *(p+1)=hv; + *(p+2)=len; + if (dir=='r' || dir=='u') *(p+3)='0'; + else *(p+3)='1'; + *(p+4)=*s; + switch (*s) { + case 'd': + if (strchr("rwmt", *++s)==NULL) { + fprintf (stderr, "WARNING: unknown disk tag <$i*%c> in <%s>\n", *s, string); + continue; + } + *(p+5)=*s; + p+=6; + break; + case 'n': + if (strchr("rwmt", *++s)==NULL) { + fprintf (stderr, "WARNING: unknown net tag <$i*%c> in <%s>\n", *s, string); + continue; + } + *(p+5)=*s; + p+=6; + break; + case 'i': + if (strchr("iomt", *++s)==NULL) { + fprintf (stderr, "WARNING: unknown ISDN tag <$i*%c> in <%s>\n", *s, string); + continue; + } + *(p+5)=*s; + p+=6; + break; + default: + p+=5; + } + + } else if (*s=='\\') { + unsigned int c=0; int n; + if (*(s+1)=='\\') { + *p++='\\'; + s+=2; + } else { + sscanf (s+1, "%3o%n", &c, &n); + if (c==0 || c>255) { + fprintf (stderr, "WARNING: illegal '\\' in <%s> <%s>\n", string, s); + continue; + } + *p++=c; + s+=n; + } + + } else { + *p++=*s; + } + + } while (*s++); + + return buffer; +} + + +void display (int smooth) { + static double disk_max=1.0; + static double net_max=1.0; + double busy, load, temp, disk, net, isdn; + int disk_r, disk_w; + int net_tx, net_rx; + int isdn_usage, isdn_in, isdn_out; + char buffer[256]; + int i; + + busy=Busy(); + load=Load(); + Disk (&disk_r, &disk_w); + Net (&net_rx, &net_tx); + temp=Temperature(); + isdn_usage=Isdn(&isdn_in, &isdn_out); + + if (disk_r>disk_max) disk_max=disk_r; + if (disk_w>disk_max) disk_max=disk_w; + + if (net_rx>net_max) net_max=net_rx; + if (net_tx>net_max) net_max=net_tx; + + for (i=0; i<ROWS; i++) { + char *s=row[i]; + char *p=buffer; + do { + if (*s=='%') { + switch (*++s) { + case '%': + *p++='%'; + break; + case 'o': + p+=sprintf (p, "%s", System()); + break; + case 'r': + p+=sprintf (p, "%s", Release()); + break; + case 'p': + p+=sprintf (p, "%s", Processor()); + break; + case 'm': + p+=sprintf (p, "%d", Memory()); + break; + case 'l': + if (load<10.0) + p+=sprintf (p, "%4.2f", load); + else + p+=sprintf (p, "%4.1f", load); + break; + case 'L': + *p++=load>overload?'!':' '; + break; + case 'b': + p+=sprintf (p, "%3.0f", 100.0*busy); + break; + case 'd': + switch (*++s) { + case 'r': + disk=disk_r; + break; + case 'w': + disk=disk_w; + break; + case 'm': + disk=disk_r>disk_w?disk_r:disk_w; + break; + default: + disk=disk_r+disk_w; + break; + } + disk/=1024; + if (disk<10.0) { + p+=sprintf (p, "%4.2f", disk); + } else if (disk<100.0) { + p+=sprintf (p, "%4.1f", disk); + } else { + p+=sprintf (p, "%4.0f", disk); + } + break; + case 'D': + if (disk_r+disk_w==0) + *p++=' '; + else + *p++=disk_r>disk_w?'\176':'\177'; + break; + case 'n': + switch (*++s) { + case 'r': + net=net_rx; + break; + case 'w': + net=net_tx; + break; + case 'm': + net=net_rx>net_tx?net_rx:net_tx; + break; + default: + net=net_rx+net_tx; + break; + } + net/=1024.0; + if (net<10.0) { + p+=sprintf (p, "%4.2f", net); + } else if (net<100.0) { + p+=sprintf (p, "%4.1f", net); + } else { + p+=sprintf (p, "%4.0f", net); + } + break; + case 'N': + if (net_rx+net_tx==0) + *p++=' '; + else + *p++=net_rx>net_tx?'\176':'\177'; + break; + case 't': + p+=sprintf (p, "%5.1f", temp); + break; + case 'i': + if (isdn_usage) { + switch (*++s) { + case 'i': + isdn=isdn_in; + break; + case 'o': + isdn=isdn_out; + break; + case 'm': + isdn=isdn_in>isdn_out?isdn_in:isdn_out; + break; + default: + isdn=isdn_in+isdn_out; + break; + } + isdn/=1024.0; + if (isdn<10.0) { + p+=sprintf (p, "%4.2f", isdn); + } else if (isdn<100.0) { + p+=sprintf (p, "%4.1f", isdn); + } else { + p+=sprintf (p, "%4.0f", isdn); + } + } else { + p+=sprintf (p, "----"); + s++; + } + break; + case 'I': + if (isdn_in+isdn_out==0) + *p++=' '; + else + *p++=isdn_in>isdn_out?'\176':'\177'; + break; + } + + } else if (*s=='$') { + double val; + int hv, len, dir; + hv=*++s; + len=*++s; + dir=*++s; + switch (*++s) { + case 'l': + val=load/overload; + break; + case 'b': + val=busy; + break; + case 'd': + switch (*++s) { + case 'r': + val=disk_r/disk_max; + break; + case 'w': + val=disk_w/disk_max; + break; + case 'm': + val=(disk_r>disk_w?disk_r:disk_w)/disk_max; + break; + default: + val=(disk_r+disk_w)/(2*disk_max); + break; + } + break; + case 'n': + switch (*++s) { + case 'r': + val=net_rx/net_max; + break; + case 'w': + val=net_tx/net_max; + break; + case 'm': + val=(net_rx>net_tx?net_rx:net_tx)/net_max; + break; + default: + val=(net_rx+net_tx)/(2*net_max); + break; + } + break; + case 't': + val=(temp-temp_min)/(temp_max-temp_min); + break; + case 'i': + switch (*++s) { + case 'i': + val=isdn_in; + break; + case 'o': + val=isdn_out; + break; + case 'm': + val=isdn_in>isdn_out?isdn_in:isdn_out; + break; + default: + val=isdn_in+isdn_out; + break; + } + val/=8000.0; + break; + default: + val=0.0; + } + switch (hv) { + case 'h': + lcd_hbar (p-buffer+1, i+1, dir-'0', len*XRES, val*len*XRES); + break; + case 'H': + lcd_hbar (p-buffer+1, i+1, dir-'0', len*XRES, (double)len*XRES*log(val*len*XRES+1)/log(len*XRES)); + break; + case 'v': + lcd_vbar (p-buffer+1, i+1, dir-'0', len*YRES, val*len*XRES); + break; + } + while (len-->0) { + *p++='\t'; + } + + } else { + *p++=*s; + } + } while (*s++); + + if (smooth==0) { + p=buffer; + while (*p) { + while (*p=='\t') p++; + for (s=p; *s; s++) { + if (*s=='\t') { + *s++='\0'; + break; + } + } + if (*p) { + lcd_put (p-buffer+1, i+1, p); + } + p=s; + } + } + } +} + + +void main (int argc, char *argv[]) +{ + char *cfg_file="/etc/lcd4linux.conf"; + char *port; + int i; + int contrast; + int smooth; + + if (argc>2) { + usage(); + exit (2); + } + if (argc==2) { + cfg_file=argv[1]; + } + + set_cfg ("row1", "*** %o %r ***"); + set_cfg ("row2", "%p CPU %m MB RAM"); + set_cfg ("row3", "Busy %b%% $r50b"); + set_cfg ("row4", "Load %l$r50l"); + + set_cfg ("tick", "100"); + set_cfg ("tack", "500"); + set_cfg ("tau", "500"); + set_cfg ("contrast", "140"); + set_cfg ("overload", "2.0"); + set_cfg ("temp_min", "20"); + set_cfg ("temp_max", "70"); + + set_cfg ("fifo", "/var/run/LCD4Linux"); + + if (read_cfg (cfg_file)==-1) + exit (1); + + port=get_cfg("port"); + sensor=get_cfg("temperature"); + tick=atoi(get_cfg("tick")); + tack=atoi(get_cfg("tack")); + tau=atoi(get_cfg("tau")); + contrast=atoi(get_cfg("contrast")); + overload=atof(get_cfg("overload")); + temp_min=atof(get_cfg("temp_min")); + temp_max=atof(get_cfg("temp_max")); + + if (port==NULL || *port=='\0') { + fprintf (stderr, "%s: missing 'port' entry!\n", cfg_file); + exit (1); + } + + for (i=0; i<ROWS; i++) { + char buffer[8]; + snprintf (buffer, sizeof(buffer), "row%d", i+1); + row[i]=strdup(parse(get_cfg(buffer))); + } + + lcd_init(port); + lcd_clear(); + lcd_contrast (contrast); + + lcd_put (1, 1, "** LCD4Linux " VERSION " **"); + lcd_put (1, 3, "(c) 1999 M. Reinelt"); + + + { + int a, b, c, d; + + lcd_dbar_init(); + for (a=0; a<40; a++) { + b=40-a; + c=2*a; + d=c+a; + lcd_dbar (2, 1, 0, 80, a, b); + lcd_dbar (2, 2, 0, 80, c, d); + lcd_dbar_flush(); + usleep( 300*1000); + } + } + + sleep (2); + lcd_clear(); + + smooth=0; + while (1) { + display(smooth); + smooth+=tick; + if (smooth>tack) smooth=0; + usleep(1000*tick); + } +} |