@ -0,0 +1,21 @@ | |||
MIT/X Consortium License | |||
© 2011 Christoph Lohmann <20h@r-36.net> | |||
Permission is hereby granted, free of charge, to any person obtaining a | |||
copy of this software and associated documentation files (the "Software"), | |||
to deal in the Software without restriction, including without limitation | |||
the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
and/or sell copies of the Software, and to permit persons to whom the | |||
Software is furnished to do so, subject to the following conditions: | |||
The above copyright notice and this permission notice shall be included in | |||
all copies or substantial portions of the Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,49 @@ | |||
# See LICENSE file for copyright and license details. | |||
include config.mk | |||
SRC = ${NAME}.c | |||
OBJ = ${SRC:.c=.o} | |||
all: options ${NAME} | |||
options: | |||
@echo ${NAME} build options: | |||
@echo "CFLAGS = ${CFLAGS}" | |||
@echo "LDFLAGS = ${LDFLAGS}" | |||
@echo "CC = ${CC}" | |||
.c.o: | |||
@echo CC $< | |||
@${CC} -c ${CFLAGS} $< | |||
${OBJ}: config.mk | |||
${NAME}: ${OBJ} | |||
@echo CC -o $@ | |||
@${CC} -o $@ ${OBJ} ${LDFLAGS} | |||
clean: | |||
@echo cleaning | |||
@rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz | |||
dist: clean | |||
@echo creating dist tarball | |||
@mkdir -p ${NAME}-${VERSION} | |||
@cp -R Makefile LICENSE config.mk \ | |||
${SRC} ${NAME}-${VERSION} | |||
@tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION} | |||
@gzip ${NAME}-${VERSION}.tar | |||
@rm -rf ${NAME}-${VERSION} | |||
install: all | |||
@echo installing executable file to ${DESTDIR}${PREFIX}/bin | |||
@mkdir -p ${DESTDIR}${PREFIX}/bin | |||
@cp -f ${NAME} ${DESTDIR}${PREFIX}/bin | |||
@chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME} | |||
uninstall: | |||
@echo removing executable file from ${DESTDIR}${PREFIX}/bin | |||
@rm -f ${DESTDIR}${PREFIX}/bin/${NAME} | |||
.PHONY: all options clean dist install uninstall |
@ -0,0 +1,30 @@ | |||
NAME = dwmstatus | |||
VERSION = 1.0 | |||
# Customize below to fit your system | |||
# paths | |||
PREFIX = /usr | |||
MANPREFIX = ${PREFIX}/share/man | |||
X11INC = /usr/X11R6/include | |||
X11LIB = /usr/X11R6/lib | |||
# includes and libs | |||
INCS = -I. -I/usr/include -I${X11INC} | |||
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 | |||
# flags | |||
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE | |||
CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} | |||
#CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} | |||
LDFLAGS = -g ${LIBS} | |||
#LDFLAGS = -s ${LIBS} | |||
# Solaris | |||
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" | |||
#LDFLAGS = ${LIBS} | |||
# compiler and linker | |||
CC = cc | |||
@ -0,0 +1,15 @@ | |||
/* | |||
* gettemperature("/sys/class/hwmon/hwmon0/device", "temp1_input"); | |||
*/ | |||
char * | |||
gettemperature(char *base, char *sensor) | |||
{ | |||
char *co; | |||
co = readfile(base, sensor); | |||
if (co == NULL) | |||
return smprintf(""); | |||
return smprintf("%02.0f°C", atof(co) / 1000); | |||
} | |||
@ -0,0 +1,229 @@ | |||
/* | |||
* Copy me if you can. | |||
* by 20h | |||
*/ | |||
#define _BSD_SOURCE | |||
#include <unistd.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <stdarg.h> | |||
#include <string.h> | |||
#include <strings.h> | |||
#include <sys/time.h> | |||
#include <time.h> | |||
#include <sys/types.h> | |||
#include <sys/wait.h> | |||
#include <X11/Xlib.h> | |||
char *tzargentina = "America/Buenos_Aires"; | |||
char *tzutc = "UTC"; | |||
char *tzberlin = "Europe/Berlin"; | |||
static Display *dpy; | |||
char * | |||
smprintf(char *fmt, ...) | |||
{ | |||
va_list fmtargs; | |||
char *ret; | |||
int len; | |||
va_start(fmtargs, fmt); | |||
len = vsnprintf(NULL, 0, fmt, fmtargs); | |||
va_end(fmtargs); | |||
ret = malloc(++len); | |||
if (ret == NULL) { | |||
perror("malloc"); | |||
exit(1); | |||
} | |||
va_start(fmtargs, fmt); | |||
vsnprintf(ret, len, fmt, fmtargs); | |||
va_end(fmtargs); | |||
return ret; | |||
} | |||
void | |||
settz(char *tzname) | |||
{ | |||
setenv("TZ", tzname, 1); | |||
} | |||
char * | |||
mktimes(char *fmt, char *tzname) | |||
{ | |||
char buf[129]; | |||
time_t tim; | |||
struct tm *timtm; | |||
settz(tzname); | |||
tim = time(NULL); | |||
timtm = localtime(&tim); | |||
if (timtm == NULL) | |||
return smprintf(""); | |||
if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) { | |||
fprintf(stderr, "strftime == 0\n"); | |||
return smprintf(""); | |||
} | |||
return smprintf("%s", buf); | |||
} | |||
void | |||
setstatus(char *str) | |||
{ | |||
XStoreName(dpy, DefaultRootWindow(dpy), str); | |||
XSync(dpy, False); | |||
} | |||
char * | |||
loadavg(void) | |||
{ | |||
double avgs[3]; | |||
if (getloadavg(avgs, 3) < 0) | |||
return smprintf(""); | |||
return smprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); | |||
} | |||
char * | |||
readfile(char *base, char *file) | |||
{ | |||
char *path, line[513]; | |||
FILE *fd; | |||
memset(line, 0, sizeof(line)); | |||
path = smprintf("%s/%s", base, file); | |||
fd = fopen(path, "r"); | |||
free(path); | |||
if (fd == NULL) | |||
return NULL; | |||
if (fgets(line, sizeof(line)-1, fd) == NULL) | |||
return NULL; | |||
fclose(fd); | |||
return smprintf("%s", line); | |||
} | |||
char * | |||
getbattery(char *base) | |||
{ | |||
char *co, status; | |||
int descap, remcap; | |||
descap = -1; | |||
remcap = -1; | |||
co = readfile(base, "present"); | |||
if (co == NULL) | |||
return smprintf(""); | |||
if (co[0] != '1') { | |||
free(co); | |||
return smprintf("not present"); | |||
} | |||
free(co); | |||
co = readfile(base, "charge_full_design"); | |||
if (co == NULL) { | |||
co = readfile(base, "energy_full_design"); | |||
if (co == NULL) | |||
return smprintf(""); | |||
} | |||
sscanf(co, "%d", &descap); | |||
free(co); | |||
co = readfile(base, "charge_now"); | |||
if (co == NULL) { | |||
co = readfile(base, "energy_now"); | |||
if (co == NULL) | |||
return smprintf(""); | |||
} | |||
sscanf(co, "%d", &remcap); | |||
free(co); | |||
co = readfile(base, "status"); | |||
if (!strncmp(co, "Discharging", 11)) { | |||
status = '-'; | |||
} else if(!strncmp(co, "Charging", 8)) { | |||
status = '+'; | |||
} else { | |||
status = '?'; | |||
} | |||
if (remcap < 0 || descap < 0) | |||
return smprintf("invalid"); | |||
return smprintf("%.0f%%%c", ((float)remcap / (float)descap) * 100, status); | |||
} | |||
char * | |||
gettemperature(char *base, char *sensor) | |||
{ | |||
char *co; | |||
co = readfile(base, sensor); | |||
if (co == NULL) | |||
return smprintf(""); | |||
return smprintf("%02.0f°C", atof(co) / 1000); | |||
} | |||
int | |||
main(void) | |||
{ | |||
char *status; | |||
char *avgs; | |||
char *bat; | |||
char *bat1; | |||
char *tmar; | |||
char *tmutc; | |||
char *tmbln; | |||
char *t0, *t1, *t2, *t3; | |||
if (!(dpy = XOpenDisplay(NULL))) { | |||
fprintf(stderr, "dwmstatus: cannot open display.\n"); | |||
return 1; | |||
} | |||
for (;;sleep(60)) { | |||
avgs = loadavg(); | |||
bat = getbattery("/sys/class/power_supply/BAT0"); | |||
bat1 = getbattery("/sys/class/power_supply/BAT1"); | |||
tmar = mktimes("%H:%M", tzargentina); | |||
tmutc = mktimes("%H:%M", tzutc); | |||
tmbln = mktimes("KW %W %a %d %b %H:%M %Z %Y", tzberlin); | |||
t0 = gettemperature("/sys/devices/virtual/hwmon/hwmon1", "temp1_input"); | |||
t1 = gettemperature("/sys/devices/platform/coretemp.0/hwmon/hwmon3", "temp1_input"); | |||
t2 = gettemperature("/sys/devices/platform/coretemp.0/hwmon/hwmon3", "temp2_input"); | |||
t3 = gettemperature("/sys/devices/platform/coretemp.0/hwmon/hwmon3", "temp3_input"); | |||
status = smprintf("T:%s|%s|%s|%s L:%s B:%s|%s A:%s U:%s %s", | |||
t0, t1, t2, t3, avgs, bat, bat1, tmar, tmutc, | |||
tmbln); | |||
setstatus(status); | |||
free(t0); | |||
free(t1); | |||
free(t2); | |||
free(t3); | |||
free(avgs); | |||
free(bat); | |||
free(bat1); | |||
free(tmar); | |||
free(tmutc); | |||
free(tmbln); | |||
free(status); | |||
} | |||
XCloseDisplay(dpy); | |||
return 0; | |||
} | |||
@ -0,0 +1,55 @@ | |||
char * | |||
readfile(char *base, char *file) | |||
{ | |||
char *path, line[513]; | |||
FILE *fd; | |||
memset(line, 0, sizeof(line)); | |||
path = smprintf("%s/%s", base, file); | |||
fd = fopen(path, "r"); | |||
if (fd == NULL) { | |||
perror("fopen"); | |||
exit(1); | |||
} | |||
free(path); | |||
if (fgets(line, sizeof(line)-1, fd) == NULL) { | |||
perror("fgets"); | |||
exit(1); | |||
} | |||
fclose(fd); | |||
return smprintf("%s", line); | |||
} | |||
char * | |||
getbattery(char *base) | |||
{ | |||
char *co; | |||
int descap, remcap; | |||
descap = -1; | |||
remcap = -1; | |||
co = readfile(base, "present"); | |||
if (co[0] != '1') { | |||
free(co); | |||
return smprintf("not present"); | |||
} | |||
free(co); | |||
co = readfile(base, "charge_full_design"); | |||
sscanf(co, "%d", &descap); | |||
free(co); | |||
co = readfile(base, "charge_now"); | |||
sscanf(co, "%d", &remcap); | |||
free(co); | |||
if (remcap < 0 || descap < 0) | |||
return smprintf("invalid"); | |||
return smprintf("%.0f", ((float)remcap / (float)descap) * 100); | |||
} | |||