feat: choose background image.

This commit is contained in:
Felix Jian 2023-04-15 23:49:27 +02:00
parent 35633d4567
commit 49d586053d
Signed by: flex
GPG Key ID: 2FB8FBECB390C227
6 changed files with 75 additions and 36 deletions

6
README
View File

@ -2,6 +2,8 @@ slock - simple screen locker
============================ ============================
simple screen locker utility for X. simple screen locker utility for X.
Includes patch for using image file as the background.
Requirements Requirements
------------ ------------
@ -13,6 +15,10 @@ Installation
Edit config.mk to match your local setup (slock is installed into Edit config.mk to match your local setup (slock is installed into
the /usr/local namespace by default). the /usr/local namespace by default).
Apply the background image patch:
patch -N < slock-image.patch
Afterwards enter the following command to build and install slock Afterwards enter the following command to build and install slock
(if necessary as root): (if necessary as root):

View File

@ -1,6 +1,6 @@
/* user and group to drop privileges to */ /* user and group to drop privileges to */
static const char *user = "nobody"; static const char *user = "nobody";
static const char *group = "nogroup"; static const char *group = "nobody";
static const char *colorname[NUMCOLS] = { static const char *colorname[NUMCOLS] = {
[INIT] = "black", /* after initialization */ [INIT] = "black", /* after initialization */

12
config.h Normal file
View File

@ -0,0 +1,12 @@
/* user and group to drop privileges to */
static const char *user = "nobody";
static const char *group = "nobody";
static const char *colorname[NUMCOLS] = {
[INIT] = "black", /* after initialization */
[INPUT] = "#005577", /* during input */
[FAILED] = "#CC3333", /* wrong password */
};
/* treat a cleared input like a wrong password (color) */
static const int failonclear = 1;

View File

@ -12,19 +12,19 @@ X11LIB = /usr/X11R6/lib
# includes and libs # includes and libs
INCS = -I. -I/usr/include -I${X11INC} 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 # flags
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H CPPFLAGS += -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
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
# On OpenBSD and Darwin remove -lcrypt from LIBS # On OpenBSD and Darwin remove -lcrypt from LIBS
#LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXext -lXrandr #LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXext -lXrandr
# On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS # On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS
# On NetBSD add -D_NETBSD_SOURCE to CPPFLAGS # On NetBSD add -D_NETBSD_SOURCE to CPPFLAGS
#CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_NETBSD_SOURCE #CPPFLAGS += -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_NETBSD_SOURCE
# On OpenBSD set COMPATSRC to empty # On OpenBSD set COMPATSRC to empty
#COMPATSRC = #COMPATSRC =

View File

@ -5,7 +5,7 @@
.Nd simple X screen locker .Nd simple X screen locker
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl v .Op Fl v i
.Op Ar cmd Op Ar arg ... .Op Ar cmd Op Ar arg ...
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm .Nm
@ -16,6 +16,8 @@ is executed after the screen has been locked.
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl v .It Fl v
Print version information to stdout and exit. Print version information to stdout and exit.
.It Fl i
Load image as background.
.El .El
.Sh SECURITY CONSIDERATIONS .Sh SECURITY CONSIDERATIONS
To make sure a locked screen can not be bypassed by switching VTs To make sure a locked screen can not be bypassed by switching VTs

69
slock.c
View File

@ -18,8 +18,9 @@
#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 <getopt.h>
#include "arg.h"
#include "util.h" #include "util.h"
char *argv0; char *argv0;
@ -35,6 +36,7 @@ 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];
}; };
@ -177,7 +179,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
break; break;
case XK_BackSpace: case XK_BackSpace:
if (len) if (len)
passwd[--len] = '\0'; passwd[len--] = '\0';
break; break;
default: default:
if (num && !iscntrl((int)buf[0]) && if (num && !iscntrl((int)buf[0]) &&
@ -190,10 +192,10 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); color = len ? 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
XClearWindow(dpy, locks[screen]->win); XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]);
} }
oldc = color; oldc = color;
} }
@ -201,26 +203,18 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
rre = (XRRScreenChangeNotifyEvent*)&ev; rre = (XRRScreenChangeNotifyEvent*)&ev;
for (screen = 0; screen < nscreens; screen++) { for (screen = 0; screen < nscreens; screen++) {
if (locks[screen]->win == rre->window) { if (locks[screen]->win == rre->window) {
if (rre->rotation == RR_Rotate_90 ||
rre->rotation == RR_Rotate_270)
XResizeWindow(dpy, locks[screen]->win,
rre->height, rre->width);
else
XResizeWindow(dpy, locks[screen]->win, XResizeWindow(dpy, locks[screen]->win,
rre->width, rre->height); rre->width, rre->height);
XClearWindow(dpy, locks[screen]->win); XClearWindow(dpy, locks[screen]->win);
break;
} }
} }
} else { } else for (screen = 0; screen < nscreens; screen++)
for (screen = 0; screen < nscreens; screen++)
XRaiseWindow(dpy, locks[screen]->win); XRaiseWindow(dpy, locks[screen]->win);
} }
}
} }
static struct lock * static struct lock *
lockscreen(Display *dpy, struct xrandr *rr, int screen) lockscreen(Display *dpy, struct xrandr *rr, int screen,Imlib_Image *image, int use_bg_image)
{ {
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
int i, ptgrab, kbgrab; int i, ptgrab, kbgrab;
@ -241,6 +235,16 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
lock->colors[i] = color.pixel; lock->colors[i] = color.pixel;
} }
if(image && use_bg_image == 1) {
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();
}
/* init */ /* init */
wa.override_redirect = 1; wa.override_redirect = 1;
wa.background_pixel = lock->colors[INIT]; wa.background_pixel = lock->colors[INIT];
@ -256,6 +260,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
&color, &color, 0, 0); &color, &color, 0, 0);
XDefineCursor(dpy, lock->win, invisible); XDefineCursor(dpy, lock->win, invisible);
if(lock->bgmap)
XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap);
/* 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) {
@ -300,7 +308,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
static void static void
usage(void) usage(void)
{ {
die("usage: slock [-v] [cmd [arg ...]]\n"); die("\nusage: slock [options]\noptions:\n\t-v\tPrint version and exit.\n\t-i\t<full path to image file to display>\n");
} }
int int
@ -314,14 +322,25 @@ main(int argc, char **argv) {
const char *hash; const char *hash;
Display *dpy; Display *dpy;
int s, nlocks, nscreens; int s, nlocks, nscreens;
Imlib_Image image;
int use_bg_image = 0;
int option = 0;
ARGBEGIN { while ((option = getopt(argc, argv,"vi:")) != -1) {
case 'v': switch (option) {
fprintf(stderr, "slock-"VERSION"\n"); case 'v' :
return 0; die("slock-"VERSION" mod-bgimage\n");
default: break;
usage(); case 'i' :
} ARGEND use_bg_image = 1;
image = imlib_load_image(optarg);
if(!image) {
die("slock: unable to load image.\n");
}
break;
default: usage();
}
}
/* validate drop-user and -group */ /* validate drop-user and -group */
errno = 0; errno = 0;
@ -363,7 +382,7 @@ main(int argc, char **argv) {
if (!(locks = calloc(nscreens, sizeof(struct lock *)))) if (!(locks = calloc(nscreens, sizeof(struct lock *))))
die("slock: out of memory\n"); die("slock: out of memory\n");
for (nlocks = 0, s = 0; s < nscreens; s++) { for (nlocks = 0, s = 0; s < nscreens; s++) {
if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) if ((locks[s] = lockscreen(dpy, &rr, s, image, use_bg_image)) != NULL)
nlocks++; nlocks++;
else else
break; break;