slock

fork of slock
git clone git://popovic.xyz/slock.git
Log | Files | Refs | README | LICENSE

commit bf2c85aa117c26a20d3282acdfe268cdd91c0a21
parent df4429ff647fa8612e70622a076a3799b016c5de
Author: Milutin Popovic <mika@popovic.xyz>
Date:   Tue, 18 Nov 2025 21:36:46 +0000

patch cleanup

Diffstat:
Dconfig.def.h.orig | 41-----------------------------------------
Dconfig.def.h.rej | 26--------------------------
Dslock.c.orig | 569-------------------------------------------------------------------------------
Dslock.c.rej | 19-------------------
4 files changed, 0 insertions(+), 655 deletions(-)

diff --git a/config.def.h.orig b/config.def.h.orig @@ -1,41 +0,0 @@ -/* user and group to drop privileges to */ -static const char *user = "mika"; -static const char *group = "mika"; - -static const char *colorname[NUMCOLS] = { - [BACKGROUND] = "white", - [INIT] = "2d2d2d", /* after initialization */ - [INPUT] = "#005577", /* during input */ - [FAILED] = "#CC3333", /* wrong password */ - [CAPS] = "red", /* CapsLock on */ -}; - -/* treat a cleared input like a wrong password (color) */ -static const int failonclear = 1; - -static const int monitortime = 5; - -static const int logosize = 75; -static const int logow = 12; /* Grid width and height for right center alignment*/ -static const int logoh = 6; - -static XRectangle rectangles[9] = { - {0, 3, 1, 3}, - {1, 3, 2, 1}, - {0, 5, 8, 1}, - {3, 0, 1, 5}, - {5, 3, 1, 2}, - {7, 3, 1, 2}, - {8, 3, 4, 1}, - {9, 4, 1, 2}, - {11,4, 1, 2}, -}; - -/*Enable blur*/ -#define BLUR -/*Set blur radius*/ -static const int blurRadius=5; -/*Enable Pixelation*/ -//#define PIXELATION -/*Set pixelation radius*/ -static const int pixelSize=0; diff --git a/config.def.h.rej b/config.def.h.rej @@ -1,26 +0,0 @@ ---- config.def.h -+++ config.def.h -@@ -3,11 +3,21 @@ static const char *user = "nobody"; - static const char *group = "nogroup"; - - static const char *colorname[NUMCOLS] = { -- [INIT] = "black", /* after initialization */ -- [INPUT] = "#005577", /* during input */ -+ [INIT] = "black", /* after initialization */ -+ [INPUT] = "#005577", /* during input */ - [FAILED] = "#CC3333", /* wrong password */ - [CAPS] = "red", /* CapsLock on */ - }; - -+/* -+ * Xresources preferences to load at startup -+ */ -+ResourcePref resources[] = { -+ { "color0", STRING, &colorname[INIT] }, -+ { "color4", STRING, &colorname[INPUT] }, -+ { "color1", STRING, &colorname[FAILED] }, -+ { "color3", STRING, &colorname[CAPS] }, -+}; -+ - /* treat a cleared input like a wrong password (color) */ - static const int failonclear = 1; diff --git a/slock.c.orig b/slock.c.orig @@ -1,569 +0,0 @@ -/* See LICENSE file for license details. */ -#define _XOPEN_SOURCE 500 -#define LENGTH(X) (sizeof X / sizeof X[0]) -#if HAVE_SHADOW_H -#include <shadow.h> -#endif - -#include <ctype.h> -#include <errno.h> -#include <grp.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <spawn.h> -#include <sys/types.h> -#include <X11/extensions/Xrandr.h> -#ifdef XINERAMA -#include <X11/extensions/Xinerama.h> -#endif -#include <X11/keysym.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/XKBlib.h> -#include <X11/Xmd.h> -#include <X11/extensions/dpms.h> - -#include <Imlib2.h> - -#include "arg.h" -#include "util.h" - -char *argv0; - -enum { - BACKGROUND, - INIT, - INPUT, - FAILED, - CAPS, - NUMCOLS -}; - -#include "config.h" - -struct lock { - int screen; - Window root, win; - Pixmap pmap; - Pixmap bgmap; - unsigned long colors[NUMCOLS]; - unsigned int x, y; - unsigned int xoff, yoff, mw, mh; - Drawable drawable; - GC gc; - XRectangle rectangles[LENGTH(rectangles)]; -}; - -struct xrandr { - int active; - int evbase; - int errbase; -}; - -Imlib_Image image; - -static void -die(const char *errstr, ...) -{ - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(1); -} - -#ifdef __linux__ -#include <fcntl.h> -#include <linux/oom.h> - -static void -dontkillme(void) -{ - FILE *f; - const char oomfile[] = "/proc/self/oom_score_adj"; - - if (!(f = fopen(oomfile, "w"))) { - if (errno == ENOENT) - return; - die("slock: fopen %s: %s\n", oomfile, strerror(errno)); - } - fprintf(f, "%d", OOM_SCORE_ADJ_MIN); - if (fclose(f)) { - if (errno == EACCES) - die("slock: unable to disable OOM killer. " - "Make sure to suid or sgid slock.\n"); - else - die("slock: fclose %s: %s\n", oomfile, strerror(errno)); - } -} -#endif - -static const char * -gethash(void) -{ - const char *hash; - struct passwd *pw; - - /* Check if the current user has a password entry */ - errno = 0; - if (!(pw = getpwuid(getuid()))) { - if (errno) - die("slock: getpwuid: %s\n", strerror(errno)); - else - die("slock: cannot retrieve password entry\n"); - } - hash = pw->pw_passwd; - -#if HAVE_SHADOW_H - if (!strcmp(hash, "x")) { - struct spwd *sp; - if (!(sp = getspnam(pw->pw_name))) - die("slock: getspnam: cannot retrieve shadow entry. " - "Make sure to suid or sgid slock.\n"); - hash = sp->sp_pwdp; - } -#else - if (!strcmp(hash, "*")) { -#ifdef __OpenBSD__ - if (!(pw = getpwuid_shadow(getuid()))) - die("slock: getpwnam_shadow: cannot retrieve shadow entry. " - "Make sure to suid or sgid slock.\n"); - hash = pw->pw_passwd; -#else - die("slock: getpwuid: cannot retrieve shadow entry. " - "Make sure to suid or sgid slock.\n"); -#endif /* __OpenBSD__ */ - } -#endif /* HAVE_SHADOW_H */ - - return hash; -} - -static void -resizerectangles(struct lock *lock) -{ - int i; - - for (i = 0; i < LENGTH(rectangles); i++){ - lock->rectangles[i].x = (rectangles[i].x * logosize) - + lock->xoff + ((lock->mw) / 2) - (logow / 2 * logosize); - lock->rectangles[i].y = (rectangles[i].y * logosize) - + lock->yoff + ((lock->mh) / 2) - (logoh / 2 * logosize); - lock->rectangles[i].width = rectangles[i].width * logosize; - lock->rectangles[i].height = rectangles[i].height * logosize; - } -} - -static void -drawlogo(Display *dpy, struct lock *lock, int color) -{ - XSetForeground(dpy, lock->gc, lock->colors[color]); - XFillRectangles(dpy, lock->win, lock->gc, lock->rectangles, LENGTH(rectangles)); - XSync(dpy, False); -} - -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 caps, num, screen, running, failure, oldc; - unsigned int len, color, indicators; - KeySym ksym; - XEvent ev; - - len = 0; - caps = 0; - running = 1; - failure = 0; - oldc = INIT; - - if (!XkbGetIndicatorState(dpy, XkbUseCoreKbd, &indicators)) - caps = indicators & 1; - - while (running && !XNextEvent(dpy, &ev)) { - if (ev.type == KeyPress) { - explicit_bzero(&buf, sizeof(buf)); - num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0); - if (IsKeypadKey(ksym)) { - if (ksym == XK_KP_Enter) - ksym = XK_Return; - else if (ksym >= XK_KP_0 && ksym <= XK_KP_9) - ksym = (ksym - XK_KP_0) + XK_0; - } - if (IsFunctionKey(ksym) || - IsKeypadKey(ksym) || - IsMiscFunctionKey(ksym) || - IsPFKey(ksym) || - IsPrivateKeypadKey(ksym)) - continue; - switch (ksym) { - case XK_Return: - passwd[len] = '\0'; - errno = 0; - if (!(inputhash = crypt(passwd, hash))) - fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); - else - running = !!strcmp(inputhash, hash); - if (running) { - XBell(dpy, 100); - failure = 1; - } - explicit_bzero(&passwd, sizeof(passwd)); - len = 0; - break; - case XK_Escape: - explicit_bzero(&passwd, sizeof(passwd)); - len = 0; - break; - case XK_BackSpace: - if (len) - passwd[--len] = '\0'; - break; - case XK_Caps_Lock: - caps = !caps; - break; - default: - if (num && !iscntrl((int)buf[0]) && - (len + num < sizeof(passwd))) { - memcpy(passwd + len, buf, num); - len += num; - } else if (buf[0] == '\025') { /* ctrl-u clears input */ - explicit_bzero(&passwd, sizeof(passwd)); - len = 0; - } - break; - } - color = len ? (caps ? CAPS : INPUT) : (failure || failonclear ? FAILED : INIT); - if (running && oldc != color) { - for (screen = 0; screen < nscreens; screen++) { - if(locks[screen]->bgmap) - XSetWindowBackgroundPixmap(dpy, locks[screen]->win, locks[screen]->bgmap); - else - XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]); - //XClearWindow(dpy, locks[screen]->win); - drawlogo(dpy, locks[screen], color); - } - oldc = color; - } - } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { - rre = (XRRScreenChangeNotifyEvent*)&ev; - for (screen = 0; screen < nscreens; screen++) { - if (locks[screen]->win == rre->window) { - if (rre->rotation == RR_Rotate_90 || - rre->rotation == RR_Rotate_270) - XResizeWindow(dpy, locks[screen]->win, - rre->height, rre->width); - else - XResizeWindow(dpy, locks[screen]->win, - rre->width, rre->height); - XClearWindow(dpy, locks[screen]->win); - break; - } - } - } else { - for (screen = 0; screen < nscreens; screen++) - XRaiseWindow(dpy, locks[screen]->win); - } - } -} - -static struct lock * -lockscreen(Display *dpy, struct xrandr *rr, int screen) -{ - char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; - int i, ptgrab, kbgrab; - struct lock *lock; - XColor color, dummy; - XSetWindowAttributes wa; - Cursor invisible; -#ifdef XINERAMA - XineramaScreenInfo *info; - int n; -#endif - - if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) - return NULL; - - lock->screen = screen; - lock->root = RootWindow(dpy, lock->screen); - - if(image) - { - lock->bgmap = XCreatePixmap(dpy, lock->root, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), DefaultDepth(dpy, lock->screen)); - imlib_context_set_image(image); - imlib_context_set_display(dpy); - imlib_context_set_visual(DefaultVisual(dpy, lock->screen)); - imlib_context_set_colormap(DefaultColormap(dpy, lock->screen)); - imlib_context_set_drawable(lock->bgmap); - imlib_render_image_on_drawable(0, 0); - imlib_free_image(); - } - for (i = 0; i < NUMCOLS; i++) { - XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), - colorname[i], &color, &dummy); - lock->colors[i] = color.pixel; - } - - lock->x = DisplayWidth(dpy, lock->screen); - lock->y = DisplayHeight(dpy, lock->screen); -#ifdef XINERAMA - if ((info = XineramaQueryScreens(dpy, &n))) { - lock->xoff = info[0].x_org; - lock->yoff = info[0].y_org; - lock->mw = info[0].width; - lock->mh = info[0].height; - } else -#endif - { - lock->xoff = lock->yoff = 0; - lock->mw = lock->x; - lock->mh = lock->y; - } - lock->drawable = XCreatePixmap(dpy, lock->root, - lock->x, lock->y, DefaultDepth(dpy, screen)); - lock->gc = XCreateGC(dpy, lock->root, 0, NULL); - XSetLineAttributes(dpy, lock->gc, 1, LineSolid, CapButt, JoinMiter); - - /* init */ - wa.override_redirect = 1; - wa.background_pixel = lock->colors[BACKGROUND]; - lock->win = XCreateWindow(dpy, lock->root, 0, 0, - lock->x, lock->y, - 0, DefaultDepth(dpy, lock->screen), - CopyFromParent, - DefaultVisual(dpy, lock->screen), - CWOverrideRedirect | CWBackPixel, &wa); - if(lock->bgmap) - XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap); - lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8); - invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, - &color, &color, 0, 0); - XDefineCursor(dpy, lock->win, invisible); - - resizerectangles(lock); - - /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ - for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { - if (ptgrab != GrabSuccess) { - ptgrab = XGrabPointer(dpy, lock->root, False, - ButtonPressMask | ButtonReleaseMask | - PointerMotionMask, GrabModeAsync, - GrabModeAsync, None, invisible, CurrentTime); - } - if (kbgrab != GrabSuccess) { - kbgrab = XGrabKeyboard(dpy, lock->root, True, - GrabModeAsync, GrabModeAsync, CurrentTime); - } - - /* input is grabbed: we can lock the screen */ - if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) { - XMapRaised(dpy, lock->win); - if (rr->active) - XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); - - XSelectInput(dpy, lock->root, SubstructureNotifyMask); - drawlogo(dpy, lock, INIT); - return lock; - } - - /* retry on AlreadyGrabbed but fail on other errors */ - if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) || - (kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess)) - break; - - usleep(100000); - } - - /* we couldn't grab all input: fail out */ - if (ptgrab != GrabSuccess) - fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", - screen); - if (kbgrab != GrabSuccess) - fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", - screen); - return NULL; -} - -static void -usage(void) -{ - die("usage: slock [-v] [cmd [arg ...]]\n"); -} - -int -main(int argc, char **argv) { - struct xrandr rr; - struct lock **locks; - struct passwd *pwd; - struct group *grp; - uid_t duid; - gid_t dgid; - const char *hash; - Display *dpy; - int s, nlocks, nscreens; - CARD16 standby, suspend, off; - BOOL dpms_state; - - ARGBEGIN { - case 'v': - puts("slock-"VERSION); - return 0; - default: - usage(); - } ARGEND - - /* validate drop-user and -group */ - errno = 0; - if (!(pwd = getpwnam(user))) - die("slock: getpwnam %s: %s\n", user, - errno ? strerror(errno) : "user entry not found"); - duid = pwd->pw_uid; - errno = 0; - if (!(grp = getgrnam(group))) - die("slock: getgrnam %s: %s\n", group, - errno ? strerror(errno) : "group entry not found"); - dgid = grp->gr_gid; - -#ifdef __linux__ - dontkillme(); -#endif - - hash = gethash(); - errno = 0; - if (!crypt("", hash)) - die("slock: crypt: %s\n", strerror(errno)); - - if (!(dpy = XOpenDisplay(NULL))) - die("slock: cannot open display\n"); - - /* drop privileges */ - if (setgroups(0, NULL) < 0) - die("slock: setgroups: %s\n", strerror(errno)); - if (setgid(dgid) < 0) - die("slock: setgid: %s\n", strerror(errno)); - if (setuid(duid) < 0) - die("slock: setuid: %s\n", strerror(errno)); - - /*Create screenshot Image*/ - Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy)); - image = imlib_create_image(scr->width,scr->height); - imlib_context_set_image(image); - imlib_context_set_display(dpy); - imlib_context_set_visual(DefaultVisual(dpy,0)); - imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr))); - imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1); - -#ifdef BLUR - - /*Blur function*/ - imlib_image_blur(blurRadius); -#endif // BLUR - -#ifdef PIXELATION - /*Pixelation*/ - int width = scr->width; - int height = scr->height; - - for(int y = 0; y < height; y += pixelSize) - { - for(int x = 0; x < width; x += pixelSize) - { - int red = 0; - int green = 0; - int blue = 0; - - Imlib_Color pixel; - Imlib_Color* pp; - pp = &pixel; - for(int j = 0; j < pixelSize && j < height; j++) - { - for(int i = 0; i < pixelSize && i < width; i++) - { - imlib_image_query_pixel(x+i,y+j,pp); - red += pixel.red; - green += pixel.green; - blue += pixel.blue; - } - } - red /= (pixelSize*pixelSize); - green /= (pixelSize*pixelSize); - blue /= (pixelSize*pixelSize); - imlib_context_set_color(red,green,blue,pixel.alpha); - imlib_image_fill_rectangle(x,y,pixelSize,pixelSize); - red = 0; - green = 0; - blue = 0; - } - } - - -#endif - /* check for Xrandr support */ - rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); - - /* get number of screens in display "dpy" and blank them */ - nscreens = ScreenCount(dpy); - if (!(locks = calloc(nscreens, sizeof(struct lock *)))) - die("slock: out of memory\n"); - for (nlocks = 0, s = 0; s < nscreens; s++) { - if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) - nlocks++; - else - break; - } - XSync(dpy, 0); - - /* did we manage to lock everything? */ - if (nlocks != nscreens) - return 1; - - /* DPMS magic to disable the monitor */ - if (!DPMSCapable(dpy)) - die("slock: DPMSCapable failed\n"); - if (!DPMSInfo(dpy, &standby, &dpms_state)) - die("slock: DPMSInfo failed\n"); - if (!DPMSEnable(dpy) && !dpms_state) - die("slock: DPMSEnable failed\n"); - if (!DPMSGetTimeouts(dpy, &standby, &suspend, &off)) - die("slock: DPMSGetTimeouts failed\n"); - if (!standby || !suspend || !off) - die("slock: at least one DPMS variable is zero\n"); - if (!DPMSSetTimeouts(dpy, monitortime, monitortime, monitortime)) - die("slock: DPMSSetTimeouts failed\n"); - - XSync(dpy, 0); - - /* run post-lock command */ - if (argc > 0) { - pid_t pid; - extern char **environ; - int err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ); - if (err) { - die("slock: failed to execute post-lock command: %s: %s\n", - argv[0], strerror(err)); - } - } - - /* everything is now blank. Wait for the correct password */ - readpw(dpy, &rr, locks, nscreens, hash); - - for (nlocks = 0, s = 0; s < nscreens; s++) { - XFreePixmap(dpy, locks[s]->drawable); - XFreeGC(dpy, locks[s]->gc); - } - - /* reset DPMS values to inital ones */ - DPMSSetTimeouts(dpy, standby, suspend, off); - if (!dpms_state) - DPMSDisable(dpy); - XSync(dpy, 0); - XCloseDisplay(dpy); - return 0; -} diff --git a/slock.c.rej b/slock.c.rej @@ -1,19 +0,0 @@ ---- slock.c -+++ slock.c -@@ -20,6 +21,7 @@ - #include <X11/Xlib.h> - #include <X11/Xutil.h> - #include <X11/XKBlib.h> -+#include <X11/Xresource.h> - - #include "arg.h" - #include "util.h" -@@ -429,6 +495,8 @@ main(int argc, char **argv) { - if (setuid(duid) < 0) - die("slock: setuid: %s\n", strerror(errno)); - -+ config_init(dpy); -+ - /* check for Xrandr support */ - rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); -