Merge remote-tracking branch 'utils/master' into utils_import
This commit is contained in:
commit
2ffeb9d9f2
|
@ -0,0 +1,10 @@
|
||||||
|
*.swp
|
||||||
|
*.tmp
|
||||||
|
c/scream
|
||||||
|
c/xgetnewwindow
|
||||||
|
c/timer
|
||||||
|
c/boid
|
||||||
|
c/a.out
|
||||||
|
c/anaconda
|
||||||
|
c/colors
|
||||||
|
c/tmessage
|
|
@ -0,0 +1,75 @@
|
||||||
|
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
|
|
@ -0,0 +1,5 @@
|
||||||
|
TODO LIST
|
||||||
|
---------
|
||||||
|
|
||||||
|
- fix paste
|
||||||
|
- make the c programs less buggy and let them not suck as much
|
|
@ -0,0 +1,247 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,206 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,286 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#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++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import httplib2
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
|
||||||
|
# fun fact: i got bored so made this on a southwest flight
|
||||||
|
|
||||||
|
while True:
|
||||||
|
request = httplib2.Http()
|
||||||
|
# you have to look in the network tab in 'inspect element', and find the '_' parameter, and paste that in
|
||||||
|
# of course, you have to be connected to southwest's onboard wifi
|
||||||
|
_param = "fill this in"
|
||||||
|
data = request.request("https://getconnected.southwestwifi.com/fp3d_fcgi-php/portal/public/index.php?_url=/index/getFile&path=last&_=" + _param)
|
||||||
|
data = json.loads(data[1])
|
||||||
|
print("-- Update --")
|
||||||
|
print("Nautical Miles: " + str(data["distanceToDestinationNauticalMiles"]))
|
||||||
|
print("Phase: " + data["presentPhase"])
|
||||||
|
print("Speed: " + str(data["groundSpeedKnots"]) + "kts")
|
||||||
|
seconds = data['timeToDestination']
|
||||||
|
minutes = math.floor(seconds / 60)
|
||||||
|
seconds = seconds % 60
|
||||||
|
print("Minutes: " + str(minutes) + " Seconds: " + str(seconds))
|
||||||
|
print("Flight Number: " + data["flightNumber"] + " Registration: " + data["tailNumber"])
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
print('\033[H\033[2J')
|
|
@ -0,0 +1,32 @@
|
||||||
|
.TH COLORS 1 colors
|
||||||
|
.SH NAME
|
||||||
|
colors \- generate colorscheme and run hooks
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B colors [-hefc] [-w path]
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B -h
|
||||||
|
disable running hooks (implies -e)
|
||||||
|
.TP
|
||||||
|
.B -e
|
||||||
|
echo colors to stdout
|
||||||
|
.TP
|
||||||
|
.B -c
|
||||||
|
check colors using color checking algorithm
|
||||||
|
.TP
|
||||||
|
.B -f
|
||||||
|
print wallpaper filename to stdout
|
||||||
|
.TP
|
||||||
|
.B -w
|
||||||
|
provide wallpaper path
|
||||||
|
.SH HOOKS
|
||||||
|
When -h is not used, a program at ~/.config/cwal/handler is executed. The first sixteen arguments are the colors in the colorscheme, and the seventeenth argument is the filename.
|
||||||
|
.SH EXIT CODES
|
||||||
|
.TP
|
||||||
|
.B 0
|
||||||
|
Normal exit code
|
||||||
|
.TP
|
||||||
|
.B 1
|
||||||
|
check_colors(...) failed.
|
||||||
|
.SH AUTHOR
|
||||||
|
randomuser
|
|
@ -0,0 +1,11 @@
|
||||||
|
.TH RNDUTILS 1 rndutils
|
||||||
|
.SH NAME
|
||||||
|
rndutils \- simple shell script utilities
|
||||||
|
.SH INSTALLATION
|
||||||
|
.B make install
|
||||||
|
.SH LICENSE
|
||||||
|
The author, randomuser (randomuser at tilde dot club) hereby
|
||||||
|
releases the software in this distribution and all
|
||||||
|
accompanying texts into the public domain, thereby relieving
|
||||||
|
him of any warranty of any kind.
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
.TH TIMER 1 timer
|
||||||
|
.SH NAME
|
||||||
|
timer \- simple command line timer program
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B timer [-evdbft] [-h int] [-m int] [-s int]
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B -e
|
||||||
|
enable usage of vt100 escape sequences for timer rendering (overrides -v)
|
||||||
|
.TP
|
||||||
|
.B -v
|
||||||
|
enable printing of timer status
|
||||||
|
.TP
|
||||||
|
.B -d
|
||||||
|
count down; when timer reaches 00:00, finish (use -h, -m, -s to set ending time)
|
||||||
|
.TP
|
||||||
|
.B -b
|
||||||
|
ASCII BEL when timer finish state reached
|
||||||
|
.TP
|
||||||
|
.B -f
|
||||||
|
timer display contains hour slot
|
||||||
|
.TP
|
||||||
|
.B -t
|
||||||
|
use a tomato timer (use -h, -m, -s to set work cycle time, rest cycle time is assumed to be half of the working time)
|
||||||
|
.TP
|
||||||
|
.B -p
|
||||||
|
disable pausing after finishing tomato timer cycle (required -t to work)
|
||||||
|
.TP
|
||||||
|
.B -z
|
||||||
|
enable build-specific runtime settings (default -ebf)
|
||||||
|
.TP
|
||||||
|
.B "-h int"
|
||||||
|
specify number of hours for timer parameters
|
||||||
|
.TP
|
||||||
|
.B "-m int"
|
||||||
|
specify number of minutes for timer parameters
|
||||||
|
.TP
|
||||||
|
.B "-s int"
|
||||||
|
specify number of seconds for timer parameters
|
||||||
|
.SH INTERACTIVE USAGE
|
||||||
|
.TP
|
||||||
|
.B pausing
|
||||||
|
a timer is paused when an astrisk prefixes the display (with -e) and/or when the timer ceases to update, e.g. count up or down. you can use the enter key to pause/unpause it (refer to the below example)
|
||||||
|
.nf
|
||||||
|
$ timer -e
|
||||||
|
* 05:45
|
||||||
|
.fi
|
||||||
|
.TP
|
||||||
|
.B stopping a timer
|
||||||
|
should you wish to stop a timer prematurely, or a timer which has no specified end condition, you may press the key combination that sends a killing signal to the program (e.g. a la SIGTERM) in your shell, which is usually ^C. the timer has no major places to clean up. however, memory leaks might occur on some operating systems due to no free()ing of resources.
|
||||||
|
.SH EXIT CODES/TERMINATION SIGNALS
|
||||||
|
.TP
|
||||||
|
.B 0
|
||||||
|
timer finished successfully
|
||||||
|
.TP
|
||||||
|
.B 1 / SIGABRT
|
||||||
|
error parsing arguments
|
||||||
|
.SH EXAMPLES
|
||||||
|
.B start a ten minute timer, counting up:
|
||||||
|
.nf
|
||||||
|
$ timer -m 10
|
||||||
|
.fi
|
||||||
|
.B show the vt100 interface, too:
|
||||||
|
.nf
|
||||||
|
$ timer -em 10
|
||||||
|
.fi
|
||||||
|
.B start a one hour sixty-two minute fourty-nine second timer counting down (with vt100 interface):
|
||||||
|
.nf
|
||||||
|
$ timer -edh 1 -m 62 -s 49
|
||||||
|
.fi
|
||||||
|
.B start a tomato timer with a work interval of fourty minutes and a rest interval of twenty minutes:
|
||||||
|
.nf
|
||||||
|
$ timer -etm 40
|
||||||
|
.fi
|
||||||
|
.SH REQUIRED HEADERS
|
||||||
|
.nf
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <string.h>
|
||||||
|
.fi
|
||||||
|
.SH BUGS
|
||||||
|
- when passing -p each tomato timer cycle is cut short one second
|
||||||
|
send email to random user at-sign tilde dot club
|
||||||
|
.SH AUTHOR
|
||||||
|
randomuser
|
|
@ -0,0 +1,30 @@
|
||||||
|
.TH TRSS 1 trss
|
||||||
|
.SH NAME
|
||||||
|
trss \- command oriented feed reader powered by sfeed
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B trss
|
||||||
|
.SH INTERFACE
|
||||||
|
.TP
|
||||||
|
.B ls
|
||||||
|
list all feed names in the 'feed home', or within a feed, list all items within
|
||||||
|
.TP
|
||||||
|
.B cd
|
||||||
|
focus another feed. in order to go back to the 'feed home', use 'cd' or 'cd ..'
|
||||||
|
.TP
|
||||||
|
.B sync
|
||||||
|
with no arguments and in the 'feed home', syncs all feeds. if in a specific feed, syncs that feed. a feed can be specified in an argument.
|
||||||
|
.TP
|
||||||
|
.B cat
|
||||||
|
open all feeds whose titles contain text as specified by an argument in 'lynx'
|
||||||
|
|
||||||
|
.SH trss-yt-id
|
||||||
|
this script is designed to allow one to obtain an rss feed for the uploads of a youtube channel. this command takes the homepage of the youtube channel in question as an argument and then returns the rss feed for that channel.
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
- when in a feed, you can't cd to another directly, you must go to to the 'feed home' and then cd
|
||||||
|
|
||||||
|
.SH DEPENDS
|
||||||
|
sfeed
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
randomuser <random user at tilde dot club>
|
|
@ -0,0 +1,10 @@
|
||||||
|
.TH XGETNEWWINDOW 1 xgetnewwindow
|
||||||
|
.SH NAME
|
||||||
|
xgetnewwindow
|
||||||
|
.SH SYNOPSIS
|
||||||
|
xgetnewwindow blocks until it recieves a CreateNotify event; that is, until a new window is created within the current Xorg instance. Once a new window is created, xgetnewwindow prints the window id (in hexadecimal) to stdout and exits.
|
||||||
|
.SH EXIT CODES
|
||||||
|
1 for abnormal termination, 0 for success.
|
||||||
|
.SH AUTHOR
|
||||||
|
randomuser
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
brightness=$(printf "250\n500\n1000\n2000\n3000\n4000\n" | tmenu)
|
||||||
|
st -c st-gpg-menu -e sh -c "sudo sh -c \"echo $brightness >> /sys/class/backlight/intel_backlight/brightness\""
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
gaps="$(bspc config top_padding)"
|
||||||
|
|
||||||
|
if [ "$gaps" -eq 20 ]; then
|
||||||
|
bspc config window_gap 0
|
||||||
|
bspc config top_padding 18
|
||||||
|
else
|
||||||
|
bspc config window_gap 3
|
||||||
|
bspc config top_padding 20
|
||||||
|
fi
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# get screen info and temporary file
|
||||||
|
tmp=$(mktemp)
|
||||||
|
res=$(xrandr |
|
||||||
|
grep ' connected' |
|
||||||
|
awk -F' ' '{print $1 " " $4}' |
|
||||||
|
awk -F'+' '{print $1}' |
|
||||||
|
fzy |
|
||||||
|
awk -F' ' '{print $2}' )
|
||||||
|
|
||||||
|
# still or motion
|
||||||
|
medium=$(printf ".mp4\n.png\n" | fzy)
|
||||||
|
output="$tmp$medium"
|
||||||
|
|
||||||
|
# capture
|
||||||
|
case "$medium" in
|
||||||
|
*mp4*)
|
||||||
|
printf "> starting video capture...\n"
|
||||||
|
ffmpeg -video_size "$res" -f x11grab -framerate 60 -i $DISPLAY -preset ultrafast -pix_fmt yuv420p "$output"
|
||||||
|
;;
|
||||||
|
*png*)
|
||||||
|
printf "> taking screenshot...\n"
|
||||||
|
# for a screenshot, we usually want an a s t h e t i c
|
||||||
|
ffmpeg -f x11grab -video_size "$res" -i $DISPLAY -vframes 1 "$output" -loglevel quiet # be quiet
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf "not a choice\n"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
# what to do with the capture?
|
||||||
|
printf "> written to %s\n" "$output"
|
||||||
|
while true; do
|
||||||
|
result=$(printf "delete\nmove to home directory\nupload to pastebin\nreview footage\nquit\n" | fzy --prompt="what next? ")
|
||||||
|
case "$result" in
|
||||||
|
*upload*)
|
||||||
|
paste "$output" | xclip -i
|
||||||
|
printf "> pasted! check your clipboard\n"
|
||||||
|
;;
|
||||||
|
*review*)
|
||||||
|
[ "$medium" = ".mp4" ] && mpv "$output" && continue
|
||||||
|
feh "$output"
|
||||||
|
;;
|
||||||
|
*delete*)
|
||||||
|
printf "> removing target file...\n"
|
||||||
|
rm "$output"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*home*)
|
||||||
|
printf "> warping your capture to home...\n"
|
||||||
|
name=$(echo "capture$medium" | fzy --prompt="name please? ")
|
||||||
|
mv "$output" "$HOME/$name"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*quit*)
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sel="$(find -L ~/.config 2>/dev/null | fzy)"
|
||||||
|
[ "$?" -eq 1 ] && exit 1
|
||||||
|
|
||||||
|
nvim "$sel"
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ "$(pgrep -c NetworkManager)" -eq 1 ] &&
|
||||||
|
printf "NetworkManager is already running!\n" &&
|
||||||
|
exit
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
"c"*)
|
||||||
|
wpa_supplicant -iwlp3s0 -c/etc/wpa_supplicant/wpa_supplicant.conf -B
|
||||||
|
dhcpcd wlp3s0
|
||||||
|
# make tor and nohup shut up in a posix-compliant way
|
||||||
|
nohup tor >/dev/null 2>&1
|
||||||
|
;;
|
||||||
|
"d"*)
|
||||||
|
killall -15 wpa_supplicant dhcpcd tor
|
||||||
|
;;
|
||||||
|
"r"*)
|
||||||
|
sh "$0" d
|
||||||
|
sh "$0" c
|
||||||
|
;;
|
||||||
|
"t"*)
|
||||||
|
[ "$(pgrep -c wpa_supplicant)" -eq 1 ] && sh "$0" d && exit
|
||||||
|
sh "$0" c
|
||||||
|
;;
|
||||||
|
"l"*)
|
||||||
|
iw dev wlp3s0 scan | \
|
||||||
|
grep 'SSID\|signal' | \
|
||||||
|
grep -v 'SSID List' | \
|
||||||
|
awk -F': ' '{print $2}' | \
|
||||||
|
sed 'N;s/\n/ /' | \
|
||||||
|
grep -v '\x00'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "
|
||||||
|
simple wrapper for connecting to a network
|
||||||
|
${0} toggle to toggle wifi connection
|
||||||
|
${0} restart to restart wifi
|
||||||
|
${0} disconnect to disconnect
|
||||||
|
${0} connect to connect to network
|
||||||
|
${0} list to list networks
|
||||||
|
"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
exit 0
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
chromium --app=https://discord.com/login --profile-directory="Profile 1"
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
exists() {
|
||||||
|
xrandr | grep ' connected' | grep -c "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
bspc monitor -d 1 2 3 4 5 6 7 8 9
|
||||||
|
|
||||||
|
if [ "$(exists "HDMI-2")" -eq 1 ] && [ "$(exists "LVDS-1")" -eq 1 ]; then
|
||||||
|
printf "two"
|
||||||
|
xrandr --output HDMI-2 --right-of LVDS-1 --auto
|
||||||
|
xrandr --output VGA-1 --off --auto
|
||||||
|
bspc monitor LVDS-1 -d 1 2 3 4 5 6 7 8 9
|
||||||
|
bspc monitor HDMI-2 -d 1 2 3 4 5 6 7 8 9
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(exists "HDMI-1")" -eq 1 ] && [ "$(exists "LVDS-1")" -eq 1 ]; then
|
||||||
|
printf "two"
|
||||||
|
xrandr --output HDMI-1 --right-of LVDS-1 --auto
|
||||||
|
xrandr --output VGA-1 --off --auto
|
||||||
|
bspc monitor LVDS-1 -d 1 2 3 4 5 6 7 8 9
|
||||||
|
bspc monitor HDMI-1 -d 1 2 3 4 5 6 7 8 9
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# default configuration's fine
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
HOME="/home/usr/.local/share/firefox" firefox "$@"
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# wrapper script to make firefox suck less
|
||||||
|
|
||||||
|
RHOME="${HOME}"
|
||||||
|
|
||||||
|
firefox_data_location="$HOME/firefoxdumpster"
|
||||||
|
[ -z "$3" ] || url="$3"
|
||||||
|
|
||||||
|
# start a profile chooser
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
profile=$(printf "programming\nschool\ntmp-school\ntmp\nchromium\n" | tmenu)
|
||||||
|
else
|
||||||
|
profile="$2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -z "$profile" ] && exit
|
||||||
|
|
||||||
|
if [ "$profile" = "tmp" ]; then
|
||||||
|
# firefox doesn't start in a directory within /tmp
|
||||||
|
# so we create one in $HOME/.cache
|
||||||
|
|
||||||
|
tmp=$(basename $(mktemp))
|
||||||
|
mkdir -p "${RHOME}/.cache/${tmp}"
|
||||||
|
rm -r "/tmp/$tmp"
|
||||||
|
HOME="/home/$(whoami)/.local/share/firefox" firefox --profile "${RHOME}/.cache/${tmp}" --no-remote "$url"
|
||||||
|
rm -r "${RHOME}/.cache/${tmp}"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$profile" = "chromium" ]; then
|
||||||
|
HOME="/home/$(whoami)/.local/share/firefox" chromium
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# start firefox
|
||||||
|
mkdir -p "${firefox_data_location}/profile"
|
||||||
|
HOME="/home/$(whoami)/.local/share/firefox" firefox --profile "${firefox_data_location}/${profile}" --no-remote "$url"
|
||||||
|
exit
|
||||||
|
|
||||||
|
printf "failed to specify a profile. exiting.\n"
|
||||||
|
exit 1
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
printf "password=%s\n" "$(pash s tildegit)"
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/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
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
setxkbmap -option caps:super
|
||||||
|
killall xcape
|
||||||
|
xcape -e 'Super_L=Escape'
|
||||||
|
xset -q | grep "Caps Lock:\s*on" && xdotool key Caps_Lock
|
||||||
|
xset r rate 200 40
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
host="$(hostname)"
|
||||||
|
|
||||||
|
case "$host" in
|
||||||
|
"mlg")
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
"toaster")
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
"fish")
|
||||||
|
exit 3
|
||||||
|
;;
|
||||||
|
"think")
|
||||||
|
exit 4
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# designed to be called from sxhkd (x session)
|
||||||
|
|
||||||
|
pgrep NetworkManager && st -e nmtui
|
|
@ -0,0 +1,104 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ -z "${XDG_CONFIG_DIR}" ] && XDG_CONFIG_DIR="${HOME}/.config"
|
||||||
|
[ -z "${NWS_CONFIG}" ] && NWS_CONFIG="${XDG_CONFIG_DIR}/nws"
|
||||||
|
[ -n "${NWS_ZONE}" ] || \
|
||||||
|
[ -e "${NWS_CONFIG}" ] && NWS_ZONE=$(cat "${NWS_CONFIG}") ||
|
||||||
|
NWS_ZONE="KGYX"
|
||||||
|
[ -z "${NWS_GIF}" ] && NWS_GIF="mpv --loop"
|
||||||
|
[ -z "${NWS_TORIFY}" ] && NWS_TORIFY=""
|
||||||
|
|
||||||
|
|
||||||
|
info () {
|
||||||
|
printf %s "\
|
||||||
|
nws - wrapper for the National Weather Service's website
|
||||||
|
|
||||||
|
=> [n]ational - View national weather mosaic
|
||||||
|
=> [l]ocal - View local weather mosaic
|
||||||
|
=> [r]ivers - View local river conditions
|
||||||
|
=> [w]eather - View local weather observations
|
||||||
|
=> [m]osaic [id] - View a given area's weather mosaic
|
||||||
|
=> [s]et [id] - Set local zone
|
||||||
|
=> [t]ext [id] - View text messages by catagory
|
||||||
|
|
||||||
|
Default zone: export NWS_ZONE=<zone>
|
||||||
|
GIF player: export NWS_GIF=<command>
|
||||||
|
Configuration: export NWS_CONFIG=<file>
|
||||||
|
Torify wrapper: export NWS_TORIFY=<command>
|
||||||
|
"
|
||||||
|
}
|
||||||
|
err () {
|
||||||
|
printf "err: %s\n" "${1}"
|
||||||
|
[ -z "${2}" ] && exit 1
|
||||||
|
exit "${2}"
|
||||||
|
}
|
||||||
|
kstrip () {
|
||||||
|
printf %s "$1" | sed 's/^K\(.*\)/\1/'
|
||||||
|
}
|
||||||
|
national () {
|
||||||
|
mosaic CONUS-LARGE
|
||||||
|
}
|
||||||
|
# name interestingly to avoid keyword collision
|
||||||
|
localradar () {
|
||||||
|
mosaic ${NWS_ZONE}
|
||||||
|
}
|
||||||
|
mosaic () {
|
||||||
|
${NWS_GIF} "https://radar.weather.gov/ridge/standard/${1}_loop.gif"
|
||||||
|
}
|
||||||
|
setzone () {
|
||||||
|
printf "%s" "${1}" > "${NWS_CONFIG}"
|
||||||
|
}
|
||||||
|
river () {
|
||||||
|
textmessage "RVA"
|
||||||
|
}
|
||||||
|
weather () {
|
||||||
|
textmessage "ZFP"
|
||||||
|
}
|
||||||
|
textmessage () {
|
||||||
|
curl --silent --fail "https://forecast.weather.gov/product.php?site=NWS&issuedby=$(kstrip ${NWS_ZONE})&product=${1}&format=TXT&version=1" | \
|
||||||
|
sed -n '/<!-- \/\/ CONTENT STARTS HERE -->/,/<\/pre>/p' | \
|
||||||
|
grep -v "a href" | \
|
||||||
|
grep -v '<!-- // CONTENT STARTS HERE -->' | \
|
||||||
|
grep -v '<\/pre>' || \
|
||||||
|
printf "${1} data not found for zone %s" ${NWS_ZONE}
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
"n"*)
|
||||||
|
national
|
||||||
|
;;
|
||||||
|
"l"*)
|
||||||
|
localradar
|
||||||
|
;;
|
||||||
|
"r"*)
|
||||||
|
river
|
||||||
|
;;
|
||||||
|
"w"*)
|
||||||
|
weather
|
||||||
|
;;
|
||||||
|
"m"*)
|
||||||
|
if [ "$#" -eq 2 ]; then
|
||||||
|
mosaid "$2"
|
||||||
|
else
|
||||||
|
err "two args required"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"s"*)
|
||||||
|
if [ "$#" -eq 2 ]; then
|
||||||
|
setzone "$2"
|
||||||
|
else
|
||||||
|
err "two args required"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"t"*)
|
||||||
|
if [ "$#" -eq 2 ]; then
|
||||||
|
textmessage "$2"
|
||||||
|
else
|
||||||
|
err "two args required"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
info
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
exit 0
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sel="$(pash l | tmenu)"
|
||||||
|
[ "$?" -eq 1 ] && exit 0
|
||||||
|
|
||||||
|
# requires bspc rule -a st-gpg-menu state=floating
|
||||||
|
st -c st-gpg-menu -e pash-dmenu-backend "$sel"
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
pash c "$1"
|
||||||
|
bspc node -d '^9'
|
||||||
|
sleep 15
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ "$1" = "" ] && exit 1
|
||||||
|
[ -f "$1" ] && curl -F"file=@${1}" https://0x0.st && exit 0
|
|
@ -0,0 +1,88 @@
|
||||||
|
#!/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
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ -z "$1" ] && exit 1
|
||||||
|
[ -z "$2" ] && exit 1
|
||||||
|
|
||||||
|
printf "[info] this utility is used for adding youtube urls as rss feeds\n"
|
||||||
|
|
||||||
|
feed="$(curl "$1" -s | \
|
||||||
|
grep 'youtube/www\.youtube\.com/channel/.\{24\}' -o | \
|
||||||
|
awk -F'/' '{print "https://www.youtube.com/feeds/videos.xml?channel_id=" $NF}' | \
|
||||||
|
sed 1q)"
|
||||||
|
|
||||||
|
[ -z "$feed" ] && printf "[err] error processing the feed. are you sure it's *www*.youtube.com and not youtube.com?\n" && exit 1
|
||||||
|
|
||||||
|
sfeedrc="$HOME/.config/sfeed/sfeedrc"
|
||||||
|
|
||||||
|
ed "$sfeedrc" <<EOF
|
||||||
|
/feeds
|
||||||
|
a
|
||||||
|
feed "$2" "$feed"
|
||||||
|
.
|
||||||
|
w
|
||||||
|
EOF
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# opens snapcad
|
||||||
|
|
||||||
|
wine ~/.wine/drive_c/Program\ Files\ \(x86\)/VEX\ Robotics/SnapCAD/SnapCAD.exe
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/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"
|
|
@ -0,0 +1,100 @@
|
||||||
|
#!/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
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/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
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
file=$(mktemp)
|
||||||
|
cat - > "$file"
|
||||||
|
|
||||||
|
st -c tmenu-prompt -g 40x10+0+0 -e tmenu-backend "$file"
|
||||||
|
cat "$file"
|
||||||
|
rm "$file"
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
printf "%s" "$1"
|
||||||
|
|
||||||
|
fzy < "$1" > "${1}a"
|
||||||
|
mv "${1}a" "${1}"
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
tmenu_path () {
|
||||||
|
IFS=" :"
|
||||||
|
for i in $PATH; do
|
||||||
|
for j in "$i"/*; do
|
||||||
|
[ -f "$j" ] && [ -x "$j" ] && printf "%s\n" "$j" | xargs basename
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$1" = "-g" ] || [ "$(basename $0)" = "regenerate" ]; then
|
||||||
|
mkdir -p $HOME/.local/share
|
||||||
|
tmenu_path > $HOME/.local/share/tmenu_cache
|
||||||
|
xmessage "regeneration complete"
|
||||||
|
else
|
||||||
|
cat $HOME/.local/share/tmenu_cache | tmenu | ${SHELL:-"/bin/sh"} &
|
||||||
|
fi
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
pid=$(pgrep sxhkd)
|
||||||
|
|
||||||
|
for i in $pid; do
|
||||||
|
inv_id=$(cat /proc/$i/cmdline | awk -F'\0' '{print $3}')
|
||||||
|
|
||||||
|
echo $inv_id
|
||||||
|
[ -z "$inv_id" ] && contingency_mode="off"
|
||||||
|
[ "$inv_id" = *"contingency" ] && contingency_mode="on"
|
||||||
|
done
|
||||||
|
|
||||||
|
killall sxhkd
|
||||||
|
|
||||||
|
trackpoint=$(xinput | grep "TrackPoint" | awk -F'\t' '{print $2}' | awk -F'=' '{print $2}')
|
||||||
|
touchpad=$(xinput | grep "TouchPad" | awk -F'\t' '{print $2}' | awk -F'=' '{print $2}')
|
||||||
|
|
||||||
|
if [ "$contingency_mode" = "off" ]; then
|
||||||
|
sxhkd -c $HOME/.config/sxhkd/contingency &
|
||||||
|
xinput disable "$trackpoint"
|
||||||
|
xinput disable "$touchpad"
|
||||||
|
xmessage "contingency mode enabled."
|
||||||
|
else
|
||||||
|
sxhkd &
|
||||||
|
xinput enable "$trackpoint"
|
||||||
|
xinput enable "$touchpad"
|
||||||
|
killall xmessage
|
||||||
|
fi
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# when the vim SwapExists autocommand is fired, this script is
|
||||||
|
# called with the path of the file in question.
|
||||||
|
|
||||||
|
# mad props to daniel conway for having this big brain idea
|
||||||
|
|
||||||
|
# note to self: protect $1 from expansion as it can contain a
|
||||||
|
# ~
|
||||||
|
|
||||||
|
[ "$#" -eq 0 ] && exit 2
|
||||||
|
|
||||||
|
window=$(
|
||||||
|
xdotool search --name "$1" | \
|
||||||
|
sed 1q
|
||||||
|
)
|
||||||
|
|
||||||
|
desk=$(
|
||||||
|
xdotool get_desktop_for_window "$window" 2>/dev/null || printf "none"
|
||||||
|
)
|
||||||
|
|
||||||
|
[ "$desk" = "none" ] && exit 1
|
||||||
|
desk=$((desk + 1))
|
||||||
|
|
||||||
|
bspc desktop -f "^${desk}"
|
||||||
|
killall -10 simplestatus
|
||||||
|
xdotool set_window --urgency 1 "$window"
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/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
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
WALLDIR="${HOME}/.local/share/wallpapers"
|
||||||
|
BASECMD="feh --no-fehbg --bg-fill"
|
||||||
|
|
||||||
|
generate_wall () {
|
||||||
|
GENWALL=$( \
|
||||||
|
ls "$WALLDIR" | \
|
||||||
|
grep "." | \
|
||||||
|
shuf -n 1
|
||||||
|
)
|
||||||
|
GENWALL="${WALLDIR}/${GENWALL}"
|
||||||
|
}
|
||||||
|
wall () {
|
||||||
|
generate_wall
|
||||||
|
while [ "${GENWALL}" = "${1}" ]; do
|
||||||
|
generate_wall
|
||||||
|
done
|
||||||
|
}
|
||||||
|
displays () {
|
||||||
|
displays=$(xrandr | grep -c ' connected')
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd=""
|
||||||
|
displays
|
||||||
|
for i in $(seq 1 "$displays"); do
|
||||||
|
wall "${tmp}"
|
||||||
|
tmp="${GENWALL}"
|
||||||
|
cmd="${cmd} ${GENWALL}"
|
||||||
|
done
|
||||||
|
eval "${BASECMD}" "${cmd}"
|
||||||
|
exit 0
|
Loading…
Reference in New Issue