initial commit
This commit is contained in:
commit
6c36abf3fb
3 changed files with 284 additions and 0 deletions
32
Makefile
Normal file
32
Makefile
Normal file
|
@ -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
|
BIN
lobat.mp3
Normal file
BIN
lobat.mp3
Normal file
Binary file not shown.
252
main.c
Normal file
252
main.c
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
/*
|
||||||
|
██████╗░░█████╗░████████╗████████╗░░░░░░░██████╗██╗░██████╗░███╗░░██╗░█████╗░██╗░░░░░
|
||||||
|
██╔══██╗██╔══██╗╚══██╔══╝╚══██╔══╝░░░░░░██╔════╝██║██╔════╝░████╗░██║██╔══██╗██║░░░░░
|
||||||
|
██████╦╝███████║░░░██║░░░░░░██║░░░█████╗╚█████╗░██║██║░░██╗░██╔██╗██║███████║██║░░░░░
|
||||||
|
██╔══██╗██╔══██║░░░██║░░░░░░██║░░░╚════╝░╚═══██╗██║██║░░╚██╗██║╚████║██╔══██║██║░░░░░
|
||||||
|
██████╦╝██║░░██║░░░██║░░░░░░██║░░░░░░░░░██████╔╝██║╚██████╔╝██║░╚███║██║░░██║███████╗
|
||||||
|
╚═════╝░╚═╝░░╚═╝░░░╚═╝░░░░░░╚═╝░░░░░░░░░╚═════╝░╚═╝░╚═════╝░╚═╝░░╚══╝╚═╝░░╚═╝╚══════╝
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/extensions/xf86vmode.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue