commit 44105f2dd7a18fd072cf01ce531e037d28a72759
parent 6afcf9a0cbc0c63f8a1be4839663803063c101a6
Author: Alexander Nortung <alexander.nortung@oakdigital.dk>
Date: Mon, 8 Apr 2024 23:56:55 +0200
Added slock multi shapes patch
Diffstat:
2 files changed, 212 insertions(+), 0 deletions(-)
diff --git a/tools.suckless.org/slock/patches/multi-shapes/index.md b/tools.suckless.org/slock/patches/multi-shapes/index.md
@@ -0,0 +1,26 @@
+Multi Shapes
+============
+
+Description
+-----------
+The same as the [Squares patch](../squares/), but will render a shape for each character in the input.
+
+> Instead of changing the color of the entire screen to indicate the current lock
+> state, draw centered squares on each monitor and change the square colors.
+>
+> This patch requires xrandr to be active and otherwise defaults to the original
+> slock behavior.
+
+Config
+------
+* `squareshape`: `0` for squares `1` for circles
+* `squaresize`: The size of the shapes in px
+* `squaregap`: The gap between the shapes
+
+Download
+--------
+* [slock-multi-shapes-1.5.diff](slock-multi-shapes-1.5.diff)
+
+Authors
+-------
+* Alexander Nortung <alex_nortung@live.dk>
diff --git a/tools.suckless.org/slock/patches/multi-shapes/slock-multi-shapes-1.5.diff b/tools.suckless.org/slock/patches/multi-shapes/slock-multi-shapes-1.5.diff
@@ -0,0 +1,186 @@
+diff --git a/config.def.h b/config.def.h
+index 9855e21..e681e8b 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -3,10 +3,21 @@ static const char *user = "nobody";
+ static const char *group = "nogroup";
+
+ static const char *colorname[NUMCOLS] = {
+- [INIT] = "black", /* after initialization */
++ [BG] = "black", /* background */
++ [INIT] = "#4f525c", /* after initialization */
+ [INPUT] = "#005577", /* during input */
+ [FAILED] = "#CC3333", /* wrong password */
+ };
+
+ /* treat a cleared input like a wrong password (color) */
+ static const int failonclear = 1;
++
++/*
++* Shapes:
++* 0: square
++* 1: circle
++*/
++static const int shape = 0;
++/* size of square in px */
++static const int shapesize = 50;
++static const int shapegap = 35;
+diff --git a/slock.c b/slock.c
+index b2f14e3..501b3be 100644
+--- a/slock.c
++++ b/slock.c
+@@ -25,6 +25,7 @@
+ char *argv0;
+
+ enum {
++ BG,
+ INIT,
+ INPUT,
+ FAILED,
+@@ -36,6 +37,8 @@ struct lock {
+ Window root, win;
+ Pixmap pmap;
+ unsigned long colors[NUMCOLS];
++ GC gc;
++ XRRScreenResources *rrsr;
+ };
+
+ struct xrandr {
+@@ -124,13 +127,69 @@ gethash(void)
+ return hash;
+ }
+
++static void
++draw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
++ unsigned int color, unsigned int len)
++{
++ int screen, crtc;
++ XRRCrtcInfo* rrci;
++
++ if (rr->active) {
++ for (screen = 0; screen < nscreens; screen++) {
++ XSetWindowBackground(dpy, locks[screen]->win,locks[screen]->colors[BG]);
++ XClearWindow(dpy, locks[screen]->win);
++ XSetForeground(dpy, locks[screen]->gc, locks[screen]->colors[color]);
++ for (crtc = 0; crtc < locks[screen]->rrsr->ncrtc; ++crtc) {
++ rrci = XRRGetCrtcInfo(dpy,
++ locks[screen]->rrsr,
++ locks[screen]->rrsr->crtcs[crtc]);
++ /* skip disabled crtc */
++ if (rrci->noutput > 0) {
++ int leftBound = rrci->x + (rrci->width - len * shapesize - (len - 1) * shapegap) / 2;
++ for (int shapei = 0; shapei < len; shapei++) {
++ int x = leftBound + shapei * (shapesize + shapegap);
++ if (shape == 0) {
++ XFillRectangle(dpy,
++ locks[screen]->win,
++ locks[screen]->gc,
++ x,
++ rrci->y + (rrci->height - shapesize) / 2,
++ shapesize,
++ shapesize);
++ } else if (shape == 1) {
++ XFillArc(dpy,
++ locks[screen]->win,
++ locks[screen]->gc,
++ x,
++ rrci->y + (rrci->height - shapesize) / 2,
++ shapesize,
++ shapesize,
++ 0,
++ 360 * 64);
++ }
++ }
++
++ }
++ XRRFreeCrtcInfo(rrci);
++ }
++ }
++ } else {
++ for (screen = 0; screen < nscreens; screen++) {
++ XSetWindowBackground(dpy,
++ locks[screen]->win,
++ locks[screen]->colors[color]);
++ XClearWindow(dpy, locks[screen]->win);
++ }
++ }
++}
++
+ static void
+ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ const char *hash)
+ {
+ XRRScreenChangeNotifyEvent *rre;
+ char buf[32], passwd[256], *inputhash;
+- int num, screen, running, failure, oldc;
++ int num, screen, running, failure, oldc, oldlen;
+ unsigned int len, color;
+ KeySym ksym;
+ XEvent ev;
+@@ -139,6 +198,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ running = 1;
+ failure = 0;
+ oldc = INIT;
++ oldlen = 0;
+
+ while (running && !XNextEvent(dpy, &ev)) {
+ if (ev.type == KeyPress) {
+@@ -188,14 +248,14 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
+ break;
+ }
+ color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
+- if (running && oldc != color) {
+- for (screen = 0; screen < nscreens; screen++) {
+- XSetWindowBackground(dpy,
+- locks[screen]->win,
+- locks[screen]->colors[color]);
+- XClearWindow(dpy, locks[screen]->win);
++ if (running && (oldc != color || oldlen != len)) {
++ int lenToUse = len;
++ if (lenToUse < 1) {
++ lenToUse = 1;
+ }
++ draw(dpy, rr, locks, nscreens, color, lenToUse);
+ oldc = color;
++ oldlen = len;
+ }
+ } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
+ rre = (XRRScreenChangeNotifyEvent*)&ev;
+@@ -228,6 +288,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
+ XColor color, dummy;
+ XSetWindowAttributes wa;
+ Cursor invisible;
++ XGCValues gcvalues;
+
+ if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
+ return NULL;
+@@ -243,7 +304,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
+
+ /* init */
+ wa.override_redirect = 1;
+- wa.background_pixel = lock->colors[INIT];
++ wa.background_pixel = lock->colors[BG];
+ lock->win = XCreateWindow(dpy, lock->root, 0, 0,
+ DisplayWidth(dpy, lock->screen),
+ DisplayHeight(dpy, lock->screen),
+@@ -255,6 +316,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
+ invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap,
+ &color, &color, 0, 0);
+ XDefineCursor(dpy, lock->win, invisible);
++ lock->gc = XCreateGC(dpy, lock->win, 0, &gcvalues);
++ XSetForeground(dpy, lock->gc, lock->colors[INIT]);
++ if (rr->active)
++ lock->rrsr = XRRGetScreenResourcesCurrent(dpy, lock->root);
+
+ /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
+ for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) {
+@@ -388,6 +453,9 @@ main(int argc, char **argv) {
+ }
+ }
+
++ /* draw the initial rectangle */
++ draw(dpy, &rr, locks, nscreens, INIT, 1);
++
+ /* everything is now blank. Wait for the correct password */
+ readpw(dpy, &rr, locks, nscreens, hash);
+