diff options
| author | TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> | 2025-02-09 03:10:22 +0900 |
|---|---|---|
| committer | TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> | 2025-02-09 03:10:22 +0900 |
| commit | 36f7b343c714566d5bf931e768f0536a12d67c2f (patch) | |
| tree | 2040321e9984b1d8191f144f6b81f05f38acb8d7 /slock | |
| parent | 365403254a39ceac9797e430d4a62ec6c7b2f99c (diff) | |
updates
Diffstat (limited to 'slock')
21 files changed, 1945 insertions, 363 deletions
diff --git a/slock/LICENSE b/slock/LICENSE index 2e4419b..cb52dba 100644 --- a/slock/LICENSE +++ b/slock/LICENSE @@ -4,6 +4,7 @@ MIT/X Consortium License © 2014 Dimitris Papastamos <sin@2f30.org> © 2006-2014 Anselm R Garbe <anselm@garbe.us> © 2014-2016 Laslo Hunhold <dev@frign.de> +© 2016-2023 Hiltjo Posthuma <hiltjo@codemadness.org> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/slock/Makefile b/slock/Makefile index b20fd4e..6d74b21 100644 --- a/slock/Makefile +++ b/slock/Makefile @@ -6,56 +6,41 @@ include config.mk SRC = slock.c ${COMPATSRC} OBJ = ${SRC:.c=.o} -all: options slock - -options: - @echo slock build options: - @echo "CFLAGS = ${CFLAGS}" - @echo "LDFLAGS = ${LDFLAGS}" - @echo "CC = ${CC}" +all: slock .c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< + ${CC} -c ${CFLAGS} $< ${OBJ}: config.h config.mk arg.h util.h config.h: - @echo creating $@ from config.def.h - @cp config.def.h $@ + cp config.def.h $@ slock: ${OBJ} - @echo CC -o $@ - @${CC} -o $@ ${OBJ} ${LDFLAGS} + ${CC} -o $@ ${OBJ} ${LDFLAGS} clean: - @echo cleaning - @rm -f slock ${OBJ} slock-${VERSION}.tar.gz + rm -f slock ${OBJ} slock-${VERSION}.tar.gz dist: clean - @echo creating dist tarball - @mkdir -p slock-${VERSION} - @cp -R LICENSE Makefile README slock.1 config.mk \ + mkdir -p slock-${VERSION} + cp -R LICENSE Makefile README slock.1 config.mk \ ${SRC} config.def.h arg.h util.h slock-${VERSION} - @tar -cf slock-${VERSION}.tar slock-${VERSION} - @gzip slock-${VERSION}.tar - @rm -rf slock-${VERSION} + tar -cf slock-${VERSION}.tar slock-${VERSION} + gzip slock-${VERSION}.tar + rm -rf slock-${VERSION} install: all - @echo installing executable file to ${DESTDIR}${PREFIX}/bin - @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f slock ${DESTDIR}${PREFIX}/bin - @chmod 755 ${DESTDIR}${PREFIX}/bin/slock - @chmod u+s ${DESTDIR}${PREFIX}/bin/slock - @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 - @mkdir -p ${DESTDIR}${MANPREFIX}/man1 - @sed "s/VERSION/${VERSION}/g" <slock.1 >${DESTDIR}${MANPREFIX}/man1/slock.1 - @chmod 644 ${DESTDIR}${MANPREFIX}/man1/slock.1 + mkdir -p ${DESTDIR}${PREFIX}/bin + cp -f slock ${DESTDIR}${PREFIX}/bin + chmod 755 ${DESTDIR}${PREFIX}/bin/slock + chmod u+s ${DESTDIR}${PREFIX}/bin/slock + mkdir -p ${DESTDIR}${MANPREFIX}/man1 + sed "s/VERSION/${VERSION}/g" <slock.1 >${DESTDIR}${MANPREFIX}/man1/slock.1 + chmod 644 ${DESTDIR}${MANPREFIX}/man1/slock.1 uninstall: - @echo removing executable file from ${DESTDIR}${PREFIX}/bin - @rm -f ${DESTDIR}${PREFIX}/bin/slock - @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 - @rm -f ${DESTDIR}${MANPREFIX}/man1/slock.1 + rm -f ${DESTDIR}${PREFIX}/bin/slock + rm -f ${DESTDIR}${MANPREFIX}/man1/slock.1 -.PHONY: all options clean dist install uninstall +.PHONY: all clean dist install uninstall diff --git a/slock/config.def.h b/slock/config.def.h new file mode 100644 index 0000000..2a8cd1b --- /dev/null +++ b/slock/config.def.h @@ -0,0 +1,98 @@ +#include <X11/XF86keysym.h> + +static const char *colorname[NUMCOLS] = { + [INIT] = "#3c3836", /* after initialization */ + [INPUT] = "#005577", /* during input */ + [INPUT_ALT] = "#227799", /* during input, second color */ + [FAILED] = "#CC3333", /* wrong password */ + [CAPS] = "#FF0000", /* CapsLock on */ + [CAPS_ALT] = "#FFA666", /* hypothetical alternate color for CapsLock on */ + [PAM] = "#9400D3", /* waiting for PAM */ +}; + +/* Enable or disable (1 means enable, 0 disable) bell sound when password is incorrect */ +static const int xbell = 0; + +/* Treat a cleared input like a wrong password (color) */ +static const int failonclear = 1; + +/* allow control key to trigger fail on clear */ +static const int controlkeyclear = 0; + +/* Time in seconds before the monitor shuts down */ +static const int monitortime = 300; + +/* Insert grid pattern with scale 1:1, the size can be changed with logosize */ +static const int logosize = 75; +/* Grid width and height for right center alignment */ +static const int logow = 12; +static const int logoh = 6; + +static XRectangle rectangles[9] = { + /* x y w h */ + { 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; +static int privateblur = 100; +/* Enable Pixelation */ +//#define PIXELATION +/* Set pixelation radius */ +static const int pixelSize = 0; + +/* Background image path, should be available to the user above */ +static const char *background_image = ""; + +/* PAM service that's used for authentication */ +static const char *pam_service = "system-login"; + +/* Font settings for the time text */ +static const float textsize=64.0; +static const char *textfamily="serif"; +static const double textcolorred=255; +static const double textcolorgreen=255; +static const double textcolorblue=255; + +/* Default message */ +static const char *message = "THESIAH"; + +/* Text color */ +static const char *text_color = "#C6D0F5"; + +/* Text size (must be a valid size) */ +static const char *font_name = "monospace:size=18:bold"; + +/* Length of entires in scom */ +#define entrylen 3 + +static const secretpass scom[entrylen] = { +/* Password command */ + { "reboot", "loginctl reboot -i" }, + { "shutdown", "loginctl poweroff -i" }, + { "suspend", "loginctl suspend -i" }, +} ; + +static const Passthrough passthroughs[] = { + /* Modifier Key */ + { 0, XF86XK_AudioRaiseVolume }, + { 0, XF86XK_AudioLowerVolume }, + { 0, XF86XK_AudioMute }, + { 0, XF86XK_AudioPause }, + { 0, XF86XK_AudioStop }, + { 0, XF86XK_AudioNext }, + { 0, XF86XK_AudioPrev }, + { 0, XF86XK_MonBrightnessUp }, + { 0, XF86XK_MonBrightnessDown }, +}; + diff --git a/slock/config.h b/slock/config.h deleted file mode 100644 index 4afba52..0000000 --- a/slock/config.h +++ /dev/null @@ -1,77 +0,0 @@ -/* user and group to drop privileges to */ -static const char *group = "wheel"; -static int personalblur = 100; - -static const char *colorname[NUMCOLS] = { - [INIT] = "#3c3836", /* after initialization */ - [INPUT] = "#005577", /* during input */ - [INPUT_ALT] = "#227799", /* during input, second color */ - [FAILED] = "#CC3333", /* wrong password */ - [CAPS] = "#FF0000", /* CapsLock on */ - [CAPS_ALT] = "#FFA666", /* hypothetical alternate color for CapsLock on */ - [PAM] = "#9400D3", /* waiting for PAM */ -}; - -/* treat a cleared input like a wrong password (color) */ -static const int failonclear = 1; - -/* Background image path, should be available to the user above */ -static const char* background_image = ""; - -/* default message */ -static const char *message = "THESIAH"; - -/* text color */ -static const char *text_color = "#C6D0F5"; - -/* text size */ -static const char *font_name = "monospace:size=18:bold"; - -/* time in seconds before the monitor shuts down */ -static const int monitortime = 600; - -/* PAM service that's used for authentication */ -static const char* pam_service = "system-login"; - -/* insert grid pattern with scale 1:1, the size can be changed with logosize */ -static const int logosize = 75; -/* grid width and height for right center alignment */ -static const int logow = 12; -static const int logoh = 6; - -static XRectangle rectangles[9] = { - /* x y w h */ - { 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 int blurRadius=5; -/*Enable Pixelation*/ -//#define PIXELATION -/*Set pixelation radius*/ -static const int pixelSize=0; - -/* - * Xresources preferences to load at startup - */ -ResourcePref resources[] = { - { "color0", STRING, &colorname[INIT] }, - { "color4", STRING, &colorname[INPUT] }, - { "color12", STRING, &colorname[INPUT_ALT] }, - { "color1", STRING, &colorname[FAILED] }, - { "color3", STRING, &colorname[CAPS] }, - { "color11", STRING, &colorname[CAPS_ALT] }, - { "color13", STRING, &colorname[PAM] }, - { "color0", STRING, &text_color }, -}; - diff --git a/slock/config.mk b/slock/config.mk index 7dab153..2d3759c 100644 --- a/slock/config.mk +++ b/slock/config.mk @@ -35,6 +35,3 @@ COMPATSRC = explicit_bzero.c #CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_NETBSD_SOURCE # On OpenBSD set COMPATSRC to empty #COMPATSRC = - -# compiler and linker -CC = cc diff --git a/slock/patches/slock-alternate-colors-20220921-35633d4.diff b/slock/patches/slock-alternate-colors-20220921-35633d4.diff new file mode 100644 index 0000000..bf28d18 --- /dev/null +++ b/slock/patches/slock-alternate-colors-20220921-35633d4.diff @@ -0,0 +1,49 @@ +From 3603c02bf54df2a5309ac74639829f2393033edc Mon Sep 17 00:00:00 2001 +From: Max Schillinger <maxschillinger@web.de> +Date: Wed, 21 Sep 2022 20:23:16 +0200 +Subject: [PATCH] Alternate color during password input + +Toggle screen color between two shades of blue during password input to get +some feedback. +--- + config.def.h | 1 + + slock.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..029af10 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -5,6 +5,7 @@ static const char *group = "nogroup"; + static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ + [INPUT] = "#005577", /* during input */ ++ [INPUT_ALT] = "#227799", /* during input, second color */ + [FAILED] = "#CC3333", /* wrong password */ + }; + +diff --git a/slock.c b/slock.c +index 5ae738c..c4f28b8 100644 +--- a/slock.c ++++ b/slock.c +@@ -27,6 +27,7 @@ char *argv0; + enum { + INIT, + INPUT, ++ INPUT_ALT, + FAILED, + NUMCOLS + }; +@@ -187,7 +188,8 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + } + break; + } +- color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); ++ color = len ? (len%2 ? INPUT : INPUT_ALT) ++ : ((failure || failonclear) ? FAILED : INIT); + if (running && oldc != color) { + for (screen = 0; screen < nscreens; screen++) { + XSetWindowBackground(dpy, +-- +2.37.3 + diff --git a/slock/patches/slock-background-image-20220318-1c5a538.diff b/slock/patches/slock-background-image-20220318-1c5a538.diff new file mode 100644 index 0000000..2d4caf4 --- /dev/null +++ b/slock/patches/slock-background-image-20220318-1c5a538.diff @@ -0,0 +1,149 @@ +From 1c5a5383a1cf3351fe9c80a21cfbc98c5ec4355d Mon Sep 17 00:00:00 2001 +From: Yan Doroshenko <yan1994doroshenko@gmail.com> +Date: Fri, 18 Mar 2022 12:28:13 +0100 +Subject: [PATCH] Provide a way to set a background image + +--- + config.def.h | 5 ++++- + config.mk | 2 +- + slock.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 52 insertions(+), 5 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..eb88b3d 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -1,6 +1,6 @@ + /* user and group to drop privileges to */ + static const char *user = "nobody"; +-static const char *group = "nogroup"; ++static const char *group = "nobody"; + + static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ +@@ -10,3 +10,6 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* Background image path, should be available to the user above */ ++static const char* background_image = ""; +diff --git a/config.mk b/config.mk +index 74429ae..987819e 100644 +--- a/config.mk ++++ b/config.mk +@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib + + # includes and libs + INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lImlib2 + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --git a/slock.c b/slock.c +index 5ae738c..345a279 100644 +--- a/slock.c ++++ b/slock.c +@@ -18,6 +18,7 @@ + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> ++#include <Imlib2.h> + + #include "arg.h" + #include "util.h" +@@ -35,6 +36,7 @@ struct lock { + int screen; + Window root, win; + Pixmap pmap; ++ Pixmap bgmap; + unsigned long colors[NUMCOLS]; + }; + +@@ -46,6 +48,8 @@ struct xrandr { + + #include "config.h" + ++Imlib_Image image; ++ + static void + die(const char *errstr, ...) + { +@@ -190,9 +194,10 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + 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]); ++ 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); + } + oldc = color; +@@ -235,6 +240,17 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + 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_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); +@@ -251,6 +267,8 @@ lockscreen(Display *dpy, struct xrandr *rr, int 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); +@@ -355,6 +373,32 @@ main(int argc, char **argv) { + if (setuid(duid) < 0) + die("slock: setuid: %s\n", strerror(errno)); + ++ /* Load picture */ ++ Imlib_Image buffer = imlib_load_image(background_image); ++ imlib_context_set_image(buffer); ++ int background_image_width = imlib_image_get_width(); ++ int background_image_height = imlib_image_get_height(); ++ ++ /* Create an image to be rendered */ ++ Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy)); ++ image = imlib_create_image(scr->width, scr->height); ++ imlib_context_set_image(image); ++ ++ /* Fill the image for every X monitor */ ++ XRRMonitorInfo *monitors; ++ int number_of_monitors; ++ monitors = XRRGetMonitors(dpy, RootWindow(dpy, XScreenNumberOfScreen(scr)), True, &number_of_monitors); ++ ++ int i; ++ for (i = 0; i < number_of_monitors; i++) { ++ imlib_blend_image_onto_image(buffer, 0, 0, 0, background_image_width, background_image_height, monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height); ++ } ++ ++ /* Clean up */ ++ imlib_context_set_image(buffer); ++ imlib_free_image(); ++ imlib_context_set_image(image); ++ + /* check for Xrandr support */ + rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); + +-- +2.35.1 + diff --git a/slock/patches/slock-capscolor-20220921-35633d4.diff b/slock/patches/slock-capscolor-20220921-35633d4.diff new file mode 100644 index 0000000..e463747 --- /dev/null +++ b/slock/patches/slock-capscolor-20220921-35633d4.diff @@ -0,0 +1,88 @@ +From da1721b1b4bb0aa8f94537ddd2a3eada1df00a30 Mon Sep 17 00:00:00 2001 +From: Max Schillinger <maxschillinger@web.de> +Date: Wed, 21 Sep 2022 19:56:58 +0200 +Subject: [PATCH] Update capscolor patch to match the latest slock commit + (35633d4) + +--- + config.def.h | 1 + + slock.c | 15 ++++++++++++--- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..6288856 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,6 +6,7 @@ static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ + [INPUT] = "#005577", /* during input */ + [FAILED] = "#CC3333", /* wrong password */ ++ [CAPS] = "red", /* CapsLock on */ + }; + + /* treat a cleared input like a wrong password (color) */ +diff --git a/slock.c b/slock.c +index 5ae738c..5f4fb7a 100644 +--- a/slock.c ++++ b/slock.c +@@ -18,6 +18,7 @@ + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> ++#include <X11/XKBlib.h> + + #include "arg.h" + #include "util.h" +@@ -28,6 +29,7 @@ enum { + INIT, + INPUT, + FAILED, ++ CAPS, + NUMCOLS + }; + +@@ -130,16 +132,20 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + { + XRRScreenChangeNotifyEvent *rre; + char buf[32], passwd[256], *inputhash; +- int num, screen, running, failure, oldc; +- unsigned int len, color; ++ 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)); +@@ -179,6 +185,9 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + if (len) + passwd[--len] = '\0'; + break; ++ case XK_Caps_Lock: ++ caps = !caps; ++ break; + default: + if (num && !iscntrl((int)buf[0]) && + (len + num < sizeof(passwd))) { +@@ -187,7 +196,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + } + break; + } +- color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); ++ color = len ? (caps ? CAPS : INPUT) : (failure || failonclear ? FAILED : INIT); + if (running && oldc != color) { + for (screen = 0; screen < nscreens; screen++) { + XSetWindowBackground(dpy, +-- +2.37.3 + diff --git a/slock/patches/slock-dpms-20231017-4f04554.diff b/slock/patches/slock-dpms-20231017-4f04554.diff new file mode 100644 index 0000000..35ad57c --- /dev/null +++ b/slock/patches/slock-dpms-20231017-4f04554.diff @@ -0,0 +1,86 @@ +From 4259049ca8d06a34c828c70298f3a8fdb8c5104c Mon Sep 17 00:00:00 2001 +From: mortezadadgar <mortezadadgar97@gmail.com> +Date: Sat, 23 Sep 2023 18:45:58 +0330 +Subject: [PATCH] Update to respect prevoius state of dpms + +--- + config.def.h | 3 +++ + slock.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 29 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 9855e21..d01bd38 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,6 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* time in seconds before the monitor shuts down */ ++static const int monitortime = 5; +diff --git a/slock.c b/slock.c +index 5ae738c..b5ac721 100644 +--- a/slock.c ++++ b/slock.c +@@ -1,4 +1,5 @@ + /* See LICENSE file for license details. */ ++#include <X11/Xmd.h> + #define _XOPEN_SOURCE 500 + #if HAVE_SHADOW_H + #include <shadow.h> +@@ -15,6 +16,7 @@ + #include <unistd.h> + #include <sys/types.h> + #include <X11/extensions/Xrandr.h> ++#include <X11/extensions/dpms.h> + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> +@@ -314,6 +316,8 @@ main(int argc, char **argv) { + const char *hash; + Display *dpy; + int s, nlocks, nscreens; ++ CARD16 standby, suspend, off; ++ BOOL dpms_state; + + ARGBEGIN { + case 'v': +@@ -374,6 +378,22 @@ main(int argc, char **argv) { + 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) { + switch (fork()) { +@@ -391,5 +411,11 @@ main(int argc, char **argv) { + /* everything is now blank. Wait for the correct password */ + readpw(dpy, &rr, locks, nscreens, hash); + ++ /* reset DPMS values to inital ones */ ++ DPMSSetTimeouts(dpy, standby, suspend, off); ++ if (!dpms_state) ++ DPMSDisable(dpy); ++ XSync(dpy, 0); ++ + return 0; + } +-- +2.42.0 + diff --git a/slock/patches/slock-foreground-and-background-20210611-35633d4.diff b/slock/patches/slock-foreground-and-background-20210611-35633d4.diff new file mode 100644 index 0000000..346fdc0 --- /dev/null +++ b/slock/patches/slock-foreground-and-background-20210611-35633d4.diff @@ -0,0 +1,340 @@ +From 61f4d247d4060f42cbdbf2771061f0e165ada3a9 Mon Sep 17 00:00:00 2001 +From: KNIX 3 <nki3@protonmail.com> +Date: Fri, 11 Jun 2021 13:20:54 -0400 +Subject: [PATCH] Foreground and Background + +--- + config.def.h | 28 +++++++++ + config.mk | 16 ++++-- + slock.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 187 insertions(+), 13 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..ceceeb0 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,31 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* insert grid pattern with scale 1:1, the size can be changed with logosize */ ++static const int logosize = 75; ++/* grid width and height for right center alignment */ ++static const int logow = 12; ++static const int logoh = 6; ++ ++static XRectangle rectangles[9] = { ++ /* x y w h */ ++ { 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.mk b/config.mk +index 74429ae..e851ede 100644 +--- a/config.mk ++++ b/config.mk +@@ -10,13 +10,21 @@ MANPREFIX = ${PREFIX}/share/man + X11INC = /usr/X11R6/include + X11LIB = /usr/X11R6/lib + ++# Xinerama ++XINERAMALIBS = -lXinerama ++XINERAMAFLAGS = -DXINERAMA ++ ++# freetype ++FREETYPELIBS = -lXft ++FREETYPEINC = /usr/include/freetype2 ++ + # includes and libs +-INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++INCS = -I. -I/usr/include -I${X11INC} -I${FREETYPEINC} ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXext -lXrandr -lImlib2 + + # flags +-CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +-CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} ++CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ${XINERAMAFLAGS} ++CFLAGS = -std=c99 -pedantic -Wall -Ofast ${INCS} ${CPPFLAGS} + LDFLAGS = -s ${LIBS} + COMPATSRC = explicit_bzero.c + +diff --git a/slock.c b/slock.c +index 5ae738c..efbe833 100644 +--- a/slock.c ++++ b/slock.c +@@ -1,5 +1,6 @@ + /* See LICENSE file for license details. */ +-#define _XOPEN_SOURCE 500 ++#define _XOPEN_SOURCE 500 ++#define LENGTH(X) (sizeof X / sizeof X[0]) + #if HAVE_SHADOW_H + #include <shadow.h> + #endif +@@ -15,9 +16,14 @@ + #include <unistd.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/Xft/Xft.h> ++#include <Imlib2.h> + + #include "arg.h" + #include "util.h" +@@ -31,11 +37,19 @@ enum { + 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 { +@@ -44,7 +58,7 @@ struct xrandr { + int errbase; + }; + +-#include "config.h" ++Imlib_Image image; + + static void + die(const char *errstr, ...) +@@ -124,6 +138,34 @@ gethash(void) + 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[BACKGROUND]); ++ XFillRectangle(dpy, lock->drawable, lock->gc, 0, 0, lock->x, lock->y); */ ++ lock->drawable = lock->bgmap; ++ XSetForeground(dpy, lock->gc, lock->colors[color]); ++ XFillRectangles(dpy, lock->drawable, lock->gc, lock->rectangles, LENGTH(rectangles)); ++ XCopyArea(dpy, lock->drawable, lock->win, lock->gc, 0, 0, lock->x, lock->y, 0, 0); ++ XSync(dpy, False); ++} ++ + static void + readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + const char *hash) +@@ -190,10 +232,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + 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); ++ drawlogo(dpy, locks[screen], color); + } + oldc = color; + } +@@ -228,6 +267,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + 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; +@@ -235,27 +278,60 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + 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[INIT]; + lock->win = XCreateWindow(dpy, lock->root, 0, 0, +- DisplayWidth(dpy, lock->screen), +- DisplayHeight(dpy, lock->screen), ++ 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) { +@@ -276,6 +352,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); + + XSelectInput(dpy, lock->root, SubstructureNotifyMask); ++ drawlogo(dpy, lock, INIT); + return lock; + } + +@@ -355,6 +432,60 @@ main(int argc, char **argv) { + 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); + +@@ -391,5 +522,12 @@ main(int argc, char **argv) { + /* 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); ++ } ++ ++ XSync(dpy, 0); ++ XCloseDisplay(dpy); + return 0; + } +-- +2.31.1 + diff --git a/slock/patches/slock-git-20161012-control-clear.diff b/slock/patches/slock-git-20161012-control-clear.diff new file mode 100644 index 0000000..b9634cd --- /dev/null +++ b/slock/patches/slock-git-20161012-control-clear.diff @@ -0,0 +1,27 @@ +diff --git a/config.def.h b/config.def.h +index 6fba2b6..933152b 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,6 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password */ + static const int failonclear = 1; ++ ++/* allow control key to trigger fail on clear */ ++static const int controlkeyclear = 0; +diff --git a/slock.c b/slock.c +index 4d7f06f..15552ef 100644 +--- a/slock.c ++++ b/slock.c +@@ -180,8 +180,9 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + passwd[len--] = '\0'; + break; + default: +- if (num && !iscntrl((int)buf[0]) && +- (len + num < sizeof(passwd))) { ++ if (controlkeyclear && iscntrl((int)buf[0])) ++ continue; ++ if (num && (len + num < sizeof(passwd))) { + memcpy(passwd + len, buf, num); + len += num; + } diff --git a/slock/patches/slock-message-xft-20210315-ae681c5.diff b/slock/patches/slock-message-xft-20210315-ae681c5.diff new file mode 100644 index 0000000..98d1645 --- /dev/null +++ b/slock/patches/slock-message-xft-20210315-ae681c5.diff @@ -0,0 +1,237 @@ +From ae681c5a52a2b4b257f9432204deedc8b5570e8d Mon Sep 17 00:00:00 2001 +From: Nathaniel Evan <nathanielevan@zohomail.com> +Date: Mon, 15 Mar 2021 05:50:20 +0700 +Subject: [PATCH] Updates message patch with Xft font support + +--- + config.def.h | 9 +++++ + config.mk | 4 +- + slock.1 | 4 ++ + slock.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 122 insertions(+), 5 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..2c83077 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,12 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* default message */ ++static const char * message = "Suckless: Software that sucks less."; ++ ++/* text color */ ++static const char * text_color = "#ffffff"; ++ ++/* text size (must be a valid size) */ ++static const char * font_name = "sans-serif:size:pixelsize=24:antialias=true:autohint=true"; +diff --git a/config.mk b/config.mk +index 74429ae..69ef27a 100644 +--- a/config.mk ++++ b/config.mk +@@ -11,8 +11,8 @@ X11INC = /usr/X11R6/include + X11LIB = /usr/X11R6/lib + + # includes and libs +-INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++INCS = -I. -I/usr/include -I${X11INC} -I/usr/include/freetype2 ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lXinerama -lXft + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --git a/slock.1 b/slock.1 +index 82cdcd6..541a264 100644 +--- a/slock.1 ++++ b/slock.1 +@@ -6,6 +6,7 @@ + .Sh SYNOPSIS + .Nm + .Op Fl v ++.Op Fl m Ar message + .Op Ar cmd Op Ar arg ... + .Sh DESCRIPTION + .Nm +@@ -16,6 +17,9 @@ is executed after the screen has been locked. + .Bl -tag -width Ds + .It Fl v + Print version information to stdout and exit. ++.It Fl m Ar message ++Overrides default slock lock message. ++.TP + .El + .Sh SECURITY CONSIDERATIONS + To make sure a locked screen can not be bypassed by switching VTs +diff --git a/slock.c b/slock.c +index 5ae738c..ef569f8 100644 +--- a/slock.c ++++ b/slock.c +@@ -14,16 +14,22 @@ + #include <string.h> + #include <unistd.h> + #include <sys/types.h> ++#include <fontconfig/fontconfig.h> + #include <X11/extensions/Xrandr.h> ++#include <X11/extensions/Xinerama.h> + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> ++#include <X11/Xft/Xft.h> + + #include "arg.h" + #include "util.h" + + char *argv0; + ++/* global count to prevent repeated error messages */ ++int count_error = 0; ++ + enum { + INIT, + INPUT, +@@ -83,6 +89,98 @@ dontkillme(void) + } + #endif + ++static void ++writemessage(Display *dpy, Window win, int screen) ++{ ++ int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size; ++ XftFont *fontinfo; ++ XftColor xftcolor; ++ XftDraw *xftdraw; ++ XGlyphInfo ext_msg, ext_space; ++ XineramaScreenInfo *xsi; ++ xftdraw = XftDrawCreate(dpy, win, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen)); ++ fontinfo = XftFontOpenName(dpy, screen, font_name); ++ XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), text_color, &xftcolor); ++ ++ if (fontinfo == NULL) { ++ if (count_error == 0) { ++ fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name); ++ count_error++; ++ } ++ return; ++ } ++ ++ XftTextExtentsUtf8(dpy, fontinfo, (XftChar8 *) " ", 1, &ext_space); ++ tab_size = 8 * ext_space.width; ++ ++ /* To prevent "Uninitialized" warnings. */ ++ xsi = NULL; ++ ++ /* ++ * Start formatting and drawing text ++ */ ++ ++ len = strlen(message); ++ ++ /* Max max line length (cut at '\n') */ ++ line_len = 0; ++ k = 0; ++ for (i = j = 0; i < len; i++) { ++ if (message[i] == '\n') { ++ if (i - j > line_len) ++ line_len = i - j; ++ k++; ++ i++; ++ j = i; ++ } ++ } ++ /* If there is only one line */ ++ if (line_len == 0) ++ line_len = len; ++ ++ if (XineramaIsActive(dpy)) { ++ xsi = XineramaQueryScreens(dpy, &i); ++ s_width = xsi[0].width; ++ s_height = xsi[0].height; ++ } else { ++ s_width = DisplayWidth(dpy, screen); ++ s_height = DisplayHeight(dpy, screen); ++ } ++ ++ XftTextExtentsUtf8(dpy, fontinfo, (XftChar8 *)message, line_len, &ext_msg); ++ height = s_height*3/7 - (k*20)/3; ++ width = (s_width - ext_msg.width)/2; ++ ++ /* Look for '\n' and print the text between them. */ ++ for (i = j = k = 0; i <= len; i++) { ++ /* i == len is the special case for the last line */ ++ if (i == len || message[i] == '\n') { ++ tab_replace = 0; ++ while (message[j] == '\t' && j < i) { ++ tab_replace++; ++ j++; ++ } ++ ++ XftDrawStringUtf8(xftdraw, &xftcolor, fontinfo, width + tab_size*tab_replace, height + 20*k, (XftChar8 *)(message + j), i - j); ++ while (i < len && message[i] == '\n') { ++ i++; ++ j = i; ++ k++; ++ } ++ } ++ } ++ ++ /* xsi should not be NULL anyway if Xinerama is active, but to be safe */ ++ if (XineramaIsActive(dpy) && xsi != NULL) ++ XFree(xsi); ++ ++ XftFontClose(dpy, fontinfo); ++ XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &xftcolor); ++ XftDrawDestroy(xftdraw); ++} ++ ++ ++ + static const char * + gethash(void) + { +@@ -194,6 +292,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + locks[screen]->win, + locks[screen]->colors[color]); + XClearWindow(dpy, locks[screen]->win); ++ writemessage(dpy, locks[screen]->win, screen); + } + oldc = color; + } +@@ -300,7 +399,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) + static void + usage(void) + { +- die("usage: slock [-v] [cmd [arg ...]]\n"); ++ die("usage: slock [-v] [-m message] [cmd [arg ...]]\n"); + } + + int +@@ -319,6 +418,9 @@ main(int argc, char **argv) { + case 'v': + fprintf(stderr, "slock-"VERSION"\n"); + return 0; ++ case 'm': ++ message = EARGF(usage()); ++ break; + default: + usage(); + } ARGEND +@@ -363,10 +465,12 @@ main(int argc, char **argv) { + 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) ++ if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) { ++ writemessage(dpy, locks[s]->win, s); + nlocks++; +- else ++ } else { + break; ++ } + } + XSync(dpy, 0); + +-- +2.30.1 + diff --git a/slock/patches/slock-noxbell-0.2.diff b/slock/patches/slock-noxbell-0.2.diff new file mode 100644 index 0000000..5a189e4 --- /dev/null +++ b/slock/patches/slock-noxbell-0.2.diff @@ -0,0 +1,37 @@ +From f8bd65f192bc09fddcbc3d5a61f4dd2bba283adf Mon Sep 17 00:00:00 2001 +From: John Doe <bankai671@proton.me> +Date: Mon, 19 Feb 2024 22:01:05 +0100 +Subject: [PATCH] add bell sound configuration + +--- + config.h | 3 +++ + slock.c | 3 ++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..b32a2cf 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,6 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* enable or disable (1 means enable, 0 disable) bell sound when password is incorrect */ ++static const int xbell = 0; +diff --git a/slock.c b/slock.c +index 5ae738c..f40ea23 100644 +--- a/slock.c ++++ b/slock.c +@@ -165,7 +165,8 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + else + running = !!strcmp(inputhash, hash); + if (running) { +- XBell(dpy, 100); ++ if (xbell == 1) ++ XBell(dpy, 100); + failure = 1; + } + explicit_bzero(&passwd, sizeof(passwd)); +-- +2.43.0 diff --git a/slock/patches/slock-pam_auth-20190207-35633d4.diff b/slock/patches/slock-pam_auth-20190207-35633d4.diff new file mode 100644 index 0000000..136f4b5 --- /dev/null +++ b/slock/patches/slock-pam_auth-20190207-35633d4.diff @@ -0,0 +1,154 @@ +diff --git a/config.def.h b/config.def.h +index 9855e21..19e7f62 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,7 +6,11 @@ static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ + [INPUT] = "#005577", /* during input */ + [FAILED] = "#CC3333", /* wrong password */ ++ [PAM] = "#9400D3", /* waiting for PAM */ + }; + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* PAM service that's used for authentication */ ++static const char* pam_service = "login"; +diff --git a/config.mk b/config.mk +index 74429ae..6e82074 100644 +--- a/config.mk ++++ b/config.mk +@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib + + # includes and libs + INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lpam + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --git a/slock.c b/slock.c +index 5ae738c..3a8da42 100644 +--- a/slock.c ++++ b/slock.c +@@ -18,16 +18,22 @@ + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> ++#include <security/pam_appl.h> ++#include <security/pam_misc.h> + + #include "arg.h" + #include "util.h" + + char *argv0; ++static int pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); ++struct pam_conv pamc = {pam_conv, NULL}; ++char passwd[256]; + + enum { + INIT, + INPUT, + FAILED, ++ PAM, + NUMCOLS + }; + +@@ -57,6 +63,31 @@ die(const char *errstr, ...) + exit(1); + } + ++static int ++pam_conv(int num_msg, const struct pam_message **msg, ++ struct pam_response **resp, void *appdata_ptr) ++{ ++ int retval = PAM_CONV_ERR; ++ for(int i=0; i<num_msg; i++) { ++ if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF && ++ strncmp(msg[i]->msg, "Password: ", 10) == 0) { ++ struct pam_response *resp_msg = malloc(sizeof(struct pam_response)); ++ if (!resp_msg) ++ die("malloc failed\n"); ++ char *password = malloc(strlen(passwd) + 1); ++ if (!password) ++ die("malloc failed\n"); ++ memset(password, 0, strlen(passwd) + 1); ++ strcpy(password, passwd); ++ resp_msg->resp_retcode = 0; ++ resp_msg->resp = password; ++ resp[i] = resp_msg; ++ retval = PAM_SUCCESS; ++ } ++ } ++ return retval; ++} ++ + #ifdef __linux__ + #include <fcntl.h> + #include <linux/oom.h> +@@ -121,6 +152,8 @@ gethash(void) + } + #endif /* HAVE_SHADOW_H */ + ++ /* pam, store user name */ ++ hash = pw->pw_name; + return hash; + } + +@@ -129,11 +162,12 @@ 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; ++ char buf[32]; ++ int num, screen, running, failure, oldc, retval; + unsigned int len, color; + KeySym ksym; + XEvent ev; ++ pam_handle_t *pamh; + + len = 0; + running = 1; +@@ -160,10 +194,26 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + case XK_Return: + passwd[len] = '\0'; + errno = 0; +- if (!(inputhash = crypt(passwd, hash))) +- fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); ++ retval = pam_start(pam_service, hash, &pamc, &pamh); ++ color = PAM; ++ for (screen = 0; screen < nscreens; screen++) { ++ XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[color]); ++ XClearWindow(dpy, locks[screen]->win); ++ XRaiseWindow(dpy, locks[screen]->win); ++ } ++ XSync(dpy, False); ++ ++ if (retval == PAM_SUCCESS) ++ retval = pam_authenticate(pamh, 0); ++ if (retval == PAM_SUCCESS) ++ retval = pam_acct_mgmt(pamh, 0); ++ ++ running = 1; ++ if (retval == PAM_SUCCESS) ++ running = 0; + else +- running = !!strcmp(inputhash, hash); ++ fprintf(stderr, "slock: %s\n", pam_strerror(pamh, retval)); ++ pam_end(pamh, retval); + if (running) { + XBell(dpy, 100); + failure = 1; +@@ -339,10 +389,9 @@ main(int argc, char **argv) { + dontkillme(); + #endif + ++ /* the contents of hash are used to transport the current user name */ + hash = gethash(); + errno = 0; +- if (!crypt("", hash)) +- die("slock: crypt: %s\n", strerror(errno)); + + if (!(dpy = XOpenDisplay(NULL))) + die("slock: cannot open display\n"); diff --git a/slock/patches/slock-passthrough-20240812-809d3c0.diff b/slock/patches/slock-passthrough-20240812-809d3c0.diff new file mode 100644 index 0000000..bc4c2bc --- /dev/null +++ b/slock/patches/slock-passthrough-20240812-809d3c0.diff @@ -0,0 +1,104 @@ +From 809d3c01cfdc8c5bf7eb37e5d3ade59b0947cab3 Mon Sep 17 00:00:00 2001 +From: catboomer <catb00mer@proton.me> +Date: Mon, 12 Aug 2024 17:55:30 -0500 +Subject: [PATCH] [PATCH] passthrough: adds table to config.h to permit certain + keys to pass through slock + +--- + config.def.h | 15 +++++++++++++++ + slock.c | 28 +++++++++++++++++++++++++++- + 2 files changed, 42 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..5b2ff78 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,18 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++#include <X11/XF86keysym.h> ++ ++static const Passthrough passthroughs[] = { ++ /* Modifier Key */ ++ { 0, XF86XK_AudioRaiseVolume }, ++ { 0, XF86XK_AudioLowerVolume }, ++ { 0, XF86XK_AudioMute }, ++ { 0, XF86XK_AudioPause }, ++ { 0, XF86XK_AudioStop }, ++ { 0, XF86XK_AudioNext }, ++ { 0, XF86XK_AudioPrev }, ++ { 0, XF86XK_MonBrightnessUp }, ++ { 0, XF86XK_MonBrightnessDown }, ++}; +diff --git a/slock.c b/slock.c +index 5ae738c..522a226 100644 +--- a/slock.c ++++ b/slock.c +@@ -22,6 +22,11 @@ + #include "arg.h" + #include "util.h" + ++#include <X11/XF86keysym.h> ++#define LENGTH(X) (sizeof X / sizeof X[0]) ++#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) ++ ++static unsigned int numlockmask = 0; + char *argv0; + + enum { +@@ -31,6 +36,11 @@ enum { + NUMCOLS + }; + ++typedef struct { ++ unsigned int mod; ++ KeySym keysym; ++} Passthrough; ++ + struct lock { + int screen; + Window root, win; +@@ -130,7 +140,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + { + XRRScreenChangeNotifyEvent *rre; + char buf[32], passwd[256], *inputhash; +- int num, screen, running, failure, oldc; ++ int num, screen, running, failure, oldc, i, passing; + unsigned int len, color; + KeySym ksym; + XEvent ev; +@@ -156,6 +166,20 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + IsPFKey(ksym) || + IsPrivateKeypadKey(ksym)) + continue; ++ ++ passing = 0; ++ for (i = 0; i < LENGTH(passthroughs); i++) { ++ if (ksym == passthroughs[i].keysym && ++ CLEANMASK(passthroughs[i].mod) == CLEANMASK(ev.xkey.state)) { ++ passing = 1; ++ XSendEvent(dpy, DefaultRootWindow(dpy), True, KeyPressMask, &ev); ++ break; ++ } ++ } ++ ++ if(passing) ++ continue; ++ + switch (ksym) { + case XK_Return: + passwd[len] = '\0'; +@@ -184,6 +208,8 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + (len + num < sizeof(passwd))) { + memcpy(passwd + len, buf, num); + len += num; ++ } else { ++ continue; /* Don't trigger fail screen when pressing control characters */ + } + break; + } +-- +2.46.0 + diff --git a/slock/patches/slock-secret-password-1.4.diff b/slock/patches/slock-secret-password-1.4.diff new file mode 100644 index 0000000..6f4be2e --- /dev/null +++ b/slock/patches/slock-secret-password-1.4.diff @@ -0,0 +1,43 @@ +diff --git a/config.def.h b/config.def.h +index 9855e21..989ca08 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,10 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* length of entires in scom */ ++#define entrylen 1 ++ ++static const secretpass scom[entrylen] = { ++/* Password command */ ++ { "shutdown", "doas poweroff" }, ++}; +diff --git a/slock.c b/slock.c +index d2f0886..6a96a2d 100644 +--- a/slock.c ++++ b/slock.c +@@ -31,6 +36,11 @@ enum { + NUMCOLS + }; ++ ++typedef struct { ++ const char *pass; ++ const char *command; ++} secretpass; ++ +@@ -160,6 +160,13 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + case XK_Return: + passwd[len] = '\0'; + errno = 0; ++ ++ for (int i = 0; i < entrylen; i++){ ++ if (strcmp(scom[i].pass, passwd) == 0){ ++ system(scom[i].command); ++ } ++ } ++ + if (!(inputhash = crypt(passwd, hash))) + fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); + else diff --git a/slock/patches/slock-showtime-1.5.diff b/slock/patches/slock-showtime-1.5.diff new file mode 100644 index 0000000..618dbf1 --- /dev/null +++ b/slock/patches/slock-showtime-1.5.diff @@ -0,0 +1,193 @@ +diff --git a/config.def.h b/config.def.h +index 9855e21..bc883ad 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -1,6 +1,11 @@ +-/* user and group to drop privileges to */ +-static const char *user = "nobody"; ++/* user and group to drop privileges to */ static const char *user = "nobody"; + static const char *group = "nogroup"; ++/*Font settings for the time text*/ ++static const float textsize=64.0; ++static const char* textfamily="serif"; ++static const double textcolorred=255; ++static const double textcolorgreen=255; ++static const double textcolorblue=255; + + static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ +diff --git a/config.mk b/config.mk +index 514c236..c42e301 100644 +--- a/config.mk ++++ b/config.mk +@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib + + # includes and libs + INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lcairo + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --git a/slock.c b/slock.c +index b2f14e3..d370a00 100644 +--- a/slock.c ++++ b/slock.c +@@ -5,6 +5,7 @@ + #endif + + #include <ctype.h> ++#include <cairo/cairo-xlib.h> + #include <errno.h> + #include <grp.h> + #include <pwd.h> +@@ -18,7 +19,8 @@ + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> +- ++#include <pthread.h> ++#include <time.h> + #include "arg.h" + #include "util.h" + +@@ -44,6 +46,14 @@ struct xrandr { + int errbase; + }; + ++struct displayData{ ++ struct lock **locks; ++ Display* dpy; ++ int nscreens; ++ cairo_t **crs; ++ cairo_surface_t **surfaces; ++}; ++static pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER; + #include "config.h" + + static void +@@ -123,10 +133,46 @@ gethash(void) + + return hash; + } ++static void ++refresh(Display *dpy, Window win , int screen, struct tm time, cairo_t* cr, cairo_surface_t* sfc) ++{/*Function that displays given time on the given screen*/ ++ static char tm[24]=""; ++ int xpos,ypos; ++ xpos=DisplayWidth(dpy, screen)/4; ++ ypos=DisplayHeight(dpy, screen)/2; ++ sprintf(tm,"%02d/%02d/%d %02d:%02d",time.tm_mday,time.tm_mon + 1,time.tm_year+1900,time.tm_hour,time.tm_min); ++ XClearWindow(dpy, win); ++ cairo_set_source_rgb(cr, textcolorred, textcolorgreen, textcolorblue); ++ cairo_select_font_face(cr, textfamily, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); ++ cairo_set_font_size(cr, textsize); ++ cairo_move_to(cr, xpos, ypos); ++ cairo_show_text(cr, tm); ++ cairo_surface_flush(sfc); ++ XFlush(dpy); ++} ++static void* ++displayTime(void* input) ++{ /*Thread that keeps track of time and refreshes it every 5 seconds */ ++ struct displayData* displayData=(struct displayData*)input; ++ while (1){ ++ pthread_mutex_lock(&mutex); /*Mutex to prevent interference with refreshing screen while typing password*/ ++ time_t rawtime; ++ time(&rawtime); ++ struct tm tm = *localtime(&rawtime); ++ for (int k=0;k<displayData->nscreens;k++){ ++ refresh(displayData->dpy, displayData->locks[k]->win, displayData->locks[k]->screen, tm,displayData->crs[k],displayData->surfaces[k]); ++ } ++ pthread_mutex_unlock(&mutex); ++ sleep(5); ++ } ++ return NULL; ++} ++ ++ + + static void + readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, +- const char *hash) ++ const char *hash,cairo_t **crs,cairo_surface_t **surfaces) + { + XRRScreenChangeNotifyEvent *rre; + char buf[32], passwd[256], *inputhash; +@@ -189,16 +235,23 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + } + color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); + if (running && oldc != color) { ++ pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering*/ + for (screen = 0; screen < nscreens; screen++) { + XSetWindowBackground(dpy, + locks[screen]->win, + locks[screen]->colors[color]); + XClearWindow(dpy, locks[screen]->win); ++ time_t rawtime; ++ time(&rawtime); ++ refresh(dpy, locks[screen]->win,locks[screen]->screen, *localtime(&rawtime),crs[screen],surfaces[screen]); ++ /*Redraw the time after screen cleared*/ + } ++ pthread_mutex_unlock(&mutex); + oldc = color; + } + } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { + rre = (XRRScreenChangeNotifyEvent*)&ev; ++ pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering.*/ + for (screen = 0; screen < nscreens; screen++) { + if (locks[screen]->win == rre->window) { + if (rre->rotation == RR_Rotate_90 || +@@ -212,6 +265,8 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + break; + } + } ++ ++ pthread_mutex_unlock(&mutex); + } else { + for (screen = 0; screen < nscreens; screen++) + XRaiseWindow(dpy, locks[screen]->win); +@@ -343,7 +398,7 @@ main(int argc, char **argv) { + errno = 0; + if (!crypt("", hash)) + die("slock: crypt: %s\n", strerror(errno)); +- ++ XInitThreads(); + if (!(dpy = XOpenDisplay(NULL))) + die("slock: cannot open display\n"); + +@@ -389,7 +444,33 @@ main(int argc, char **argv) { + } + + /* everything is now blank. Wait for the correct password */ +- readpw(dpy, &rr, locks, nscreens, hash); ++ pthread_t thredid; ++ /* Create Cairo drawables upon which the time will be shown. */ ++ struct displayData displayData; ++ cairo_surface_t **surfaces; ++ cairo_t **crs; ++ if (!(surfaces=calloc(nscreens, sizeof(cairo_surface_t*)))){ ++ die("Out of memory"); ++ } ++ if (!(crs=calloc(nscreens, sizeof(cairo_t*)))){ ++ die("Out of memory"); ++ } ++ for (int k=0;k<nscreens;k++){ ++ Drawable win=locks[k]->win; ++ int screen=locks[k]->screen; ++ XMapWindow(dpy, win); ++ surfaces[k]=cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, screen),DisplayWidth(dpy, screen) , DisplayHeight(dpy, screen)); ++ crs[k]=cairo_create(surfaces[k]); ++ } ++ displayData.dpy=dpy; ++ displayData.locks=locks; ++ displayData.nscreens=nscreens; ++ displayData.crs=crs; ++ displayData.surfaces=surfaces; ++ /*Start the thread that redraws time every 5 seconds*/ ++ pthread_create(&thredid, NULL, displayTime, &displayData); ++ /*Wait for the password*/ ++ readpw(dpy, &rr, locks, nscreens, hash,crs,surfaces); + + return 0; + } diff --git a/slock/patches/slock-user-1.5.diff b/slock/patches/slock-user-1.5.diff new file mode 100644 index 0000000..ee05747 --- /dev/null +++ b/slock/patches/slock-user-1.5.diff @@ -0,0 +1,47 @@ +From 7f1f66dfb1feb2b6df87565f1b895dd7a12d7ceb Mon Sep 17 00:00:00 2001 +From: Phillip Tischler <ptgit@protonmail.com> +Date: Sat, 18 Mar 2023 22:59:55 +0100 +Subject: [PATCH] Always use the current users password ($USER) + +--- + config.def.h | 4 ---- + slock.c | 8 ++++---- + 2 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..3229e62 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -1,7 +1,3 @@ +-/* user and group to drop privileges to */ +-static const char *user = "nobody"; +-static const char *group = "nogroup"; +- + static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ + [INPUT] = "#005577", /* during input */ +diff --git a/slock.c b/slock.c +index 5ae738c..7444eac 100644 +--- a/slock.c ++++ b/slock.c +@@ -325,13 +325,13 @@ main(int argc, char **argv) { + + /* validate drop-user and -group */ + errno = 0; +- if (!(pwd = getpwnam(user))) +- die("slock: getpwnam %s: %s\n", user, ++ if (!(pwd = getpwnam(getenv("USER")))) ++ die("slock: getpwnam %s: %s\n", getenv("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, ++ if (!(grp = getgrnam(getenv("USER")))) ++ die("slock: getgrnam %s: %s\n", getenv("USER"), + errno ? strerror(errno) : "group entry not found"); + dgid = grp->gr_gid; + +-- +2.30.2 + diff --git a/slock/slock.1 b/slock/slock.1 index 541a264..e1476ab 100644 --- a/slock/slock.1 +++ b/slock/slock.1 @@ -1,5 +1,6 @@ -.Dd 2016-08-23 +.Dd October 6, 2023 .Dt SLOCK 1 +.Os .Sh NAME .Nm slock .Nd simple X screen locker @@ -10,10 +11,12 @@ .Op Ar cmd Op Ar arg ... .Sh DESCRIPTION .Nm -is a simple X screen locker. If provided, -.Ar cmd Op Ar arg ... +is a simple X screen locker. +If provided, +.Ar cmd is executed after the screen has been locked. -.Sh OPTIONS +.Pp +The options are as follows: .Bl -tag -width Ds .It Fl v Print version information to stdout and exit. @@ -21,23 +24,26 @@ Print version information to stdout and exit. Overrides default slock lock message. .TP .El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +$ +.Nm +/usr/sbin/s2ram .Sh SECURITY CONSIDERATIONS To make sure a locked screen can not be bypassed by switching VTs or killing the X server with Ctrl+Alt+Backspace, it is recommended to disable both in .Xr xorg.conf 5 for maximum security: -.Bd -literal -offset left +.Bd -literal Section "ServerFlags" Option "DontVTSwitch" "True" Option "DontZap" "True" EndSection .Ed -.Sh EXAMPLES -$ -.Nm -/usr/sbin/s2ram .Sh CUSTOMIZATION .Nm can be customized by creating a custom config.h from config.def.h and -(re)compiling the source code. This keeps it fast, secure and simple. +(re)compiling the source code. +This keeps it fast, secure and simple. diff --git a/slock/slock.c b/slock/slock.c index 92b17b9..040012d 100644 --- a/slock/slock.c +++ b/slock/slock.c @@ -1,5 +1,4 @@ /* See LICENSE file for license details. */ -#include <X11/Xmd.h> #define _XOPEN_SOURCE 500 #define LENGTH(X) (sizeof X / sizeof X[0]) #if HAVE_SHADOW_H @@ -9,7 +8,6 @@ #include <ctype.h> #include <cairo/cairo-xlib.h> #include <errno.h> -#include <math.h> #include <grp.h> #include <pwd.h> #include <stdarg.h> @@ -18,18 +16,19 @@ #include <string.h> #include <unistd.h> #include <sys/types.h> +#include <fontconfig/fontconfig.h> +#include <X11/extensions/dpms.h> #include <X11/extensions/Xrandr.h> #ifdef XINERAMA #include <X11/extensions/Xinerama.h> #endif -#include <X11/extensions/dpms.h> #include <X11/keysym.h> +#include <X11/Xmd.h> +#include <X11/XF86keysym.h> +#include <X11/XKBlib.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#include <X11/XKBlib.h> -#include <X11/Xresource.h> #include <X11/Xft/Xft.h> -#include <X11/XF86keysym.h> #include <Imlib2.h> #include <security/pam_appl.h> #include <security/pam_misc.h> @@ -39,37 +38,40 @@ #include "arg.h" #include "util.h" +#include <X11/XF86keysym.h> +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + +static unsigned int numlockmask = 0; char *argv0; -static int pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); -struct pam_conv pamc = {pam_conv, NULL}; -char passwd[256]; /* global count to prevent repeated error messages */ int count_error = 0; +static int pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); +struct pam_conv pamc = {pam_conv, NULL}; +char passwd[256]; + enum { - CAPS, - CAPS_ALT, INIT, INPUT, INPUT_ALT, FAILED, + CAPS, + CAPS_ALT, PAM, NUMCOLS }; -/* Xresources preferences */ -enum resource_type { - STRING = 0, - INTEGER = 1, - FLOAT = 2 -}; +typedef struct { + unsigned int mod; + KeySym keysym; +} Passthrough; typedef struct { - char *name; - enum resource_type type; - void *dst; -} ResourcePref; + const char *pass; + const char *command; +} secretpass; struct displayData{ struct lock **locks; @@ -79,7 +81,6 @@ struct displayData{ cairo_surface_t **surfaces; }; static pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER; - #include "config.h" struct lock { @@ -103,6 +104,8 @@ struct xrandr { Imlib_Image image; +Imlib_Image image; + static void die(const char *errstr, ...) { @@ -165,39 +168,98 @@ dontkillme(void) } #endif -static void writemessage(Display *dpy, Window win, int screen) { - Visual *visual = DefaultVisual(dpy, screen); - Colormap colormap = DefaultColormap(dpy, screen); - XftDraw *draw; - XftFont *font; - XftColor color; - XGlyphInfo extents; // Use XGlyphInfo for text extents - int x, y; - XWindowAttributes attr; - - XGetWindowAttributes(dpy, win, &attr); - - draw = XftDrawCreate(dpy, win, visual, colormap); - font = XftFontOpenName(dpy, screen, font_name); // Make sure font_name is defined, such as "monospace:size=18" - if (!XftColorAllocName(dpy, visual, colormap, text_color, &color)) { // Ensure text_color is defined, e.g., "#FFFFFF" - fprintf(stderr, "slock: failed to allocate color\n"); - } +static void +writemessage(Display *dpy, Window win, int screen) +{ + int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size; + XftFont *fontinfo; + XftColor xftcolor; + XftDraw *xftdraw; + XGlyphInfo ext_msg, ext_space; + XineramaScreenInfo *xsi; + xftdraw = XftDrawCreate(dpy, win, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen)); + fontinfo = XftFontOpenName(dpy, screen, font_name); + XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), text_color, &xftcolor); + + if (fontinfo == NULL) { + if (count_error == 0) { + fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name); + count_error++; + } + return; + } + + XftTextExtentsUtf8(dpy, fontinfo, (XftChar8 *) " ", 1, &ext_space); + tab_size = 8 * ext_space.width; + + /* To prevent "Uninitialized" warnings. */ + xsi = NULL; + + /* + * Start formatting and drawing text + */ + + len = strlen(message); + + /* Max max line length (cut at '\n') */ + line_len = 0; + k = 0; + for (i = j = 0; i < len; i++) { + if (message[i] == '\n') { + if (i - j > line_len) + line_len = i - j; + k++; + i++; + j = i; + } + } + /* If there is only one line */ + if (line_len == 0) + line_len = len; + + if (XineramaIsActive(dpy)) { + xsi = XineramaQueryScreens(dpy, &i); + s_width = xsi[0].width; + s_height = xsi[0].height; + } else { + s_width = DisplayWidth(dpy, screen); + s_height = DisplayHeight(dpy, screen); + } + + XftTextExtentsUtf8(dpy, fontinfo, (XftChar8 *)message, line_len, &ext_msg); + height = s_height*3/4 - (k*20)/3; + width = (s_width - ext_msg.width)/2; + + /* Look for '\n' and print the text between them. */ + for (i = j = k = 0; i <= len; i++) { + /* i == len is the special case for the last line */ + if (i == len || message[i] == '\n') { + tab_replace = 0; + while (message[j] == '\t' && j < i) { + tab_replace++; + j++; + } - // Measure the text - XftTextExtentsUtf8(dpy, font, (FcChar8 *)message, strlen(message), &extents); - // Center the text horizontally and vertically - x = (attr.width - extents.xOff) / 2; - y = (attr.height - (font->ascent + font->descent)) / 1.185 + font->ascent; + XftDrawStringUtf8(xftdraw, &xftcolor, fontinfo, width + tab_size*tab_replace, height + 20*k, (XftChar8 *)(message + j), i - j); + while (i < len && message[i] == '\n') { + i++; + j = i; + k++; + } + } + } - // Draw the text - XftDrawStringUtf8(draw, &color, font, x, y, (FcChar8 *)message, strlen(message)); + /* xsi should not be NULL anyway if Xinerama is active, but to be safe */ + if (XineramaIsActive(dpy) && xsi != NULL) + XFree(xsi); - // Cleanup - XftColorFree(dpy, visual, colormap, &color); - XftDrawDestroy(draw); - XftFontClose(dpy, font); + XftFontClose(dpy, fontinfo); + XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &xftcolor); + XftDrawDestroy(xftdraw); } + + static const char * gethash(void) { @@ -268,35 +330,32 @@ drawlogo(Display *dpy, struct lock *lock, int color) XCopyArea(dpy, lock->drawable, lock->win, lock->gc, 0, 0, lock->x, lock->y, 0, 0); XSync(dpy, False); } - static void refresh(Display *dpy, Window win , int screen, struct tm time, cairo_t* cr, cairo_surface_t* sfc) {/*Function that displays given time on the given screen*/ - static char tm[32]=""; - double xpos,ypos; - cairo_text_extents_t extents; - - sprintf(tm,"%02d/%02d/%d %02d:%02d",time.tm_year+1900,time.tm_mon+1,time.tm_mday,time.tm_hour,time.tm_min); - - XClearWindow(dpy, win); - cairo_set_source_rgb(cr, 1, 1, 1); // Corrected color values (0 to 1 range) - cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size(cr, 64.0); - - // Measure the text to be rendered - cairo_text_extents(cr, tm, &extents); - xpos = (DisplayWidth(dpy, screen) - extents.width) / 2 - extents.x_bearing; - ypos = (DisplayHeight(dpy, screen) - extents.height) / 1.1 - extents.y_bearing; - - cairo_move_to(cr, xpos, ypos); - cairo_show_text(cr, tm); - - writemessage(dpy, win, screen); - - cairo_surface_flush(sfc); - XFlush(dpy); + static char tm[64] = ""; + int xpos,ypos; + double text_width, text_height; + + sprintf(tm,"%02d/%02d/%02d %02d:%02d",time.tm_year+1900,time.tm_mon+1,time.tm_mday,time.tm_hour,time.tm_min); + XClearWindow(dpy, win); + cairo_set_source_rgb(cr, textcolorred, textcolorgreen, textcolorblue); + cairo_select_font_face(cr, textfamily, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size(cr, textsize); + + cairo_text_extents_t extents; + cairo_text_extents(cr, tm, &extents); + text_width = extents.width; + text_height = extents.height; + + xpos = (DisplayWidth(dpy, screen) - text_width) / 2; + ypos = (DisplayHeight(dpy, screen) + 12 * text_height) / 2; + cairo_move_to(cr, xpos, ypos); + cairo_show_text(cr, tm); + cairo_surface_flush(sfc); + writemessage(dpy, win, screen); + XFlush(dpy); } - static void* displayTime(void* input) { /*Thread that keeps track of time and refreshes it every 5 seconds */ @@ -315,13 +374,15 @@ displayTime(void* input) return NULL; } + + static void readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, const char *hash,cairo_t **crs,cairo_surface_t **surfaces) { XRRScreenChangeNotifyEvent *rre; char buf[32]; - int caps, num, screen, running, failure, oldc, retval; + int caps, num, screen, running, failure, oldc, retval, i, passing; unsigned int len, color, indicators; KeySym ksym; XEvent ev; @@ -352,10 +413,31 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; + + passing = 0; + for (i = 0; i < LENGTH(passthroughs); i++) { + if (ksym == passthroughs[i].keysym && + CLEANMASK(passthroughs[i].mod) == CLEANMASK(ev.xkey.state)) { + passing = 1; + XSendEvent(dpy, DefaultRootWindow(dpy), True, KeyPressMask, &ev); + break; + } + } + + if(passing) + continue; + switch (ksym) { case XK_Return: passwd[len] = '\0'; errno = 0; + + for (int i = 0; i < entrylen; i++){ + if (strcmp(scom[i].pass, passwd) == 0){ + system(scom[i].command); + } + } + retval = pam_start(pam_service, hash, &pamc, &pamh); color = PAM; for (screen = 0; screen < nscreens; screen++) { @@ -377,7 +459,8 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, fprintf(stderr, "slock: %s\n", pam_strerror(pamh, retval)); pam_end(pamh, retval); if (running) { - XBell(dpy, 100); + if (xbell == 1) + XBell(dpy, 100); failure = 1; } explicit_bzero(&passwd, sizeof(passwd)); @@ -394,43 +477,35 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, case XK_Caps_Lock: caps = !caps; break; - case XF86XK_AudioPlay: - case XF86XK_AudioStop: - case XF86XK_AudioPrev: - case XF86XK_AudioNext: - case XF86XK_AudioRaiseVolume: - case XF86XK_AudioLowerVolume: - case XF86XK_AudioMute: - case XF86XK_AudioMicMute: - case XF86XK_MonBrightnessDown: - case XF86XK_MonBrightnessUp: - XSendEvent(dpy, DefaultRootWindow(dpy), True, KeyPressMask, &ev); - break; default: - if (num && !iscntrl((int)buf[0]) && - (len + num < sizeof(passwd))) { + if (controlkeyclear && iscntrl((int)buf[0])) + continue; + if (num && (len + num < sizeof(passwd))) { memcpy(passwd + len, buf, num); len += num; + } else { + continue; /* Don't trigger fail screen when pressing control characters */ } break; } - color = len ? (caps ? (len % 2 ? CAPS : CAPS_ALT) : (len % 2 ? INPUT : INPUT_ALT)) + color = len ? (caps ? (len % 2 ? CAPS : CAPS_ALT) : (len % 2 ? INPUT : INPUT_ALT)) : ((failure || failonclear) ? FAILED : INIT); if (running && oldc != color) { - pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering*/ + pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering*/ for (screen = 0; screen < nscreens; screen++) { - time_t rawtime; - time(&rawtime); - refresh(dpy, locks[screen]->win,locks[screen]->screen, *localtime(&rawtime),crs[screen],surfaces[screen]); + time_t rawtime; + time(&rawtime); + refresh(dpy, locks[screen]->win,locks[screen]->screen, *localtime(&rawtime),crs[screen],surfaces[screen]); + /*Redraw the time after screen cleared*/ drawlogo(dpy, locks[screen], color); - writemessage(dpy, locks[screen]->win, screen); + writemessage(dpy, locks[screen]->win, screen); } - pthread_mutex_unlock(&mutex); + pthread_mutex_unlock(&mutex); oldc = color; } } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { rre = (XRRScreenChangeNotifyEvent*)&ev; - pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering.*/ + pthread_mutex_lock(&mutex); /*Stop the time refresh thread from interfering.*/ for (screen = 0; screen < nscreens; screen++) { if (locks[screen]->win == rre->window) { if (rre->rotation == RR_Rotate_90 || @@ -444,7 +519,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, break; } } - pthread_mutex_unlock(&mutex); + pthread_mutex_unlock(&mutex); } else { for (screen = 0; screen < nscreens; screen++) XRaiseWindow(dpy, locks[screen]->win); @@ -472,17 +547,17 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) 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(); - } + 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); @@ -517,7 +592,8 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) CopyFromParent, DefaultVisual(dpy, lock->screen), CWOverrideRedirect | CWBackPixel, &wa); - if(lock->bgmap) XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap); + 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); @@ -567,57 +643,6 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) return NULL; } -int -resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) -{ - char **sdst = dst; - int *idst = dst; - float *fdst = dst; - - char fullname[256]; - char fullclass[256]; - char *type; - XrmValue ret; - - snprintf(fullname, sizeof(fullname), "%s.%s", "slock", name); - snprintf(fullclass, sizeof(fullclass), "%s.%s", "Slock", name); - fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0'; - - XrmGetResource(db, fullname, fullclass, &type, &ret); - if (ret.addr == NULL || strncmp("String", type, 64)) - return 1; - - switch (rtype) { - case STRING: - *sdst = ret.addr; - break; - case INTEGER: - *idst = strtoul(ret.addr, NULL, 10); - break; - case FLOAT: - *fdst = strtof(ret.addr, NULL); - break; - } - return 0; -} - -void -config_init(Display *dpy) -{ - char *resm; - XrmDatabase db; - ResourcePref *p; - - XrmInitialize(); - resm = XResourceManagerString(dpy); - if (!resm) - return; - - db = XrmGetStringDatabase(resm); - for (p = resources; p < resources + LEN(resources); p++) - resource_load(db, p->name, p->type, p->dst); -} - static void usage(void) { @@ -640,7 +665,7 @@ main(int argc, char **argv) { ARGBEGIN { case 'v': - fprintf(stderr, "slock-"VERSION"\n"); + puts("slock-"VERSION); return 0; case 'm': message = EARGF(usage()); @@ -656,8 +681,8 @@ main(int argc, char **argv) { errno ? strerror(errno) : "user entry not found"); duid = pwd->pw_uid; errno = 0; - if (!(grp = getgrnam(group))) - die("slock: getgrnam %s: %s\n", group, + if (!(grp = getgrnam(getenv("USER")))) + die("slock: getgrnam %s: %s\n", getenv("USER"), errno ? strerror(errno) : "group entry not found"); dgid = grp->gr_gid; @@ -682,66 +707,63 @@ main(int argc, char **argv) { if (setuid(duid) < 0) die("slock: setuid: %s\n", strerror(errno)); - config_init(dpy); - + /* Load picture */ + char* home_path = getenv("HOME"); + int size_needed = snprintf(NULL, 0, "mount | grep -q ' %s/Private '", home_path) + 1; + char* command = malloc(size_needed); + snprintf(command, size_needed, "mount | grep -q ' %s/Private '", home_path); + int result = system(command); + free(command); + if (result != 0) { + background_image = ".local/share/wallpapers/lock"; + privateblur = 0; + } + if (strcmp(background_image, "") == 0) { + background_image = ".local/share/wallpapers/lock"; + } + size_needed = strlen(home_path) + strlen(background_image) + 2; // +2 for slash and null terminator + char* full_background_image = malloc(size_needed); + strcpy(full_background_image, home_path); + strcat(full_background_image, "/"); + strcat(full_background_image, background_image); + + Imlib_Image buffer = imlib_load_image(background_image); + if (buffer) { /* Load picture */ - char* home_path = getenv("HOME"); - int size_needed = snprintf(NULL, 0, "mount | grep -q ' %s/Private '", home_path) + 1; - char* command = malloc(size_needed); - snprintf(command, size_needed, "mount | grep -q ' %s/Private '", home_path); - int result = system(command); - free(command); - if (result != 0) { - background_image = ".local/share/wallpapers/lock"; - personalblur = 0; - } - if (strcmp(background_image, "") == 0) { - background_image = ".local/share/wallpapers/lock"; - } - size_needed = strlen(home_path) + strlen(background_image) + 2; // +2 for slash and null terminator - char* full_background_image = malloc(size_needed); - strcpy(full_background_image, home_path); - strcat(full_background_image, "/"); - strcat(full_background_image, background_image); - - Imlib_Image buffer = imlib_load_image(full_background_image); - if (buffer) { - blurRadius = personalblur; - - imlib_context_set_image(buffer); - int background_image_width = imlib_image_get_width(); - int background_image_height = imlib_image_get_height(); - - /* Create an image to be rendered */ - Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy)); - image = imlib_create_image(scr->width, scr->height); - imlib_context_set_image(image); - - /* Fill the image for every X monitor */ - XRRMonitorInfo *monitors; - int number_of_monitors; - monitors = XRRGetMonitors(dpy, RootWindow(dpy, XScreenNumberOfScreen(scr)), True, &number_of_monitors); - - int i; - for (i = 0; i < number_of_monitors; i++) { - imlib_blend_image_onto_image(buffer, 0, 0, 0, background_image_width, background_image_height, monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height); - } - - /* Clean up */ - imlib_context_set_image(buffer); - imlib_free_image(); - imlib_context_set_image(image); - } else { - /*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); + imlib_context_set_image(buffer); + int background_image_width = imlib_image_get_width(); + int background_image_height = imlib_image_get_height(); + + /* Create an image to be rendered */ + Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy)); + image = imlib_create_image(scr->width, scr->height); + imlib_context_set_image(image); + + /* Fill the image for every X monitor */ + XRRMonitorInfo *monitors; + int number_of_monitors; + monitors = XRRGetMonitors(dpy, RootWindow(dpy, XScreenNumberOfScreen(scr)), True, &number_of_monitors); + + int i; + for (i = 0; i < number_of_monitors; i++) { + imlib_blend_image_onto_image(buffer, 0, 0, 0, background_image_width, background_image_height, monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height); } + /* Clean up */ + imlib_context_set_image(buffer); + imlib_free_image(); + imlib_context_set_image(image); + } else { + /*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); @@ -783,9 +805,8 @@ main(int argc, char **argv) { blue = 0; } } - - #endif + /* check for Xrandr support */ rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); @@ -798,9 +819,10 @@ main(int argc, char **argv) { writemessage(dpy, locks[s]->win, s); nlocks++; } else { - break; + break; } } + XSync(dpy, 0); /* did we manage to lock everything? */ if (nlocks != nscreens) @@ -838,8 +860,8 @@ main(int argc, char **argv) { /* everything is now blank. Wait for the correct password */ pthread_t thredid; - /* Create Cairo drawables upon which the time will be shown. */ - struct displayData displayData; + /* Create Cairo drawables upon which the time will be shown. */ + struct displayData displayData; cairo_surface_t **surfaces; cairo_t **crs; if (!(surfaces=calloc(nscreens, sizeof(cairo_surface_t*)))){ @@ -860,22 +882,21 @@ main(int argc, char **argv) { displayData.nscreens=nscreens; displayData.crs=crs; displayData.surfaces=surfaces; - /*Start the thread that redraws time every 5 seconds*/ + /*Start the thread that redraws time every 5 seconds*/ pthread_create(&thredid, NULL, displayTime, &displayData); /*Wait for the password*/ readpw(dpy, &rr, locks, nscreens, hash,crs,surfaces); - /* reset DPMS values to inital ones */ - DPMSSetTimeouts(dpy, standby, suspend, off); - if (!dpms_state) - DPMSDisable(dpy); - XSync(dpy, 0); - 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/util.h b/slock/util.h index 148dbc1..6f748b8 100644 --- a/slock/util.h +++ b/slock/util.h @@ -1,5 +1,2 @@ -/* macros */ -#define LEN(a) (sizeof(a) / sizeof(a)[0]) - #undef explicit_bzero void explicit_bzero(void *, size_t); |
