feat: choose background image.
This commit is contained in:
parent
35633d4567
commit
49d586053d
6
README
6
README
|
@ -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):
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
10
config.mk
10
config.mk
|
@ -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 =
|
||||||
|
|
||||||
|
|
4
slock.1
4
slock.1
|
@ -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
|
||||||
|
|
75
slock.c
75
slock.c
|
@ -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 ||
|
XResizeWindow(dpy, locks[screen]->win,
|
||||||
rre->rotation == RR_Rotate_270)
|
rre->width, rre->height);
|
||||||
XResizeWindow(dpy, locks[screen]->win,
|
|
||||||
rre->height, rre->width);
|
|
||||||
else
|
|
||||||
XResizeWindow(dpy, locks[screen]->win,
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue