1
0
mirror of https://github.com/tiyn/slock.git synced 2025-10-15 20:31:21 +02:00

26 Commits

Author SHA1 Message Date
fedcfc595b changed sudo commands 2023-12-20 04:08:52 +01:00
940aa6c46b changed sudo commands 2023-12-20 04:06:26 +01:00
8eae6d56b3 added secret-password patch for readme 2023-10-29 03:10:54 +01:00
632909ee67 cleanup 2023-10-29 03:09:23 +01:00
5a88ca3a66 made secret-password an array again 2023-10-29 03:00:48 +01:00
TiynGER
eeb357c356 added secret-password patch 2023-10-29 02:54:43 +01:00
TiynGER
f6f743c04d added secret-password patch 2023-10-29 02:52:03 +01:00
TiynGER
535d3daa33 added secret-password patch 2023-10-29 02:37:09 +01:00
TiynGER
62f56acf86 updated logo size 2023-10-26 17:07:07 +02:00
b8f4624e30 changed logo to tiyn logo 2023-10-26 17:05:05 +02:00
744232078f changed colors 2023-10-26 14:45:56 +02:00
e738d89c47 added capscolor patch to readme 2023-10-26 02:58:19 +02:00
737545828a added capscolor patch to master 2023-10-26 02:57:38 +02:00
d396a4a4c1 added capscolor patch 2023-10-26 02:51:41 +02:00
b1c8a9dda1 added control-clear patch to readme 2023-10-26 02:41:21 +02:00
cc6c284600 added control-clear patch to master 2023-10-26 02:40:44 +02:00
6b5d4811eb added control-clear patch 2023-10-26 02:36:52 +02:00
a8518168e5 remove unneeded code of dwmlogo patch 2023-10-25 23:28:18 +02:00
72b4407a7b added dwmlogo patch to master 2023-10-25 17:05:18 +02:00
11041fad4c added dwmlogo patch 2023-10-25 16:50:28 +02:00
0033cc887d move bg to cache 2023-10-24 18:57:27 +02:00
3922b40c0a updated gitignore 2023-10-24 18:48:43 +02:00
f7bf0a3ea9 added background-image patch 2023-10-24 18:47:36 +02:00
d59cbb3d75 Merge branch 'background-image' 2023-10-24 18:28:00 +02:00
7a531c1744 added background-image patch 2023-10-24 18:27:53 +02:00
1d78f190a7 readme updated 2023-08-22 15:18:39 +02:00
9 changed files with 732 additions and 32 deletions

View File

@@ -7,7 +7,10 @@ This is my patched version of slock. The base version is directly from suckless.
The list below shows the currently applied patches to the master branch. The list below shows the currently applied patches to the master branch.
- slock-background-image-20220318-1c5a538.diff (shows a background image in locked state) - slock-background-image-20220318-1c5a538.diff (shows a background image in locked state)
- slock-capscolor-20220921-35633d4.diff (displays a separate color if caps is set)
- slock-dwmlogo-20210324.diff (adds dwm logo on lock screen) - slock-dwmlogo-20210324.diff (adds dwm logo on lock screen)
- slock-git-20161012-control-clear.diff (doesnt turn logo red when pressing control keys)
- slock-secret-password-1.4.diff (modified) (can give additional passwords that run commands)
## Installation ## Installation

View File

@@ -4,9 +4,9 @@ static const char *group = "nobody";
static const char *colorname[NUMCOLS] = { static const char *colorname[NUMCOLS] = {
[INIT] = "#2d2d2d", /* after initialization */ [INIT] = "#2d2d2d", /* after initialization */
[BACKGROUND] = "black", /* after initialization */
[INPUT] = "#005577", /* during input */ [INPUT] = "#005577", /* during input */
[FAILED] = "#CC3333", /* wrong password */ [FAILED] = "#cc3333", /* wrong password */
[CAPS] = "#ff0000", /* CapsLock on */
}; };
/* treat a cleared input like a wrong password (color) */ /* treat a cleared input like a wrong password (color) */
@@ -15,20 +15,40 @@ static const int failonclear = 1;
/* Background image path, should be available to the user above */ /* Background image path, should be available to the user above */
static const char* background_image = "/home/user/.local/share/lock"; static const char* background_image = "/home/user/.local/share/lock";
/* insert grid pattern with scale 1:1, the size can be changed with logosize */ /* insert grid pattern with scale 1:1, the size can be changed with logosize */
static const int logosize = 75; static const int logosize = 40;
static const int logow = 12; /* grid width and height for right center alignment*/ static const int logow = 10; /* grid width and height for right center alignment*/
static const int logoh = 6; static const int logoh = 15;
static XRectangle rectangles[9] = { static XRectangle rectangles[12] = {
/* x y w h */ /* x y w h */
{ 0, 3, 1, 3 }, { 0, 0, 1, 3 },
{ 1, 3, 2, 1 }, { 0, 7, 4, 2 },
{ 0, 5, 8, 1 }, { 1, 0, 1, 4 },
{ 3, 0, 1, 5 }, { 2, 2, 1, 3 },
{ 5, 3, 1, 2 }, { 3, 3, 1, 3 },
{ 7, 3, 1, 2 }, { 4, 0, 2, 2 },
{ 8, 3, 4, 1 }, { 4, 4, 2, 11 },
{ 9, 4, 1, 2 }, { 6, 3, 1, 3 },
{ 11, 4, 1, 2 }, { 6, 7, 4, 2 },
{ 7, 2, 1, 3 },
{ 8, 0, 1, 4 },
{ 9, 0, 1, 3 },
}; };
/* allow control key to trigger fail on clear */
static const int controlkeyclear = 1;
/* struct for secret passwords and commands */
struct secretpass {
char const *pass;
char const *command;
};
/* list of secret passwords and their commands */
static const struct secretpass scom[1] = {
/* Password command */
{"shutdown", "sudo shutdown -h now"},
};
/* length of entries in scom */
static const int entrylen = 1;

View File

@@ -10,12 +10,20 @@ MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib X11LIB = /usr/X11R6/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lXft
FREETYPEINC = /usr/include/freetype2
# includes and libs # includes and libs
INCS = -I. -I/usr/include -I${X11INC} INCS = -I. -I/usr/include -I${X11INC} -I${FREETYPEINC}
LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXext -lXrandr -lImlib2
# flags # flags
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ${XINERAMAFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS} LDFLAGS = -s ${LIBS}
COMPATSRC = explicit_bzero.c COMPATSRC = explicit_bzero.c

View File

@@ -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

View File

@@ -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

246
slock-dwmlogo-20210324.diff Normal file
View File

@@ -0,0 +1,246 @@
diff --git a/config.def.h b/config.def.h
index 9855e21..0940fb8 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,10 +3,30 @@ static const char *user = "nobody";
static const char *group = "nogroup";
static const char *colorname[NUMCOLS] = {
- [INIT] = "black", /* after initialization */
+ [BACKGROUND] = "black", /* after initialization */
+ [INIT] = "#2d2d2d", /* after initialization */
[INPUT] = "#005577", /* during input */
[FAILED] = "#CC3333", /* wrong password */
};
/* 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;
+static const int logow = 12; /* grid width and height for right center alignment*/
+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 },
+
+};
diff --git a/config.mk b/config.mk
index 74429ae..08356e8 100644
--- a/config.mk
+++ b/config.mk
@@ -10,12 +10,20 @@ MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
+# Xinerama, comment if you don't want it
+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
# flags
-CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
+CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ${XINERAMAFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS}
COMPATSRC = explicit_bzero.c
diff --git a/slock.c b/slock.c
index 5ae738c..3ea9b7f 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,13 @@
#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 "arg.h"
#include "util.h"
@@ -25,17 +30,25 @@
char *argv0;
enum {
+ BACKGROUND,
INIT,
INPUT,
FAILED,
NUMCOLS
};
+#include "config.h"
+
struct lock {
int screen;
Window root, win;
Pixmap pmap;
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,8 +57,6 @@ struct xrandr {
int errbase;
};
-#include "config.h"
-
static void
die(const char *errstr, ...)
{
@@ -124,6 +135,32 @@ 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);
+ 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 +227,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 +262,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;
@@ -241,12 +279,31 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
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];
+ wa.background_pixel = lock->colors[BACKGROUND];
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),
@@ -256,6 +313,8 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
&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 +335,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;
}
@@ -391,5 +451,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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,33 @@
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 */
s
+static const int 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
@@ -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);
+ }
+ }
+

152
slock.c
View File

@@ -1,5 +1,6 @@
/* See LICENSE file for license details. */ /* 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 #if HAVE_SHADOW_H
#include <shadow.h> #include <shadow.h>
#endif #endif
@@ -15,9 +16,15 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <Imlib2.h>
#include <X11/Xft/Xft.h>
#include <X11/XKBlib.h>
#include "arg.h" #include "arg.h"
#include "util.h" #include "util.h"
@@ -28,14 +35,23 @@ enum {
INIT, INIT,
INPUT, INPUT,
FAILED, FAILED,
CAPS,
NUMCOLS NUMCOLS
}; };
#include "config.h"
struct lock { struct lock {
int screen; int screen;
Window root, win; Window root, win;
Pixmap pmap; Pixmap pmap;
Pixmap bgmap;
unsigned long colors[NUMCOLS]; unsigned long colors[NUMCOLS];
unsigned int x, y;
unsigned int xoff, yoff, mw, mh;
Drawable drawable;
GC gc;
XRectangle rectangles[LENGTH(rectangles)];
}; };
struct xrandr { struct xrandr {
@@ -44,8 +60,7 @@ struct xrandr {
int errbase; int errbase;
}; };
#include "config.h" Imlib_Image image;
static void static void
die(const char *errstr, ...) die(const char *errstr, ...)
{ {
@@ -124,22 +139,49 @@ gethash(void)
return hash; return hash;
} }
static void
resizerectangles(struct lock *lock)
{
int i;
for (i = 0; i < LENGTH(rectangles); i++){
lock->rectangles[i].x = (rectangles[i].x * logosize)
+ lock->xoff + ((lock->mw) / 2) - (logow / 2 * logosize);
lock->rectangles[i].y = (rectangles[i].y * logosize)
+ lock->yoff + ((lock->mh) / 2) - (logoh / 2 * logosize);
lock->rectangles[i].width = rectangles[i].width * logosize;
lock->rectangles[i].height = rectangles[i].height * logosize;
}
}
static void
drawlogo(Display *dpy, struct lock *lock, int color)
{
XSetForeground(dpy, lock->gc, lock->colors[color]);
XFillRectangles(dpy, lock->win, lock->gc, lock->rectangles, LENGTH(rectangles));
XSync(dpy, False);
}
static void static void
readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
const char *hash) const char *hash)
{ {
XRRScreenChangeNotifyEvent *rre; XRRScreenChangeNotifyEvent *rre;
char buf[32], passwd[256], *inputhash; char buf[32], passwd[256], *inputhash;
int num, screen, running, failure, oldc; int caps, num, screen, running, failure, oldc;
unsigned int len, color; unsigned int len, color, indicators;
KeySym ksym; KeySym ksym;
XEvent ev; XEvent ev;
len = 0; len = 0;
caps = 0;
running = 1; running = 1;
failure = 0; failure = 0;
oldc = INIT; oldc = INIT;
if (!XkbGetIndicatorState(dpy, XkbUseCoreKbd, &indicators))
caps = indicators & 1;
while (running && !XNextEvent(dpy, &ev)) { while (running && !XNextEvent(dpy, &ev)) {
if (ev.type == KeyPress) { if (ev.type == KeyPress) {
explicit_bzero(&buf, sizeof(buf)); explicit_bzero(&buf, sizeof(buf));
@@ -160,6 +202,12 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
case XK_Return: case XK_Return:
passwd[len] = '\0'; passwd[len] = '\0';
errno = 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))) if (!(inputhash = crypt(passwd, hash)))
fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); fprintf(stderr, "slock: crypt: %s\n", strerror(errno));
else else
@@ -179,21 +227,27 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
if (len) if (len)
passwd[--len] = '\0'; passwd[--len] = '\0';
break; break;
case XK_Caps_Lock:
caps = !caps;
break;
default: default:
if (num && !iscntrl((int)buf[0]) && if (controlkeyclear && iscntrl((int)buf[0]))
(len + num < sizeof(passwd))) { continue;
if (num && (len + num < sizeof(passwd))) {
memcpy(passwd + len, buf, num); memcpy(passwd + len, buf, num);
len += num; len += num;
} }
break; break;
} }
color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); color = len ? (caps ? CAPS : INPUT) : (failure || failonclear ? FAILED : INIT);
if (running && oldc != color) { if (running && oldc != color) {
for (screen = 0; screen < nscreens; screen++) { for (screen = 0; screen < nscreens; screen++) {
XSetWindowBackground(dpy, if (locks[screen]->bgmap)
locks[screen]->win, XSetWindowBackgroundPixmap(dpy, locks[screen]->win, locks[screen]->bgmap);
locks[screen]->colors[color]); else
XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]);
XClearWindow(dpy, locks[screen]->win); XClearWindow(dpy, locks[screen]->win);
drawlogo(dpy, locks[screen], color);
} }
oldc = color; oldc = color;
} }
@@ -228,6 +282,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
XColor color, dummy; XColor color, dummy;
XSetWindowAttributes wa; XSetWindowAttributes wa;
Cursor invisible; Cursor invisible;
#ifdef XINERAMA
XineramaScreenInfo *info;
int n;
#endif
if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
return NULL; return NULL;
@@ -235,27 +293,61 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
lock->screen = screen; lock->screen = screen;
lock->root = RootWindow(dpy, lock->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++) { for (i = 0; i < NUMCOLS; i++) {
XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen),
colorname[i], &color, &dummy); colorname[i], &color, &dummy);
lock->colors[i] = color.pixel; 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 */ /* init */
wa.override_redirect = 1; wa.override_redirect = 1;
wa.background_pixel = lock->colors[INIT]; wa.background_pixel = lock->colors[INIT];
lock->win = XCreateWindow(dpy, lock->root, 0, 0, lock->win = XCreateWindow(dpy, lock->root, 0, 0,
DisplayWidth(dpy, lock->screen), lock->x, lock->y,
DisplayHeight(dpy, lock->screen),
0, DefaultDepth(dpy, lock->screen), 0, DefaultDepth(dpy, lock->screen),
CopyFromParent, CopyFromParent,
DefaultVisual(dpy, lock->screen), DefaultVisual(dpy, lock->screen),
CWOverrideRedirect | CWBackPixel, &wa); CWOverrideRedirect | CWBackPixel, &wa);
if(lock->bgmap)
XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap);
lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8); lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8);
invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap,
&color, &color, 0, 0); &color, &color, 0, 0);
XDefineCursor(dpy, lock->win, invisible); XDefineCursor(dpy, lock->win, invisible);
resizerectangles(lock);
/* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) {
if (ptgrab != GrabSuccess) { if (ptgrab != GrabSuccess) {
@@ -276,6 +368,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
XSelectInput(dpy, lock->root, SubstructureNotifyMask); XSelectInput(dpy, lock->root, SubstructureNotifyMask);
drawlogo(dpy, lock, INIT);
return lock; return lock;
} }
@@ -355,6 +448,32 @@ main(int argc, char **argv) {
if (setuid(duid) < 0) if (setuid(duid) < 0)
die("slock: setuid: %s\n", strerror(errno)); 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 */ /* check for Xrandr support */
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
@@ -391,5 +510,12 @@ main(int argc, char **argv) {
/* everything is now blank. Wait for the correct password */ /* everything is now blank. Wait for the correct password */
readpw(dpy, &rr, locks, nscreens, hash); 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; return 0;
} }