applied Fernando Silveira's multiscreen patch for old style multihead setups - … | |
git clone git://git.suckless.org/slock | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 732d2b3bf5da3a1883b3246062aa556a59b8517c | |
parent 0cb05bdb75ac13f010d51e267007ca1c869763ec | |
Author: Anselm R Garbe <[email protected]> | |
Date: Thu, 26 Nov 2009 12:53:26 +0000 | |
applied Fernando Silveira's multiscreen patch for old style multihead setups | |
Diffstat: | |
M slock.c | 220 +++++++++++++++++++++--------… | |
1 file changed, 151 insertions(+), 69 deletions(-) | |
--- | |
diff --git a/slock.c b/slock.c | |
@@ -5,6 +5,7 @@ | |
#endif | |
#include <ctype.h> | |
+#include <errno.h> | |
#include <pwd.h> | |
#include <stdarg.h> | |
#include <stdlib.h> | |
@@ -15,31 +16,42 @@ | |
#include <X11/keysym.h> | |
#include <X11/Xlib.h> | |
#include <X11/Xutil.h> | |
-#include <X11/extensions/dpms.h> | |
#if HAVE_BSD_AUTH | |
#include <login_cap.h> | |
#include <bsd_auth.h> | |
#endif | |
+struct st_lock { | |
+ int screen; | |
+ Window root, w; | |
+ Pixmap pmap; | |
+}; | |
+ | |
+extern const char *__progname; | |
+ | |
static void | |
die(const char *errstr, ...) { | |
va_list ap; | |
+ fprintf(stderr, "%s: ", __progname); | |
va_start(ap, errstr); | |
vfprintf(stderr, errstr, ap); | |
va_end(ap); | |
+ fprintf(stderr, "\n"); | |
+ fflush(stderr); | |
+ | |
exit(EXIT_FAILURE); | |
} | |
#ifndef HAVE_BSD_AUTH | |
static const char * | |
-get_password() { /* only run as root */ | |
+get_password(void) { /* only run as root */ | |
const char *rval; | |
struct passwd *pw; | |
if(geteuid() != 0) | |
- die("slock: cannot retrieve password entry (make sure to suid … | |
+ die("cannot retrieve password entry (make sure to suid slock)"… | |
pw = getpwuid(getuid()); | |
endpwent(); | |
rval = pw->pw_passwd; | |
@@ -55,81 +67,34 @@ get_password() { /* only run as root */ | |
/* drop privileges */ | |
if(setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) | |
- die("slock: cannot drop privileges\n"); | |
+ die("cannot drop privileges"); | |
return rval; | |
} | |
#endif | |
-int | |
-main(int argc, char **argv) { | |
- char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; | |
+static void | |
+#ifdef HAVE_BSD_AUTH | |
+read_password(Display *dpy) | |
+#else | |
+read_password(Display *dpy, const char *pws) | |
+#endif | |
+{ | |
char buf[32], passwd[256]; | |
- int num, screen; | |
+ int num; | |
-#ifndef HAVE_BSD_AUTH | |
- const char *pws; | |
-#endif | |
unsigned int len; | |
Bool running = True; | |
- Cursor invisible; | |
- Display *dpy; | |
KeySym ksym; | |
- Pixmap pmap; | |
- Window root, w; | |
- XColor black, dummy; | |
XEvent ev; | |
- XSetWindowAttributes wa; | |
- CARD16 standby, suspend, off; | |
- | |
- if((argc == 2) && !strcmp("-v", argv[1])) | |
- die("slock-"VERSION", © 2006-2008 Anselm R Garbe\n"); | |
- else if(argc != 1) | |
- die("usage: slock [-v]\n"); | |
- | |
-#ifndef HAVE_BSD_AUTH | |
- pws = get_password(); | |
-#endif | |
- | |
- if(!(dpy = XOpenDisplay(0))) | |
- die("slock: cannot open display\n"); | |
- screen = DefaultScreen(dpy); | |
- root = RootWindow(dpy, screen); | |
- /* init */ | |
- wa.override_redirect = 1; | |
- wa.background_pixel = BlackPixel(dpy, screen); | |
- w = XCreateWindow(dpy, root, 0, 0, DisplayWidth(dpy, screen), DisplayH… | |
- 0, DefaultDepth(dpy, screen), CopyFromParent, | |
- DefaultVisual(dpy, screen), CWOverrideRedirect | CWBac… | |
- XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &… | |
- pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8); | |
- invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0); | |
- XDefineCursor(dpy, w, invisible); | |
- XMapRaised(dpy, w); | |
- for(len = 1000; len; len--) { | |
- if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonRele… | |
- GrabModeAsync, GrabModeAsync, None, invisible, Current… | |
- break; | |
- usleep(1000); | |
- } | |
- if((running = running && (len > 0))) { | |
- for(len = 1000; len; len--) { | |
- if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabM… | |
- == GrabSuccess) | |
- break; | |
- usleep(1000); | |
- } | |
- running = (len > 0); | |
- } | |
len = 0; | |
- XSync(dpy, False); | |
+ running = True; | |
- if(DPMSCapable(dpy)) { /* save and customize DPMS settings */ | |
- DPMSGetTimeouts(dpy, &standby, &suspend, &off); | |
- DPMSSetTimeouts(dpy, 10, 30, 90); | |
- } | |
+ /* As "slock" stands for "Simple X display locker", the DPMS settings | |
+ * had been removed and you can set it with "xset" or some other | |
+ * utility. This way the user can easily set a customized DPMS | |
+ * timeout. */ | |
- /* main event loop */ | |
while(running && !XNextEvent(dpy, &ev)) { | |
if(ev.type == KeyPress) { | |
buf[0] = 0; | |
@@ -172,12 +137,129 @@ main(int argc, char **argv) { | |
} | |
} | |
} | |
- if(DPMSCapable(dpy)) { /* restore DPMS settings */ | |
- DPMSSetTimeouts(dpy, standby, suspend, off); | |
- } | |
+} | |
+ | |
+static void | |
+unlockscreen(Display *dpy, struct st_lock *lock) { | |
+ if (dpy == NULL || lock == NULL) | |
+ return; | |
+ | |
XUngrabPointer(dpy, CurrentTime); | |
- XFreePixmap(dpy, pmap); | |
- XDestroyWindow(dpy, w); | |
+ XFreePixmap(dpy, lock->pmap); | |
+ XDestroyWindow(dpy, lock->w); | |
+ | |
+ free(lock); | |
+} | |
+ | |
+static struct st_lock * | |
+lockscreen(Display *dpy, int screen) { | |
+ char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; | |
+ unsigned int len; | |
+ struct st_lock *lock; | |
+ Bool running = True; | |
+ XColor black, dummy; | |
+ XSetWindowAttributes wa; | |
+ Cursor invisible; | |
+ | |
+ if (dpy == NULL || screen < 0) | |
+ return NULL; | |
+ | |
+ lock = malloc(sizeof(struct st_lock)); | |
+ if (lock == NULL) | |
+ return NULL; | |
+ | |
+ lock->screen = screen; | |
+ | |
+ lock->root = RootWindow(dpy, lock->screen); | |
+ | |
+ /* init */ | |
+ wa.override_redirect = 1; | |
+ wa.background_pixel = BlackPixel(dpy, lock->screen); | |
+ lock->w = XCreateWindow(dpy, lock->root, 0, 0, DisplayWidth(dpy, lock-… | |
+ 0, DefaultDepth(dpy, lock->screen), CopyFromParent, | |
+ DefaultVisual(dpy, lock->screen), CWOverrideRedirect |… | |
+ XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), "black", &bl… | |
+ lock->pmap = XCreateBitmapFromData(dpy, lock->w, curs, 8, 8); | |
+ invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &black, &… | |
+ XDefineCursor(dpy, lock->w, invisible); | |
+ XMapRaised(dpy, lock->w); | |
+ for(len = 1000; len; len--) { | |
+ if(XGrabPointer(dpy, lock->root, False, ButtonPressMask | Butt… | |
+ GrabModeAsync, GrabModeAsync, None, invisible, Current… | |
+ break; | |
+ usleep(1000); | |
+ } | |
+ if((running = running && (len > 0))) { | |
+ for(len = 1000; len; len--) { | |
+ if(XGrabKeyboard(dpy, lock->root, True, GrabModeAsync,… | |
+ == GrabSuccess) | |
+ break; | |
+ usleep(1000); | |
+ } | |
+ running = (len > 0); | |
+ } | |
+ | |
+ if (!running) { | |
+ unlockscreen(dpy, lock); | |
+ lock = NULL; | |
+ } | |
+ | |
+ return lock; | |
+} | |
+ | |
+static void | |
+usage(void) { | |
+ fprintf(stderr, "usage: %s -v", __progname); | |
+ exit(EXIT_FAILURE); | |
+} | |
+ | |
+int | |
+main(int argc, char **argv) { | |
+#ifndef HAVE_BSD_AUTH | |
+ const char *pws; | |
+#endif | |
+ Display *dpy; | |
+ int nscreens, screen; | |
+ | |
+ struct st_lock **locks; | |
+ | |
+ if((argc == 2) && !strcmp("-v", argv[1])) | |
+ die("slock-%s, © 2006-2008 Anselm R Garbe", VERSION); | |
+ else if(argc != 1) | |
+ usage(); | |
+ | |
+#ifndef HAVE_BSD_AUTH | |
+ pws = get_password(); | |
+#endif | |
+ | |
+ if(!(dpy = XOpenDisplay(0))) | |
+ die("cannot open display"); | |
+ | |
+ /* Get the number of screens in display "dpy" and blank them all. */ | |
+ nscreens = ScreenCount(dpy); | |
+ locks = malloc(sizeof(struct st_lock *) * nscreens); | |
+ if (locks == NULL) | |
+ die("malloc: %s", strerror(errno)); | |
+ | |
+ for (screen = 0; screen < nscreens; screen++) | |
+ locks[screen] = lockscreen(dpy, screen); | |
+ | |
+ XSync(dpy, False); | |
+ | |
+ /* Everything is now blank. Now wait for the correct password. */ | |
+#ifdef HAVE_BSD_AUTH | |
+ read_password(dpy); | |
+#else | |
+ read_password(dpy, pws); | |
+#endif | |
+ | |
+ /* Password ok, unlock everything and quit. */ | |
+ for (screen = 0; screen < nscreens; screen++) | |
+ unlockscreen(dpy, locks[screen]); | |
+ | |
+ free(locks); | |
+ | |
XCloseDisplay(dpy); | |
+ | |
return 0; | |
} |