299 lines
5.3 KiB
C
299 lines
5.3 KiB
C
/*
|
|
* 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 *tzwarsaw = "Europe/Warsaw";
|
|
char *tzlocal = "Australia/Sydney";
|
|
|
|
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, 1) < 0)
|
|
return smprintf("");
|
|
|
|
return smprintf("📈 %.2f ", avgs[0]);
|
|
}
|
|
|
|
char *
|
|
readfile(char *base, char *file)
|
|
{
|
|
char *path, line[513];
|
|
FILE *fd;
|
|
|
|
memset(line, 0, sizeof(line));
|
|
|
|
if (file != NULL)
|
|
path = smprintf("%s/%s", base, file);
|
|
else {
|
|
path = smprintf("%s", base);
|
|
}
|
|
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;
|
|
char *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("%s %.0f%% ", status, ((float)remcap / (float)descap) * 100);
|
|
}
|
|
|
|
char *
|
|
getBrightness(char *base) {
|
|
char *co;
|
|
int brightness, max_brightness;
|
|
char *status;
|
|
|
|
co = readfile(base, "brightness");
|
|
if (co == NULL)
|
|
return smprintf("");
|
|
|
|
sscanf(co, "%d", &brightness);
|
|
free(co);
|
|
|
|
co = readfile(base, "max_brightness");
|
|
if (co == NULL)
|
|
return smprintf("");
|
|
sscanf(co, "%d", &max_brightness);
|
|
free(co);
|
|
|
|
int percentage = (((float)brightness / (float)max_brightness) * 100);
|
|
|
|
if(percentage < 50) {
|
|
status = "🔅";
|
|
} else {
|
|
status = "☀";
|
|
}
|
|
|
|
return smprintf("%s %d%% ", status, percentage);
|
|
}
|
|
char *
|
|
getPowerConsumption(char *base) {
|
|
char *co;
|
|
long usageRead;
|
|
float usage;
|
|
|
|
co = readfile(base, NULL);
|
|
if (co == NULL)
|
|
return smprintf("");
|
|
|
|
sscanf(co, "%ld", &usageRead);
|
|
free(co);
|
|
|
|
if (usage == 0)
|
|
return smprintf("");
|
|
|
|
usage = usageRead/ 1e6;
|
|
|
|
return smprintf("%.2lf W ", usage);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void update() {
|
|
char *status;
|
|
char *avgs;
|
|
char *home_time;
|
|
char *local_time;
|
|
char *t0;
|
|
char *bat;
|
|
char *brightness;
|
|
char *powerConsumption;
|
|
|
|
avgs = loadavg();
|
|
home_time = mktimes("%H:%M", tzwarsaw);
|
|
local_time = mktimes("%H:%M %d.%m.%Y", tzlocal);
|
|
t0 = gettemperature("/sys/class//hwmon/hwmon1", "temp1_input");
|
|
bat = getbattery("/sys/class/power_supply/BAT0");
|
|
brightness = getBrightness("/sys/class/backlight/amdgpu_bl0");
|
|
powerConsumption = getPowerConsumption("/sys/class/power_supply/BAT0/power_now");
|
|
|
|
if (strcmp(tzwarsaw, tzlocal) == 0) {
|
|
status = smprintf("%s%s%s%s%s%s",
|
|
powerConsumption, bat, brightness, t0, avgs, local_time);
|
|
} else {
|
|
status = smprintf("%s%s%s%s%s%s %s",
|
|
powerConsumption, bat, brightness, t0, avgs, home_time, local_time);
|
|
}
|
|
setstatus(status);
|
|
|
|
free(t0);
|
|
free(bat);
|
|
free(avgs);
|
|
free(home_time);
|
|
free(local_time);
|
|
free(status);
|
|
free(brightness);
|
|
}
|
|
|
|
void sleepUntilFullMinute() {
|
|
time_t tim;
|
|
struct tm *tm;
|
|
tim = time(NULL);
|
|
|
|
tm = localtime(&tim);
|
|
int seconds_left = 60 - tm->tm_sec;
|
|
sleep(seconds_left);
|
|
}
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
if (!(dpy = XOpenDisplay(NULL))) {
|
|
fprintf(stderr, "dwmstatus: cannot open display.\n");
|
|
return 1;
|
|
}
|
|
update();
|
|
sleepUntilFullMinute();
|
|
|
|
for (;;sleep(60)) {
|
|
update();
|
|
}
|
|
|
|
XCloseDisplay(dpy);
|
|
|
|
return 0;
|
|
}
|
|
|