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.
Includes patch for using image file as the background.
Requirements
------------
@ -13,6 +15,10 @@ Installation
Edit config.mk to match your local setup (slock is installed into
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
(if necessary as root):

View File

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

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
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
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS}
CPPFLAGS += -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
CFLAGS += -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS += -s ${LIBS}
COMPATSRC = explicit_bzero.c
# On OpenBSD and Darwin remove -lcrypt from LIBS
#LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXext -lXrandr
# On *BSD remove -DHAVE_SHADOW_H from 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
#COMPATSRC =

View File

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

67
slock.c
View File

@ -18,8 +18,9 @@
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <Imlib2.h>
#include <getopt.h>
#include "arg.h"
#include "util.h"
char *argv0;
@ -35,6 +36,7 @@ struct lock {
int screen;
Window root, win;
Pixmap pmap;
Pixmap bgmap;
unsigned long colors[NUMCOLS];
};
@ -177,7 +179,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
break;
case XK_BackSpace:
if (len)
passwd[--len] = '\0';
passwd[len--] = '\0';
break;
default:
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);
if (running && oldc != color) {
for (screen = 0; screen < nscreens; screen++) {
XSetWindowBackground(dpy,
locks[screen]->win,
locks[screen]->colors[color]);
XClearWindow(dpy, locks[screen]->win);
if(locks[screen]->bgmap)
XSetWindowBackgroundPixmap(dpy, locks[screen]->win, locks[screen]->bgmap);
else
XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]);
}
oldc = color;
}
@ -201,26 +203,18 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
rre = (XRRScreenChangeNotifyEvent*)&ev;
for (screen = 0; screen < nscreens; screen++) {
if (locks[screen]->win == rre->window) {
if (rre->rotation == RR_Rotate_90 ||
rre->rotation == RR_Rotate_270)
XResizeWindow(dpy, locks[screen]->win,
rre->height, rre->width);
else
XResizeWindow(dpy, locks[screen]->win,
rre->width, rre->height);
XClearWindow(dpy, locks[screen]->win);
break;
}
}
} else {
for (screen = 0; screen < nscreens; screen++)
} else for (screen = 0; screen < nscreens; screen++)
XRaiseWindow(dpy, locks[screen]->win);
}
}
}
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};
int i, ptgrab, kbgrab;
@ -241,6 +235,16 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
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 */
wa.override_redirect = 1;
wa.background_pixel = lock->colors[INIT];
@ -256,6 +260,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
&color, &color, 0, 0);
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 */
for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) {
if (ptgrab != GrabSuccess) {
@ -300,7 +308,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
static 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
@ -314,14 +322,25 @@ main(int argc, char **argv) {
const char *hash;
Display *dpy;
int s, nlocks, nscreens;
Imlib_Image image;
int use_bg_image = 0;
int option = 0;
ARGBEGIN {
while ((option = getopt(argc, argv,"vi:")) != -1) {
switch (option) {
case 'v' :
fprintf(stderr, "slock-"VERSION"\n");
return 0;
default:
usage();
} ARGEND
die("slock-"VERSION" mod-bgimage\n");
break;
case 'i' :
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 */
errno = 0;
@ -363,7 +382,7 @@ 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, image, use_bg_image)) != NULL)
nlocks++;
else
break;