remove historical cruft and exchange homegrown statusbar to polybar
the statusbar program is being reworked. until then, we'll just use polybar.
This commit is contained in:
parent
16c071c9a3
commit
4b2b07b960
|
@ -1,75 +0,0 @@
|
||||||
include config.mk
|
|
||||||
all: mkc
|
|
||||||
install: man sh c all
|
|
||||||
.PHONY: man sh mkc c
|
|
||||||
|
|
||||||
man:
|
|
||||||
mkdir -p $(DESTDIR)$(PREFIX)/man/man1
|
|
||||||
cp -f man/* $(DESTDIR)$(PREFIX)/man/man1
|
|
||||||
|
|
||||||
sh:
|
|
||||||
mkdir -p $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/paste $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/snapcad $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/sfeed_yt_add $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/disp $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/wallpaper $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/connect $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/nws $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/vol $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/pco $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/git-survey $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/vim-swap-handler $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/status $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/statusbar $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/cfg $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/fire $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/pash-dmenu $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/pash-dmenu-backend $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/tmenu $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/tmenu-backend $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/tmenu_run $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/ss $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/net $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/bspwm-toggle-gaps $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/machine $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/brightness $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/git-credential-gitpass $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/capture $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/toggle-contingency-mode $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f sh/keyboard $(DESTDIR)$(PREFIX)/bin
|
|
||||||
ln -sf $(DESTDIR)$(PREFIX)/bin/tmenu_run $(DESTDIR)$(PREFIX)/bin/regenerate
|
|
||||||
cp -f sh/discord $(DESTDIR)$(PREFIX)/bin
|
|
||||||
|
|
||||||
check:
|
|
||||||
shellcheck sh/*
|
|
||||||
|
|
||||||
mkc: c/scream c/timer c/boid c/anaconda c/colors c/xgetnewwindow c/tmessage
|
|
||||||
|
|
||||||
c/boid:
|
|
||||||
cc c/boid.c -o c/boid -lm -lX11
|
|
||||||
|
|
||||||
c/anaconda:
|
|
||||||
cc c/anaconda.c -o c/anaconda -lm -lX11
|
|
||||||
|
|
||||||
c/xgetnewwindow:
|
|
||||||
cc c/xgetnewwindow.c -o c/xgetnewwindow -lX11
|
|
||||||
|
|
||||||
c:
|
|
||||||
cp -f c/scream $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f c/timer $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f c/boid $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f c/anaconda $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f c/colors $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f c/xgetnewwindow $(DESTDIR)$(PREFIX)/bin
|
|
||||||
cp -f c/tmessage $(DESTDIR)$(PREFIX)/bin
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f c/scream
|
|
||||||
rm -f c/timer
|
|
||||||
rm -f c/boid
|
|
||||||
rm -f c/anaconda
|
|
||||||
rm -f c/colors
|
|
||||||
rm -f c/simplestatus
|
|
||||||
rm -f c/xgetnewwindow
|
|
||||||
rm -f c/tmessage
|
|
|
@ -1,247 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
typedef struct point {
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
struct point *next;
|
|
||||||
} point;
|
|
||||||
|
|
||||||
typedef struct anaconda {
|
|
||||||
int score;
|
|
||||||
double rot;
|
|
||||||
struct point *chain;
|
|
||||||
} anaconda;
|
|
||||||
|
|
||||||
Display *d;
|
|
||||||
Window w;
|
|
||||||
XEvent e;
|
|
||||||
int s;
|
|
||||||
GC gc;
|
|
||||||
|
|
||||||
void xinit(void) {
|
|
||||||
d = XOpenDisplay(NULL);
|
|
||||||
s = DefaultScreen(d);
|
|
||||||
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
|
|
||||||
BlackPixel(d, s), WhitePixel(d, s));
|
|
||||||
XSelectInput(d, w, ExposureMask | KeyPressMask | PointerMotionMask);
|
|
||||||
XMapWindow(d, w);
|
|
||||||
gc = XCreateGC(d, w, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* thanks to
|
|
||||||
* https://stackoverflow.com/questions/3838329/how-can-i-check-if-two-segments-intersect/9997374#9997374
|
|
||||||
* for functions ccw and intersect
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ccw(point *a, point *b, point *c) {
|
|
||||||
return (c->y - a->y) * (b->x - a->x) >
|
|
||||||
(b->y - a->y) * (c->x - a->x);
|
|
||||||
}
|
|
||||||
|
|
||||||
int intersect(point *a, point *b, point *c, point *d) {
|
|
||||||
return (ccw(a, c, d) != ccw(b, c, d)) && (ccw(a, b, c) != ccw(a, b, d));
|
|
||||||
}
|
|
||||||
|
|
||||||
int randrange(int b, int s) {
|
|
||||||
return rand() % (b - s + 1) + s;
|
|
||||||
}
|
|
||||||
|
|
||||||
int eucliddist(point *a, point *b) {
|
|
||||||
return sqrt(pow(a->x - b->x, 2) + pow(a->y - b->y, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
point *mkPoint(double x, double y) {
|
|
||||||
point *ret = malloc(sizeof *ret);
|
|
||||||
|
|
||||||
ret->x = x;
|
|
||||||
ret->y = y;
|
|
||||||
ret->next = NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
point *rotate(point *p, double rot) {
|
|
||||||
double rad = rot * M_PI/180;
|
|
||||||
|
|
||||||
return mkPoint(
|
|
||||||
p->x * cos(rad) - p->y * sin(rad),
|
|
||||||
p->x * sin(rad) + p->y * cos(rad)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendPoint(point *dest, point *origin) {
|
|
||||||
while(dest->next) dest = dest->next;
|
|
||||||
dest->next = origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int updateAnaconda(anaconda *anaconda, point *basepoint, int w, int h, point *apple) {
|
|
||||||
point *temp, *new, *ptr;
|
|
||||||
new = anaconda->chain;
|
|
||||||
|
|
||||||
temp = rotate(basepoint, anaconda->rot);
|
|
||||||
new = mkPoint(
|
|
||||||
new->x + temp->x,
|
|
||||||
new->y + temp->y
|
|
||||||
);
|
|
||||||
new->next = anaconda->chain;
|
|
||||||
anaconda->chain = new;
|
|
||||||
|
|
||||||
free(temp);
|
|
||||||
|
|
||||||
if(eucliddist(new, apple) <= 30) {
|
|
||||||
anaconda->score += 30;
|
|
||||||
apple->x = randrange(20, w / 2);
|
|
||||||
apple->y = randrange(20, h / 2);
|
|
||||||
} else {
|
|
||||||
ptr = new;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
if(ptr->next) {
|
|
||||||
if(ptr->next->next) ptr = ptr->next;
|
|
||||||
else break;
|
|
||||||
} else break;
|
|
||||||
}
|
|
||||||
free(ptr->next);
|
|
||||||
ptr->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = anaconda->chain;
|
|
||||||
for(int i = 0; i < 3; i++) {
|
|
||||||
if(ptr->next) ptr = ptr->next;
|
|
||||||
else return 1; /* we're fine, the snake is too short to intersect itself */
|
|
||||||
}
|
|
||||||
|
|
||||||
while(ptr->next) {
|
|
||||||
if(intersect(new, new->next, ptr, ptr->next)) return 0;
|
|
||||||
ptr = ptr->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(
|
|
||||||
new->x >= w || new->x <= 0 ||
|
|
||||||
new->y >= h || new->y <= 0
|
|
||||||
) return 0;
|
|
||||||
|
|
||||||
if(eucliddist(new, apple) <= 30) {
|
|
||||||
anaconda->score += 30;
|
|
||||||
apple->x = randrange(20, w / 2);
|
|
||||||
apple->y = randrange(20, h / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeAnaconda(anaconda *anaconda) {
|
|
||||||
point *current = anaconda->chain;
|
|
||||||
point *next = NULL;
|
|
||||||
for(;;) {
|
|
||||||
if(!current) break;
|
|
||||||
next = current->next;
|
|
||||||
free(current);
|
|
||||||
current = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(anaconda);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
point *generateChain(int length) {
|
|
||||||
point *ret = mkPoint(100, 100);
|
|
||||||
point *head = ret;
|
|
||||||
|
|
||||||
for(int i = 1; i < length - 1; i++) {
|
|
||||||
ret->next = mkPoint(
|
|
||||||
10 * i + 100,
|
|
||||||
5 * i + 100
|
|
||||||
);
|
|
||||||
ret = ret->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
anaconda *mkAnaconda(point *point, double rot) {
|
|
||||||
anaconda *ret = malloc(sizeof *ret);
|
|
||||||
|
|
||||||
ret->chain = point;
|
|
||||||
ret->rot = rot;
|
|
||||||
ret->score = 0;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
anaconda *anaconda = mkAnaconda(generateChain(30), 0);
|
|
||||||
point *basepoint = mkPoint(10, 0);
|
|
||||||
char scorebuffer[30];
|
|
||||||
xinit();
|
|
||||||
srand(time(0));
|
|
||||||
int width = DisplayWidth(d, s);
|
|
||||||
int height = DisplayHeight(d, s);
|
|
||||||
point *apple = mkPoint(randrange(20, width / 2 - 20), randrange(20, height / 2 - 20));
|
|
||||||
int exposed = 0;
|
|
||||||
while(1) {
|
|
||||||
if(exposed) {
|
|
||||||
if(!updateAnaconda(anaconda, basepoint, width, height, apple)) {
|
|
||||||
freeAnaconda(anaconda);
|
|
||||||
free(apple);
|
|
||||||
free(basepoint);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
XClearWindow(d, w);
|
|
||||||
point *ptr = anaconda->chain;
|
|
||||||
while(ptr->next) {
|
|
||||||
XDrawLine(d, w, gc, ptr->x, ptr->y, ptr->next->x, ptr->next->y);
|
|
||||||
ptr = ptr->next;
|
|
||||||
}
|
|
||||||
XDrawArc(d, w, gc, apple->x - (5/2), apple->y - (5/2), 5, 5, 0, 360*64);
|
|
||||||
int len = snprintf(&scorebuffer, 30, "%i", anaconda->score);
|
|
||||||
XDrawString(d, w, gc, 25, 25, &scorebuffer, len);
|
|
||||||
}
|
|
||||||
while(XPending(d)) {
|
|
||||||
XNextEvent(d, &e);
|
|
||||||
switch(e.type) {
|
|
||||||
case KeyPress:
|
|
||||||
switch(e.xkey.keycode) {
|
|
||||||
case 113: /* left arrow key */
|
|
||||||
anaconda->rot += 10;
|
|
||||||
break;
|
|
||||||
case 114: /* right arrow key */
|
|
||||||
anaconda->rot -= 10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Expose:
|
|
||||||
/* hold off drawing until we get an expose event */
|
|
||||||
exposed = 1;
|
|
||||||
|
|
||||||
width = e.xexpose.width;
|
|
||||||
height = e.xexpose.height;
|
|
||||||
|
|
||||||
if(apple->x > width) {
|
|
||||||
free(apple);
|
|
||||||
apple = mkPoint(randrange(20, width / 2 - 20), randrange(20, height / 2 - 20));
|
|
||||||
} else if (apple->y > height) {
|
|
||||||
free(apple);
|
|
||||||
apple = mkPoint(randrange(20, width / 2 - 20), randrange(20, height / 2 - 20));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
usleep(100000);
|
|
||||||
}
|
|
||||||
|
|
||||||
freeAnaconda(anaconda);
|
|
||||||
free(apple);
|
|
||||||
free(basepoint);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,206 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
|
|
||||||
|
|
||||||
const double sprite[][2] = {
|
|
||||||
{0, 1},
|
|
||||||
{-0.5, -1},
|
|
||||||
{0, -0.5},
|
|
||||||
{0.5, -1},
|
|
||||||
};
|
|
||||||
#define SIZE sizeof sprite / sizeof sprite[0]
|
|
||||||
|
|
||||||
double buffer[SIZE][2];
|
|
||||||
int boidcounter = 0;
|
|
||||||
|
|
||||||
Display *d;
|
|
||||||
Window w;
|
|
||||||
XEvent e;
|
|
||||||
int s;
|
|
||||||
GC gc;
|
|
||||||
|
|
||||||
typedef struct point {
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
} point;
|
|
||||||
|
|
||||||
typedef struct boid {
|
|
||||||
int id;
|
|
||||||
point *p;
|
|
||||||
double rot;
|
|
||||||
struct boid *next;
|
|
||||||
} boid;
|
|
||||||
|
|
||||||
void xinit(void) {
|
|
||||||
d = XOpenDisplay(NULL);
|
|
||||||
s = DefaultScreen(d);
|
|
||||||
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
|
|
||||||
BlackPixel(d, s), WhitePixel(d, s));
|
|
||||||
XSelectInput(d, w, ExposureMask | KeyPressMask | PointerMotionMask);
|
|
||||||
XMapWindow(d, w);
|
|
||||||
gc = XCreateGC(d, w, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sign(double x) {
|
|
||||||
return (x > 0) - (x < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
point *rotate(double x, double y, double rot) {
|
|
||||||
point *ret = malloc(sizeof ret);
|
|
||||||
double rad = rot * M_PI/180;
|
|
||||||
|
|
||||||
ret->x = x * cos(rad) - y * sin(rad);
|
|
||||||
ret->y = x * sin(rad) + y * cos(rad);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
double distance(point *a, point *b) {
|
|
||||||
return sqrt(pow(a->x - b->x, 2) + pow(a->y - b->y, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void calculateRender(
|
|
||||||
double x,
|
|
||||||
double y,
|
|
||||||
double rot,
|
|
||||||
int scale
|
|
||||||
) {
|
|
||||||
memcpy(&buffer, &sprite, SIZE);
|
|
||||||
|
|
||||||
for(int i = 0; i < SIZE; i++) {
|
|
||||||
point *p = rotate(sprite[i][0], sprite[i][1], rot);
|
|
||||||
|
|
||||||
buffer[i][0] = p->x * scale + x;
|
|
||||||
buffer[i][1] = p->y * scale + y;
|
|
||||||
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderBuffer(void) {
|
|
||||||
for(int i = 0; i < SIZE - 1; i++) {
|
|
||||||
XDrawLine(d, w, gc,
|
|
||||||
buffer[i][0], buffer[i][1],
|
|
||||||
buffer[i + 1][0], buffer[i + 1][1]);
|
|
||||||
}
|
|
||||||
XDrawLine(d, w, gc,
|
|
||||||
buffer[0][0], buffer[0][1],
|
|
||||||
buffer[SIZE - 1][0], buffer[SIZE - 1][1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderBoid(boid *boid) {
|
|
||||||
calculateRender(
|
|
||||||
boid->p->x,
|
|
||||||
boid->p->y,
|
|
||||||
boid->rot,
|
|
||||||
5
|
|
||||||
);
|
|
||||||
renderBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
boid *mkBoid(double x, double y, double rot) {
|
|
||||||
boid *b = malloc(sizeof b);
|
|
||||||
point *p = malloc(sizeof p);
|
|
||||||
b->p = p;
|
|
||||||
|
|
||||||
b->p->x = x;
|
|
||||||
b->p->y = y;
|
|
||||||
b->rot = rot;
|
|
||||||
b->next = NULL;
|
|
||||||
b->id = boidcounter++;
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendBoid(boid *destination, boid *source) {
|
|
||||||
destination->next = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
double averageHeading(boid *b) {
|
|
||||||
boid *c = b;
|
|
||||||
double sum;
|
|
||||||
int count;
|
|
||||||
while(c) {
|
|
||||||
sum += c->rot;
|
|
||||||
count++;
|
|
||||||
c = c->next;
|
|
||||||
}
|
|
||||||
return sum / count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void randomBoids(boid *b, int num) {
|
|
||||||
srand(time(0));
|
|
||||||
boid *ptr = b;
|
|
||||||
for(int i = 0; i < num; i++) {
|
|
||||||
int w = rand() % DisplayWidth(d, s) + 1;
|
|
||||||
int h = rand() % DisplayHeight(d, s) + 1;
|
|
||||||
int deg = rand() % 360;
|
|
||||||
appendBoid(ptr, mkBoid(w, h, deg));
|
|
||||||
ptr = ptr->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateBoid(boid *b, boid *chain, int id, double average) {
|
|
||||||
point *p = rotate(5, 0, b->rot + 90);
|
|
||||||
b->p->x = b->p->x + p->x;
|
|
||||||
b->p->y = b->p->y + p->y;
|
|
||||||
double toTurn = 0;
|
|
||||||
|
|
||||||
boid *c = chain;
|
|
||||||
while(c) {
|
|
||||||
if(c->id != id) {
|
|
||||||
int dist = distance(c->p, b->p);
|
|
||||||
if(dist < 50) toTurn += dist / 75;
|
|
||||||
}
|
|
||||||
int w = DisplayWidth(d, s);
|
|
||||||
int h = DisplayHeight(d, s);
|
|
||||||
int centerw = w / 2 - b->p->x;
|
|
||||||
int centerh = h / 2 - b->p->y;
|
|
||||||
double deg = atan((double)centerh / (double)centerw) * 180/M_PI;
|
|
||||||
toTurn += sign(deg) * 0.5;
|
|
||||||
toTurn += (average - c->rot) * 0.4;
|
|
||||||
if(b->p->x > w) b->p->x = 0;
|
|
||||||
else if(b->p->x < 0) b->p->x = w;
|
|
||||||
if(b->p->y > h) b->p->y = 0;
|
|
||||||
else if(b->p->y < 0) b->p->y = h;
|
|
||||||
|
|
||||||
toTurn = MIN(toTurn / 4, 30);
|
|
||||||
|
|
||||||
b->rot += toTurn;
|
|
||||||
c = c->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
xinit();
|
|
||||||
boid *b = mkBoid(100, 100, 0);
|
|
||||||
randomBoids(b, 100);
|
|
||||||
while(1) {
|
|
||||||
XClearWindow(d, w);
|
|
||||||
boid *ptr = b;
|
|
||||||
while(ptr) {
|
|
||||||
updateBoid(ptr, b, ptr->id, averageHeading(b));
|
|
||||||
renderBoid(ptr);
|
|
||||||
XFlush(d);
|
|
||||||
ptr = ptr->next;
|
|
||||||
}
|
|
||||||
while(XPending(d)) {
|
|
||||||
XNextEvent(d, &e);
|
|
||||||
switch(e.type) {
|
|
||||||
case KeyPress:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
usleep(50000);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,286 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct color {
|
|
||||||
int r;
|
|
||||||
int g;
|
|
||||||
int b;
|
|
||||||
};
|
|
||||||
|
|
||||||
void init_random(void) {
|
|
||||||
srand(time(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
int rand_range(int u, int l) {
|
|
||||||
return (rand() % (u - l + 1)) + l;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exec_with_stdout(char *file, char *args[], char *buf, int length) {
|
|
||||||
int pfds[2];
|
|
||||||
pipe(pfds);
|
|
||||||
int status = fork();
|
|
||||||
|
|
||||||
if(status == 0) {
|
|
||||||
close(1);
|
|
||||||
dup(pfds[1]);
|
|
||||||
close(pfds[0]);
|
|
||||||
|
|
||||||
execvp(file, args);
|
|
||||||
} else {
|
|
||||||
if(!buf) return; /* don't read anything */
|
|
||||||
int readin = read(pfds[0], buf, length - 1);
|
|
||||||
buf[readin] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void imagemagick(char *filename, char *buffer, int size) {
|
|
||||||
char *execargs[] = {
|
|
||||||
"convert",
|
|
||||||
filename,
|
|
||||||
"-resize",
|
|
||||||
"25%",
|
|
||||||
"-colors",
|
|
||||||
"16",
|
|
||||||
"-unique-colors",
|
|
||||||
"-quiet",
|
|
||||||
"txt:-",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
char *name = "convert";
|
|
||||||
|
|
||||||
exec_with_stdout(name, execargs, buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct color *get_raw_colors(char *image) {
|
|
||||||
char buf[2048];
|
|
||||||
|
|
||||||
imagemagick(image, (char *)&buf, 2048);
|
|
||||||
int hcount = 0;
|
|
||||||
char cbuf[3][3];
|
|
||||||
static struct color colors[16];
|
|
||||||
|
|
||||||
for(int i = 0; (unsigned int)i < sizeof buf; i++) {
|
|
||||||
if(buf[i] == '#') {
|
|
||||||
hcount++; /* we have to ignore a comment, that's why there's a special case */
|
|
||||||
if(hcount >= 2 && hcount - 2 < 16 && (unsigned int)(i + 6) < sizeof buf) {
|
|
||||||
memcpy((char *)&cbuf[0], buf + i + 1, 2);
|
|
||||||
memcpy((char *)&cbuf[1], buf + i + 3, 2);
|
|
||||||
memcpy((char *)&cbuf[2], buf + i + 5, 2);
|
|
||||||
cbuf[0][2] = '\0';
|
|
||||||
cbuf[1][2] = '\0';
|
|
||||||
cbuf[2][2] = '\0';
|
|
||||||
colors[hcount - 2].r = (int)strtol((char *)&cbuf[0], NULL, 16);
|
|
||||||
colors[hcount - 2].g = (int)strtol((char *)&cbuf[1], NULL, 16);
|
|
||||||
colors[hcount - 2].b = (int)strtol((char *)&cbuf[2], NULL, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (struct color *)&colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
void blend_color(struct color *a, struct color *b, struct color *c) {
|
|
||||||
c->r = (int)(0.5 * a->r + 0.5 * b->r);
|
|
||||||
c->g = (int)(0.5 * a->g + 0.5 * b->g);
|
|
||||||
c->b = (int)(0.5 * a->b + 0.5 * b->b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void darken_color(struct color *a, struct color *b, double percentage) {
|
|
||||||
b->r = (int)(a->r * (1 - percentage));
|
|
||||||
b->g = (int)(a->g * (1 - percentage));
|
|
||||||
b->b = (int)(a->b * (1 - percentage));
|
|
||||||
}
|
|
||||||
|
|
||||||
void adjust_colors(struct color *colors) {
|
|
||||||
/* #eeeeee */
|
|
||||||
struct color e = {238, 238, 238};
|
|
||||||
|
|
||||||
/* if top digit != 0 */
|
|
||||||
if(colors[0].r > 15)
|
|
||||||
darken_color(&colors[0], &colors[0], 0.40);
|
|
||||||
|
|
||||||
blend_color(&colors[7], &e, &colors[7]);
|
|
||||||
darken_color(&colors[7], &colors[8], 0.30);
|
|
||||||
blend_color(&colors[15], &e, &colors[15]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_colors(struct color *colors) {
|
|
||||||
int j = 0;
|
|
||||||
for(int i = 0; i < 16; i++) {
|
|
||||||
if(colors[i].r + colors[i].g + colors[i].b == 0) j++;
|
|
||||||
}
|
|
||||||
if(j > 0) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct color *get_colors(char *filename) {
|
|
||||||
/* check for permission */
|
|
||||||
if(access(filename, F_OK | R_OK) != 0) {
|
|
||||||
errno = ENOENT;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct color *col = get_raw_colors(filename);
|
|
||||||
adjust_colors(col);
|
|
||||||
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* generalized function ,
|
|
||||||
* used by get_conf_file and get_wal_dir */
|
|
||||||
char *get_file_gen(char *initvar, char *backvar, char *postfix, char *file) {
|
|
||||||
static char buffer[256];
|
|
||||||
int extension = 0;
|
|
||||||
char *path = getenv(initvar);
|
|
||||||
if(!path) {
|
|
||||||
path = getenv(backvar);
|
|
||||||
extension = 1;
|
|
||||||
}
|
|
||||||
if(!path) {
|
|
||||||
fprintf(stderr, "error: both initvar and backvar are undefined.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(buffer, 256, "%s%s/%s", path, extension ? postfix : "", file);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *get_conf_file(char *file) {
|
|
||||||
return get_file_gen("XDG_CONFIG_HOME", "HOME", "/.config/cwal", file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pass NULL to get the base dir name, not specific file */
|
|
||||||
char *get_wal_dir(char *file) {
|
|
||||||
if(!file) file = "";
|
|
||||||
|
|
||||||
return get_file_gen("XDG_DATA_HOME", "HOME", "/.local/share/wallpapers", file);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *select_random_rel(void) {
|
|
||||||
DIR *dir = opendir(get_wal_dir(NULL));
|
|
||||||
struct dirent *file;
|
|
||||||
/* probably should move hardcoded constants somewhere that makes sense */
|
|
||||||
static char names[50][256];
|
|
||||||
int i = 0, random;
|
|
||||||
|
|
||||||
init_random();
|
|
||||||
|
|
||||||
while(file = readdir(dir)) {
|
|
||||||
if(i == 50) break;
|
|
||||||
if(file->d_type != DT_REG) continue;
|
|
||||||
|
|
||||||
memcpy(&names[i], file->d_name, 256);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
random = rand_range(i - 1, 0);
|
|
||||||
|
|
||||||
return names[random];
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_color(struct color *color) {
|
|
||||||
printf("#%02x%02x%02x\n", color->r, color->g, color->b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void run_handler(struct color *colors, char *wal) {
|
|
||||||
char chars[16][8];
|
|
||||||
char *argv[19];
|
|
||||||
|
|
||||||
for(int i = 0; i < 16; i++) {
|
|
||||||
snprintf(&chars[i], 8, "#%02x%02x%02x", colors[i].r, colors[i].g, colors[i].b);
|
|
||||||
}
|
|
||||||
for(int i = 0; i < 16; i++) {
|
|
||||||
argv[i + 1] = &chars[i];
|
|
||||||
}
|
|
||||||
argv[17] = wal;
|
|
||||||
argv[18] = NULL;
|
|
||||||
|
|
||||||
char *conf = get_conf_file("handler");
|
|
||||||
argv[0] = "handler";
|
|
||||||
|
|
||||||
if(access(conf, F_OK | R_OK | X_OK) != 0) {
|
|
||||||
printf("couldn't find %s!\n", conf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
exec_with_stdout(conf, argv, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct settings {
|
|
||||||
int h:1; /* running hooks or not */
|
|
||||||
int e:1; /* echo colors */
|
|
||||||
int c:1; /* enable color check */
|
|
||||||
int f:1; /* print filename used */
|
|
||||||
char *wal; /* custom file if provided */
|
|
||||||
} settings = {
|
|
||||||
.h = 1,
|
|
||||||
.e = 0,
|
|
||||||
.c = 0,
|
|
||||||
.f = 0,
|
|
||||||
.wal = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
char *select_random_file(char *file) {
|
|
||||||
if(!file) file = select_random_rel();
|
|
||||||
static char ret[256];
|
|
||||||
file = get_wal_dir(file);
|
|
||||||
memcpy(&ret, file, 256);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int c;
|
|
||||||
while((c = getopt(argc, argv, "hefcw:")) != -1) {
|
|
||||||
switch(c) {
|
|
||||||
case 'h':
|
|
||||||
settings.h = 0;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
settings.wal = optarg;
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
settings.e = 1;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
settings.c = 1;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
settings.f = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(settings.h == 0) settings.e = 1;
|
|
||||||
|
|
||||||
char *file = select_random_file(settings.wal);
|
|
||||||
struct color *colors = get_colors(file);
|
|
||||||
|
|
||||||
if(settings.f) printf("%s\n", file);
|
|
||||||
|
|
||||||
if(settings.e) {
|
|
||||||
for(int i = 0; i < 16; i++) {
|
|
||||||
print_color(&colors[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(settings.c) {
|
|
||||||
c = check_colors(colors);
|
|
||||||
if(c == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(settings.h) run_handler(colors, file);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
/* written on new year's eve 2020
|
|
||||||
* good night and good riddance */
|
|
||||||
|
|
||||||
char newchar(char c, int i) {
|
|
||||||
if(i % 2) {
|
|
||||||
if(islower(c)) return c - 32;
|
|
||||||
} else if(isupper(c)) return c + 32;
|
|
||||||
if(c == 33) return -2;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
int main(void) {
|
|
||||||
char c;
|
|
||||||
int i = 0;
|
|
||||||
while((c = getchar()) != EOF) {
|
|
||||||
putchar(newchar(c, i));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,174 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct timer {
|
|
||||||
int s; /* seconds */
|
|
||||||
int d; /* data storage */
|
|
||||||
void (*u)(struct timer *t); /* update function */
|
|
||||||
int (*c)(struct timer *t); /* stop check function */
|
|
||||||
int (*p)(struct timer *t); /* pause check function */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct settings {
|
|
||||||
unsigned int e:1; /* use escape (v assumed) */
|
|
||||||
unsigned int v:1; /* verbose */
|
|
||||||
unsigned int d:1; /* count down/up (1/0) */
|
|
||||||
unsigned int b:1; /* ascii bel when done */
|
|
||||||
unsigned int f:1; /* display hours */
|
|
||||||
unsigned int t:1; /* tomato timer */
|
|
||||||
unsigned int p:1; /* stop after tomato timer cycle finished */
|
|
||||||
int s; /* seconds */
|
|
||||||
} s = {
|
|
||||||
.e = 0,
|
|
||||||
.v = 0,
|
|
||||||
.d = 0,
|
|
||||||
.b = 0,
|
|
||||||
.f = 0,
|
|
||||||
.t = 0,
|
|
||||||
.p = 0,
|
|
||||||
.s = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
void timerdec(struct timer *t) { if (t->s) t->s--; }
|
|
||||||
void timerinc(struct timer *t) { t->s++; }
|
|
||||||
void timerupdate(struct timer *t) { if(t->u) t->u(t); }
|
|
||||||
|
|
||||||
int timerstate(int (*f)(struct timer *t), struct timer *t) {
|
|
||||||
if(f) {
|
|
||||||
if(f(t)) return 1;
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int timerstop(struct timer *t) { return timerstate(t->c, t); }
|
|
||||||
int timerpause(struct timer *t) { return timerstate(t->p, t); }
|
|
||||||
|
|
||||||
int timerzero(struct timer *t) {
|
|
||||||
if(!t->s) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int seconds(int t) { return t % 60; }
|
|
||||||
int minutes(int t) { return (t / 60) % 60; }
|
|
||||||
int minute(int t) { return t / 60; }
|
|
||||||
int hours(int t) { return (t / 60) / 60; }
|
|
||||||
|
|
||||||
struct timer *timerinit(void) {
|
|
||||||
struct timer *t = malloc(sizeof *t);
|
|
||||||
t->s = 0;
|
|
||||||
t->d = 0;
|
|
||||||
t->u = NULL;
|
|
||||||
t->c = NULL;
|
|
||||||
t->p = NULL;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
int timerissettings(struct timer *t) {
|
|
||||||
if(!t->s) return 0;
|
|
||||||
if(s.s == t->s) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tomatotimer(struct timer *t) {
|
|
||||||
if(t->s) return 0;
|
|
||||||
if(t->d % 2) t->s = s.s / 2;
|
|
||||||
else t->s = s.s;
|
|
||||||
t->d++;
|
|
||||||
if(s.b) putchar('\a');
|
|
||||||
if(s.p) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *timerdisp(struct timer *t) {
|
|
||||||
char *str = malloc(20);
|
|
||||||
if(s.f) snprintf(str, 20, "%02i:%02i:%02i",
|
|
||||||
hours(t->s), minutes(t->s), seconds(t->s));
|
|
||||||
/* TODO: give minute(...) and minutes(...) better names */
|
|
||||||
else snprintf(str, 20, "%02i:%02i", minute(t->s), seconds(t->s));
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void defaultSettings(struct settings s) {
|
|
||||||
s.e = 1;
|
|
||||||
s.b = 1;
|
|
||||||
s.f = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void timerloop() {
|
|
||||||
struct timer *t = timerinit();
|
|
||||||
if(s.d) {
|
|
||||||
t->u = timerdec;
|
|
||||||
t->s = s.s;
|
|
||||||
t->c = timerzero;
|
|
||||||
} else {
|
|
||||||
t->u = timerinc;
|
|
||||||
t->c = timerissettings;
|
|
||||||
}
|
|
||||||
if(s.t) {
|
|
||||||
t->u = timerdec;
|
|
||||||
if(s.s == 0) s.s = 20 * 60;
|
|
||||||
t->s = s.s;
|
|
||||||
t->d = 1;
|
|
||||||
t->p = tomatotimer;
|
|
||||||
t->c = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *c;
|
|
||||||
int e;
|
|
||||||
struct pollfd p = { .fd = STDIN_FILENO, .events = POLLIN };
|
|
||||||
for(;;) {
|
|
||||||
poll(&p, 1, 60);
|
|
||||||
if((e = (p.revents == POLLIN)) || timerpause(t)) {
|
|
||||||
/* TODO: make this nicer */
|
|
||||||
if(e) getchar();
|
|
||||||
if(s.e) {
|
|
||||||
c = timerdisp(t);
|
|
||||||
if(e) printf("\r\e[1A* %s", c);
|
|
||||||
else printf("\r* %s", c);
|
|
||||||
}
|
|
||||||
getchar();
|
|
||||||
/* TODO: stop relying on hard assumptions */
|
|
||||||
if(s.e) printf("\r\e[1A \r");
|
|
||||||
}
|
|
||||||
c = timerdisp(t);
|
|
||||||
if(s.e) {
|
|
||||||
printf("%s\r", c);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
else if(s.v) printf("%s\n", c);
|
|
||||||
if(timerstop(t)) break;
|
|
||||||
free(c);
|
|
||||||
timerupdate(t);
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
if(s.b) putchar('\a');
|
|
||||||
free(t);
|
|
||||||
free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
char c;
|
|
||||||
while((c = getopt(argc, argv, "evdbftpzh:m:s:")) != -1) {
|
|
||||||
switch(c) {
|
|
||||||
break; case 'e': s.e = 1;
|
|
||||||
break; case 'v': s.v = 1;
|
|
||||||
break; case 'd': s.d = 1;
|
|
||||||
break; case 'b': s.b = 1;
|
|
||||||
break; case 'f': s.f = 1;
|
|
||||||
break; case 't': s.t = 1;
|
|
||||||
break; case 'p': s.p = 1;
|
|
||||||
break; case 'z': s.e = 1; s.b = 1; s.f = 1;
|
|
||||||
break; case 'h': s.s = s.s + (atoi(optarg) * 3600);
|
|
||||||
break; case 'm': s.s = s.s + (atoi(optarg) * 60);
|
|
||||||
break; case 's': s.s = s.s + atoi(optarg);
|
|
||||||
break; case '?': return 1;
|
|
||||||
break; default: abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timerloop();
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,148 +0,0 @@
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define ESC_CLEAR "\033[2J"
|
|
||||||
#define ESC_CUSHOME "\033[H"
|
|
||||||
#define ESC_NEWLINE "\033[E\033[1C"
|
|
||||||
|
|
||||||
const char MSG_OK[] = "(O)k";
|
|
||||||
const char MSG_CANCEL[] = "(C)ancel";
|
|
||||||
|
|
||||||
typedef struct winsize ws;
|
|
||||||
|
|
||||||
int lines, cols;
|
|
||||||
char *message;
|
|
||||||
size_t message_len;
|
|
||||||
|
|
||||||
struct termios original_termios;
|
|
||||||
|
|
||||||
void render(char *message, int message_len, int lines, int cols);
|
|
||||||
|
|
||||||
void rawmode_start() {
|
|
||||||
tcgetattr(STDIN_FILENO, &original_termios);
|
|
||||||
struct termios raw = original_termios;
|
|
||||||
raw.c_lflag &= ~(ECHO | ICANON);
|
|
||||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rawmode_stop() {
|
|
||||||
tcsetattr(STDIN_FILENO, TCSAFLUSH, &original_termios);
|
|
||||||
printf("\n\n");
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
ws *getWinSize(void) {
|
|
||||||
/* we're only going to use these values once per invocation,
|
|
||||||
* so it's fine that it's static. */
|
|
||||||
static ws w;
|
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
|
||||||
|
|
||||||
return &w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void handler(int signal, siginfo_t *info, void *context) {
|
|
||||||
ws *w = getWinSize();
|
|
||||||
lines = w->ws_row;
|
|
||||||
cols = w->ws_col;
|
|
||||||
|
|
||||||
render(message, message_len, lines, cols);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void termhandler(int signal, siginfo_t *info, void *context) {
|
|
||||||
rawmode_stop();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int calculate_number_of_lines(int length, int cols) {
|
|
||||||
/* cols - 1 accounts for right padding */
|
|
||||||
return length / (cols - 1) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void go_to_initial_message_printing_pos(void) {
|
|
||||||
printf(ESC_CUSHOME "\033[1B\033[1C");
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_message(char *message, int messagelen, int cols) {
|
|
||||||
int linecount = calculate_number_of_lines(messagelen, cols);
|
|
||||||
int adjcols = cols - 2;
|
|
||||||
int offset = 1;
|
|
||||||
for(int character = 0; character < messagelen; character++) {
|
|
||||||
if(character == adjcols * offset) {
|
|
||||||
printf(ESC_NEWLINE);
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
putchar(message[character]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void render(char *message, int messagelen, int lines, int cols) {
|
|
||||||
int cancel_length = sizeof(MSG_CANCEL) / sizeof(MSG_CANCEL[0]);
|
|
||||||
|
|
||||||
/* print the stuff */
|
|
||||||
printf(ESC_CLEAR "" ESC_CUSHOME);
|
|
||||||
go_to_initial_message_printing_pos();
|
|
||||||
print_message(message, message_len, cols);
|
|
||||||
|
|
||||||
printf(ESC_NEWLINE);
|
|
||||||
printf(ESC_NEWLINE);
|
|
||||||
printf("%s", MSG_OK);
|
|
||||||
printf("\033[1D\033[%iC\033[%iD%s", cols, cancel_length, MSG_CANCEL);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
int cancel_length = strlen(MSG_CANCEL);
|
|
||||||
char c;
|
|
||||||
struct sigaction resizeaction = {};
|
|
||||||
struct sigaction termaction = {};
|
|
||||||
ws *w;
|
|
||||||
|
|
||||||
/* check if we have a message */
|
|
||||||
if(argc > 1) {
|
|
||||||
message = argv[1]; /* second argument's a message */
|
|
||||||
message_len = strlen(message);
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup sigaction handlers */
|
|
||||||
resizeaction.sa_sigaction = &handler;
|
|
||||||
if(sigaction(SIGWINCH, &resizeaction, NULL) == -1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
termaction.sa_sigaction = &termhandler;
|
|
||||||
if(sigaction(SIGTERM, &termaction, NULL) == -1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rawmode_start();
|
|
||||||
|
|
||||||
/* get window properties */
|
|
||||||
w = getWinSize();
|
|
||||||
lines = w->ws_row;
|
|
||||||
cols = w->ws_col;
|
|
||||||
|
|
||||||
render(message, message_len, lines, cols);
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
read(STDIN_FILENO, &c, 1);
|
|
||||||
if(c == 'o') {
|
|
||||||
return 2;
|
|
||||||
rawmode_stop();
|
|
||||||
} else if(c == 'c') {
|
|
||||||
return 3;
|
|
||||||
rawmode_stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
Display* display = XOpenDisplay(NULL);
|
|
||||||
if(!display) {
|
|
||||||
printf("Error: Unable to open display.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int screen = DefaultScreen(display);
|
|
||||||
Window root = RootWindow(display, screen);
|
|
||||||
|
|
||||||
/* SubstructureNotifyMask allows us to be notified of CreateNotify events */
|
|
||||||
XSelectInput(display, root, SubstructureNotifyMask);
|
|
||||||
|
|
||||||
XEvent event;
|
|
||||||
for(;;) {
|
|
||||||
XNextEvent(display, &event);
|
|
||||||
if(event.type == CreateNotify) {
|
|
||||||
/* print window id */
|
|
||||||
printf("0x%x\n", event.xcreatewindow.window);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XCloseDisplay(display);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
DESTDIR=$(HOME)/.local
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
chromium --app=https://discord.com/login --profile-directory="Profile 1"
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
for i in *; do
|
|
||||||
cd "$i" || continue
|
|
||||||
exists=$(
|
|
||||||
git status |
|
|
||||||
grep -c 'Your branch is ahead of '
|
|
||||||
)
|
|
||||||
|
|
||||||
[ "$exists" -eq 0 ] || printf "> %s\n" "$i"
|
|
||||||
cd ..
|
|
||||||
done
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# designed to be called from sxhkd (x session)
|
|
||||||
|
|
||||||
pgrep NetworkManager && st -e nmtui
|
|
|
@ -1,88 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# script for interfacing with planning center online
|
|
||||||
|
|
||||||
appid=$(cat "$HOME/.local/share/pco/appid")
|
|
||||||
token=$(cat "$HOME/.local/share/pco/token")
|
|
||||||
userid=$(cat "$HOME/.local/share/pco/userid")
|
|
||||||
|
|
||||||
get_blockouts_online () {
|
|
||||||
curl -su "$appid:$token" "https://api.planningcenteronline.com/services/v2/people/$userid/blockouts" | \
|
|
||||||
jq .data[].attributes.ends_at | \
|
|
||||||
awk -F'"|-|T' '
|
|
||||||
function y(x) {
|
|
||||||
if (x == 1) return "Jan"
|
|
||||||
if (x == 2) return "Feb"
|
|
||||||
if (x == 3) return "Mar"
|
|
||||||
if (x == 4) return "Apr"
|
|
||||||
if (x == 5) return "May"
|
|
||||||
if (x == 6) return "Jun"
|
|
||||||
if (x == 7) return "Jul"
|
|
||||||
if (x == 8) return "Aug"
|
|
||||||
if (x == 9) return "Sep"
|
|
||||||
if (x == 10) return "Oct"
|
|
||||||
if (x == 11) return "Nov"
|
|
||||||
if (x == 12) return "Dec"
|
|
||||||
return "Unk"
|
|
||||||
}
|
|
||||||
|
|
||||||
{print y($3) " " $4 " " $2}' | \
|
|
||||||
tr '\n' '|' | \
|
|
||||||
sed 's/.\{1\}$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
get_blockouts_local () {
|
|
||||||
grep "MSG Blockout date" "$DOTREMINDERS" | \
|
|
||||||
awk -F' ' '{print $2 " " $3 " " $4}'
|
|
||||||
}
|
|
||||||
|
|
||||||
get_blockouts () {
|
|
||||||
all_dates=$(get_blockouts_online)
|
|
||||||
OLDIFS="$IFS"
|
|
||||||
IFS="|"
|
|
||||||
for i in $all_dates; do
|
|
||||||
results=$(grep -c "^REM $i MSG Blockout date" "$DOTREMINDERS")
|
|
||||||
[ "$results" -eq 0 ] && \
|
|
||||||
printf "REM %s MSG Blockout date\n" "$i" >> "$DOTREMINDERS" && \
|
|
||||||
printf "added %s to calendar\n" "$i" || \
|
|
||||||
printf "omitted %s from the calendar, it's already there\n" "$i"
|
|
||||||
done
|
|
||||||
IFS="$OLDIFS"
|
|
||||||
}
|
|
||||||
|
|
||||||
push_blockouts () {
|
|
||||||
file=$(mktemp)
|
|
||||||
get_blockouts_online | tr '|' '\n' >> "$file"
|
|
||||||
local=$(get_blockouts_local)
|
|
||||||
|
|
||||||
# don't mess with the spacing
|
|
||||||
OLDIFS=$IFS
|
|
||||||
IFS="
|
|
||||||
"
|
|
||||||
printf "temp file: %s\n" "$file"
|
|
||||||
|
|
||||||
for i in $local; do
|
|
||||||
count=$(grep -c "^$i$" "$file")
|
|
||||||
if [ "$count" -eq 0 ]; then
|
|
||||||
printf "push: %s\n" "$i"
|
|
||||||
stddate=$(date --date="$i" "+%Y-%m-%dT06:00:00Z")
|
|
||||||
curl -X POST -H "Content-Type: application/json" -d "
|
|
||||||
{
|
|
||||||
\"data\": {
|
|
||||||
\"attributes\": {
|
|
||||||
\"reason\": \"n/a\",
|
|
||||||
\"repeat_frequency\": \"no_repeat\",
|
|
||||||
\"starts_at\": \"$stddate\",
|
|
||||||
\"ends_at\": \"$stddate\"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}" -su "$appid:$token" "https://api.planningcenteronline.com/services/v2/people/$userid/blockouts"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
IFS=$OLDIFS
|
|
||||||
|
|
||||||
rm "$file"
|
|
||||||
}
|
|
||||||
|
|
||||||
get_blockouts
|
|
||||||
push_blockouts
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# opens snapcad
|
|
||||||
|
|
||||||
wine ~/.wine/drive_c/Program\ Files\ \(x86\)/VEX\ Robotics/SnapCAD/SnapCAD.exe
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
scripts="$(
|
|
||||||
find /home/usr/git/utils/sh /home/usr/git/utils/c -type f |
|
|
||||||
grep -v '\.git' |
|
|
||||||
xargs file |
|
|
||||||
grep 'C source \|POSIX shell script' |
|
|
||||||
awk -F':' '{print $1}' |
|
|
||||||
fzy
|
|
||||||
)"
|
|
||||||
|
|
||||||
[ -z "$scripts" ] || nvim "$scripts"
|
|
|
@ -1,100 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
power_prefix="/sys/class/power_supply/"
|
|
||||||
[ -d "${power_prefix}sbs-20-000b" ] && bat="sbs-20-000b"
|
|
||||||
[ -d "${power_prefix}BAT0" ] && bat="BAT0"
|
|
||||||
|
|
||||||
[ "$(pgrep -c pulseaudio)" -eq 1 ] && ss="pulse" || ss="alsa"
|
|
||||||
|
|
||||||
mod_bspwm () {
|
|
||||||
used_desk=$(bspc query -D -d .occupied --names | tr '\n' ' ')
|
|
||||||
current_desk=$(bspc query -D -d .focused --names)
|
|
||||||
final_string=""
|
|
||||||
current_printed=0
|
|
||||||
cur_char='>'
|
|
||||||
|
|
||||||
for i in $used_desk; do
|
|
||||||
[ "$i" = "$current_desk" ] && \
|
|
||||||
final_string=${final_string}"$cur_char$i " && \
|
|
||||||
current_printed=1 || \
|
|
||||||
final_string=${final_string}"$i "
|
|
||||||
done
|
|
||||||
|
|
||||||
[ $current_printed -eq 0 ] &&
|
|
||||||
final_string=${final_string}"$cur_char$current_desk "
|
|
||||||
|
|
||||||
printf "%s" "$final_string"
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_period () {
|
|
||||||
nextclass
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_sensors () {
|
|
||||||
sensors | grep 'Core 0' | awk -F' ' '{print $3}' | tr -d '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_power () {
|
|
||||||
[ -z "$bat" ] ||
|
|
||||||
tr -d '\n' < /sys/class/power_supply/$bat/capacity
|
|
||||||
sed 's/Charging/↑/g;s/Not charging/-/g;s/Discharging/↓/g;s/Full/-/g' < /sys/class/power_supply/$bat/status
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_vol () {
|
|
||||||
[ "$ss" = "pulse" ] && pactl list sinks | awk -F' ' '$1 == "Volume:" {print "pv" $5}'
|
|
||||||
[ "$ss" = "alsa" ] && amixer | grep '^ Front' | awk -F'[' '{ORS = ""; print "av" substr($2, 1, 3); exit}'
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_date_time () {
|
|
||||||
date '+%m%d-%H:%M' | tr '\n' ' '
|
|
||||||
}
|
|
||||||
|
|
||||||
update_mod () {
|
|
||||||
output="$(eval "mod_$1")"
|
|
||||||
eval "output_$1=\"$output\""
|
|
||||||
}
|
|
||||||
|
|
||||||
get_mod () {
|
|
||||||
eval "printf '%s' \${output_$1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
echo_bar () {
|
|
||||||
left="$(get_mod "bspwm")"
|
|
||||||
right="$(get_mod "date_time")$(get_mod "period") $(get_mod "sensors") $(get_mod "power") $(get_mod "vol")"
|
|
||||||
|
|
||||||
width="$(tput cols)"
|
|
||||||
rightwidth="${#right}"
|
|
||||||
|
|
||||||
# print left side
|
|
||||||
printf "\033[2J\033[H%s" "$left"
|
|
||||||
|
|
||||||
# print right side
|
|
||||||
printf "\033[1;%if%s" "$((width - rightwidth + 1))" "$right"
|
|
||||||
}
|
|
||||||
|
|
||||||
register_sigs () {
|
|
||||||
trap "update_mod vol" USR2
|
|
||||||
trap "update_mod bspwm" USR1
|
|
||||||
}
|
|
||||||
|
|
||||||
update_all () {
|
|
||||||
update_mod power
|
|
||||||
update_mod vol
|
|
||||||
update_mod bspwm
|
|
||||||
update_mod date_time
|
|
||||||
update_mod period
|
|
||||||
update_mod sensors
|
|
||||||
}
|
|
||||||
|
|
||||||
tput civis
|
|
||||||
|
|
||||||
register_sigs
|
|
||||||
update_all
|
|
||||||
|
|
||||||
i=0
|
|
||||||
while true; do
|
|
||||||
sleep 0.25
|
|
||||||
[ "$i" -eq $((29 * 4)) ] && update_all && i=0
|
|
||||||
echo_bar
|
|
||||||
i="$((i + 1))"
|
|
||||||
done
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
barwidth=20
|
|
||||||
|
|
||||||
# remove all current statusbars
|
|
||||||
# pgrep doesn't handle arguments for running commands
|
|
||||||
# shellcheck disable=2009
|
|
||||||
processes="$(ps aux | grep 'st -c' | grep 'status' | awk -F' ' '{print $2}')"
|
|
||||||
for i in $processes; do
|
|
||||||
pkill -P "$i" >/dev/null 2>&1
|
|
||||||
kill "$i"
|
|
||||||
done
|
|
||||||
|
|
||||||
# get all screens
|
|
||||||
screens="$(xrandr | grep ' connected' | sed 's/ primary//g' | awk -F' ' '{print $1 " " $3}')"
|
|
||||||
|
|
||||||
# for every screen, create a statusbar
|
|
||||||
IFS="
|
|
||||||
"
|
|
||||||
for i in $screens; do
|
|
||||||
screenstring=$(echo "$i" | awk -v a="$barwidth" -F'[ x+]' '{print $2 "x" a "+" $4 "+" $5}')
|
|
||||||
st -c statusbar -p -g "$screenstring" -e status &
|
|
||||||
done
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
pulse=$(pgrep -c pulseaudio)
|
|
||||||
|
|
||||||
[ "$1" = "inc" ] && sign="+"
|
|
||||||
[ "$1" = "dec" ] && sign="-"
|
|
||||||
|
|
||||||
[ "$#" -eq 0 ] && exit 1
|
|
||||||
|
|
||||||
if [ "$pulse" -eq 1 ]; then
|
|
||||||
for SINK in $(pacmd list-sinks | grep 'index:' | cut -b12-)
|
|
||||||
do
|
|
||||||
pactl set-sink-volume "$SINK" "${sign}5%"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
amixer -c 0 set Master "5%${sign}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
killall -12 status
|
|
|
@ -4,7 +4,7 @@
|
||||||
# post-wm boilerplate
|
# post-wm boilerplate
|
||||||
wallpaper
|
wallpaper
|
||||||
disp
|
disp
|
||||||
statusbar &
|
polybar &
|
||||||
|
|
||||||
# set up the color scheme
|
# set up the color scheme
|
||||||
bspc config normal_border_color "#161510"
|
bspc config normal_border_color "#161510"
|
||||||
|
|
24
desktop.nix
24
desktop.nix
|
@ -24,12 +24,34 @@ in {
|
||||||
sound.enable = true;
|
sound.enable = true;
|
||||||
hardware.pulseaudio.enable = true;
|
hardware.pulseaudio.enable = true;
|
||||||
|
|
||||||
|
nixpkgs.config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
sx
|
sx
|
||||||
lynx
|
|
||||||
fzy
|
fzy
|
||||||
gnupg
|
gnupg
|
||||||
xclip
|
xclip
|
||||||
|
polybar
|
||||||
|
|
||||||
|
ncpamixer
|
||||||
|
tig
|
||||||
|
cmus
|
||||||
|
neomutt
|
||||||
|
mpv
|
||||||
|
yt-dlp
|
||||||
|
zathura
|
||||||
|
tmux
|
||||||
|
lynx
|
||||||
|
feh
|
||||||
|
elinks
|
||||||
|
sc-im
|
||||||
|
ledger
|
||||||
|
remind
|
||||||
|
python3
|
||||||
|
|
||||||
|
discord
|
||||||
|
|
||||||
(pkgs.callPackage ./builds/utils.nix {})
|
(pkgs.callPackage ./builds/utils.nix {})
|
||||||
(pkgs.callPackage ./builds/st.nix {})
|
(pkgs.callPackage ./builds/st.nix {})
|
||||||
|
|
Loading…
Reference in New Issue