commit 6c36abf3fbcea2a90b21b8c173245779952c105f Author: Јован Ђокић-Шумарац Date: Thu May 19 04:50:55 2022 +0200 initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..11a03ac --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +## +# batt-signal +# +# @file +# @version 0.1 + +PREFIX = /usr/local +SHAREPREFIX = $(PREFIX)/share/batt-signal + +all: batt-signal + +CFLAGS = -O2 +CPPFLAGS = -DSHAREPREFIX=\"$(SHAREPREFIX)\" +LIBS = -L/usr/X11R6/lib -lX11 -lXxf86vm -lXft +INCS = -I/usr/include/freetype2 + +batt-signal: main.c + gcc main.c -o batt-signal $(LIBS) $(INCS) $(CFLAGS) $(CPPFLAGS) + +clean: + rm -f batt-signal + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f batt-signal $(DESTDIR)$(PREFIX)/bin + + mkdir -p $(DESTDIR)$(SHAREPREFIX) + cp -f lobat.mp3 $(DESTDIR)$(SHAREPREFIX) + +.PHONY: all install clean + +# end diff --git a/lobat.mp3 b/lobat.mp3 new file mode 100644 index 0000000..9197152 Binary files /dev/null and b/lobat.mp3 differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..484e6f1 --- /dev/null +++ b/main.c @@ -0,0 +1,252 @@ +/* +██████╗░░█████╗░████████╗████████╗░░░░░░░██████╗██╗░██████╗░███╗░░██╗░█████╗░██╗░░░░░ +██╔══██╗██╔══██╗╚══██╔══╝╚══██╔══╝░░░░░░██╔════╝██║██╔════╝░████╗░██║██╔══██╗██║░░░░░ +██████╦╝███████║░░░██║░░░░░░██║░░░█████╗╚█████╗░██║██║░░██╗░██╔██╗██║███████║██║░░░░░ +██╔══██╗██╔══██║░░░██║░░░░░░██║░░░╚════╝░╚═══██╗██║██║░░╚██╗██║╚████║██╔══██║██║░░░░░ +██████╦╝██║░░██║░░░██║░░░░░░██║░░░░░░░░░██████╔╝██║╚██████╔╝██║░╚███║██║░░██║███████╗ +╚═════╝░╚═╝░░╚═╝░░░╚═╝░░░░░░╚═╝░░░░░░░░░╚═════╝░╚═╝░╚═════╝░╚═╝░░╚══╝╚═╝░░╚═╝╚══════╝ +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FONT_SIZE 24 + + + +typedef struct { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long inputMode; + unsigned long status; +} Hints; + + + + +int width, height; +char *message = "Battery is low!!"; + + + + +void catch_fire(char *, int); +void draw_ui(Display *, Window, Visual *, Colormap, int); +void window_attr(Display *, Window, int); +void alert(); + + +enum state { + Alert, + Normal +}; + + +int main(void) { + + time_t lastalert = 0; // a long time ago + enum state laststate = Normal, curstate = Normal; + + + while (1) { + FILE *battery = fopen("/sys/class/power_supply/BAT0/capacity","r"); + FILE *status = fopen("/sys/class/power_supply/BAT0/status","r"); + if(battery == NULL || status == NULL) { + catch_fire("batt-signal : Cannot find battery.\n", 100); + } + + + int cap; + char bat_status[20] = ""; + + fscanf(battery,"%d", &cap); + fscanf(status, "%s", bat_status); + + curstate = cap <= 105 && strcmp(bat_status, "Discharging") == 0 ? Alert : Normal; + if (curstate == Alert && (time(NULL) - lastalert >= 180 || laststate == Normal)) { + alert(); + lastalert = time(NULL); + } + laststate = curstate; +printf("%s : %d\n", bat_status, cap); + + fclose(battery); + fclose(status); + sleep(1); + } + + + return 0; +} + + + + + + +void catch_fire(char *string, int error) { + fprintf(stderr, string); + exit(error); +} + + + + + +void draw_ui(Display *d, Window w, Visual *visual, Colormap cmap, int s) { + + // FONT SHENANIGANS + char font_name[strlen("monospace-") + 2]; + sprintf(font_name, "monospace-%d", FONT_SIZE); + XftFont *font = XftFontOpenName(d, s, font_name); + + printf("lol1\n"); + // FONT COLORS + XftColor xft_black, xft_white; + XftColorAllocName(d, visual, cmap, "black", &xft_black); + XftColorAllocName(d, visual, cmap, "white", &xft_white); + + XftDraw *xftdraw = XftDrawCreate(d, w, visual, cmap); + + + + // MAKE WHITE RECT + int white_rect_x = width / 24; + int white_rect_y = height / 12; + int white_rect_width = width / 18; + int white_rect_height = height / 6; + + XftDrawRect(xftdraw, &xft_white, white_rect_x, white_rect_y, white_rect_width, white_rect_height); + + + + // MAKE BLACK RECT + int black_rect_x = width / 24 + width / 140; + int black_rect_y = height / 12 + height / 100; + int black_rect_width = width / 24; + int black_rect_height = height / 8; + + XftDrawRect(xftdraw, &xft_black, black_rect_x, black_rect_y, black_rect_width, black_rect_height); + + + + // MAKE WHITE BAR + int bar_rect_x = width / 24 + width / 36 - width / 120; + int bar_rect_y = height / 12 - height / 100; + int bar_rect_width = width / 60; + int bar_rect_height = height / 60; + + XftDrawRect(xftdraw, &xft_white, bar_rect_x, bar_rect_y, bar_rect_width, bar_rect_height); + + + // PRINT PASS MESSAGE + XftDrawString8(xftdraw, &xft_white, font, white_rect_x *3, height/6, message, strlen(message)); + + +} + +void alert() + { + Display *d = XOpenDisplay(NULL); + if (d == NULL) + catch_fire("Cannot open display\n", 1); + + int s = DefaultScreen(d); + int depth = DefaultDepth(d, s); + width = DisplayWidth(d, s); + height = DisplayHeight(d, s); + + Window w; + Visual *visual = DefaultVisual(d, s); + Colormap cmap = DefaultColormap(d, s); + + + + // IGNORES WM RULES + XSetWindowAttributes attributes; + attributes.override_redirect = True; + attributes.background_pixel = BlackPixel(d, s); + + + // MAKE THE WINDOW + w = XCreateWindow(d, XRootWindow(d, s), 0, 0, width, height, 0, depth, InputOutput, visual, CWBackPixel | CWOverrideRedirect, &attributes); + + + // SET WINDOW ATTRIBUTES + window_attr(d, w, s); + + // DRAW THE RECTANGLES AND STRINGS + draw_ui(d, w, visual, cmap, s); + + + + //PLAY THE SOUND + pid_t child_id; + + child_id = fork(); + + if (child_id == -1) { + catch_fire("Couldn't fork\n", 1); + } else if (child_id == 0) { + execl("/usr/bin/mpg123", "mpg123", SHAREPREFIX "/lobat.mp3", NULL); + } + + while (1) { + + int foo; + KeySym ksym; + XEvent e; + + XNextEvent(d, &e); + + // CHECK IF ANYTHING IS PRESSED + if(e.type == KeyPress) + break; + + draw_ui(d, w, visual, cmap, s); + } + + XCloseDisplay(d); + } + +void window_attr(Display *d, Window w, int s) { + + int mode_count; + + // VIDEO MODES + XF86VidModeModeInfo **modes, *video_mode; + XF86VidModeGetAllModeLines(d, s, &mode_count, &modes); + video_mode = modes[0]; + + // DISABLE DECORATIONS + Hints hints; + hints.flags = 2; + hints.decorations = 0; + + Atom roperty = XInternAtom(d, "_MOTIF_WM_HINTS", True); + + XSelectInput(d, w, ExposureMask | KeyPressMask); + XMapWindow(d, w); + + // SETTING FULLSCREEN + XF86VidModeSwitchToMode(d, s, video_mode); + XF86VidModeSetViewPort(d, s, 0, 0); + XMoveResizeWindow(d, w, width/3, height/3, width/3, height/3); + XMapRaised(d, w); + + XGrabPointer(d, w, True, 0, GrabModeAsync, GrabModeAsync, w, 0L, CurrentTime); + XGrabKeyboard(d, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); + +}