summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2025-02-09 03:10:22 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2025-02-09 03:10:22 +0900
commit36f7b343c714566d5bf931e768f0536a12d67c2f (patch)
tree2040321e9984b1d8191f144f6b81f05f38acb8d7
parent365403254a39ceac9797e430d4a62ec6c7b2f99c (diff)
updates
-rw-r--r--slock/LICENSE1
-rw-r--r--slock/Makefile55
-rw-r--r--slock/config.def.h98
-rw-r--r--slock/config.h77
-rw-r--r--slock/config.mk3
-rw-r--r--slock/patches/slock-alternate-colors-20220921-35633d4.diff49
-rw-r--r--slock/patches/slock-background-image-20220318-1c5a538.diff149
-rw-r--r--slock/patches/slock-capscolor-20220921-35633d4.diff88
-rw-r--r--slock/patches/slock-dpms-20231017-4f04554.diff86
-rw-r--r--slock/patches/slock-foreground-and-background-20210611-35633d4.diff340
-rw-r--r--slock/patches/slock-git-20161012-control-clear.diff27
-rw-r--r--slock/patches/slock-message-xft-20210315-ae681c5.diff237
-rw-r--r--slock/patches/slock-noxbell-0.2.diff37
-rw-r--r--slock/patches/slock-pam_auth-20190207-35633d4.diff154
-rw-r--r--slock/patches/slock-passthrough-20240812-809d3c0.diff104
-rw-r--r--slock/patches/slock-secret-password-1.4.diff43
-rw-r--r--slock/patches/slock-showtime-1.5.diff193
-rw-r--r--slock/patches/slock-user-1.5.diff47
-rw-r--r--slock/slock.126
-rw-r--r--slock/slock.c491
-rw-r--r--slock/util.h3
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);