@ -33,18 +33,18 @@ enum {
# include "config.h"
# include "config.h"
typedef struct {
struct lock {
int screen ;
int screen ;
Window root , win ;
Window root , win ;
Pixmap pmap ;
Pixmap pmap ;
unsigned long colors [ NUMCOLS ] ;
unsigned long colors [ NUMCOLS ] ;
} Lock ;
} ;
static Lock * * locks ;
struct xrandr {
static int nscreens ;
int active ;
static Bool rr ;
int evbase ;
static int rrev base;
int err base ;
static int rrerrbase ;
} ;
static void
static void
die ( const char * errstr , . . . )
die ( const char * errstr , . . . )
@ -123,7 +123,8 @@ getpw(void)
}
}
static void
static void
readpw ( Display * dpy , const char * pws )
readpw ( Display * dpy , struct xrandr * rr , struct lock * * locks , int nscreens ,
const char * pws )
{
{
char buf [ 32 ] , passwd [ 256 ] , * encrypted ;
char buf [ 32 ] , passwd [ 256 ] , * encrypted ;
int num , screen , running , failure ;
int num , screen , running , failure ;
@ -194,7 +195,7 @@ readpw(Display *dpy, const char *pws)
}
}
oldc = color ;
oldc = color ;
}
}
} else if ( rr & & ev . type = = rrevbase + RRScreenChangeNotify ) {
} else if ( rr - > active & & ev . type = = rr - > evbase + RRScreenChangeNotify ) {
XRRScreenChangeNotifyEvent * rre = ( XRRScreenChangeNotifyEvent * ) & ev ;
XRRScreenChangeNotifyEvent * 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 ) {
@ -207,44 +208,17 @@ readpw(Display *dpy, const char *pws)
}
}
}
}
static void
static struct lock *
unlockscreen ( Display * dpy , Lock * lock )
lockscreen ( Display * dpy , struct xrandr * rr , int screen )
{
if ( dpy = = NULL | | lock = = NULL )
return ;
XUngrabPointer ( dpy , CurrentTime ) ;
XUngrabKeyboard ( dpy , CurrentTime ) ;
XFreeColors ( dpy , DefaultColormap ( dpy , lock - > screen ) , lock - > colors , NUMCOLS , 0 ) ;
XFreePixmap ( dpy , lock - > pmap ) ;
XDestroyWindow ( dpy , lock - > win ) ;
free ( lock ) ;
}
static void
cleanup ( Display * dpy )
{
int s ;
for ( s = 0 ; s < nscreens ; + + s )
unlockscreen ( dpy , locks [ s ] ) ;
free ( locks ) ;
XCloseDisplay ( dpy ) ;
}
static Lock *
lockscreen ( Display * dpy , int screen )
{
{
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 ;
L ock * lock ;
struct lock * lock ;
XColor color , dummy ;
XColor color , dummy ;
XSetWindowAttributes wa ;
XSetWindowAttributes wa ;
Cursor invisible ;
Cursor invisible ;
if ( dpy = = NULL | | screen < 0 | | ! ( lock = malloc ( sizeof ( L ock) ) ) )
if ( dpy = = NULL | | screen < 0 | | ! ( lock = malloc ( sizeof ( struct lock ) ) ) )
return NULL ;
return NULL ;
lock - > screen = screen ;
lock - > screen = screen ;
@ -281,7 +255,7 @@ lockscreen(Display *dpy, int screen)
/* input is grabbed: we can lock the screen */
/* input is grabbed: we can lock the screen */
if ( ptgrab = = GrabSuccess & & kbgrab = = GrabSuccess ) {
if ( ptgrab = = GrabSuccess & & kbgrab = = GrabSuccess ) {
XMapRaised ( dpy , lock - > win ) ;
XMapRaised ( dpy , lock - > win ) ;
if ( rr )
if ( rr - > active )
XRRSelectInput ( dpy , lock - > win , RRScreenChangeNotifyMask ) ;
XRRSelectInput ( dpy , lock - > win , RRScreenChangeNotifyMask ) ;
XSelectInput ( dpy , lock - > root , SubstructureNotifyMask ) ;
XSelectInput ( dpy , lock - > root , SubstructureNotifyMask ) ;
@ -312,13 +286,15 @@ usage(void)
int
int
main ( int argc , char * * argv ) {
main ( int argc , char * * argv ) {
struct xrandr rr ;
struct lock * * locks ;
struct passwd * pwd ;
struct passwd * pwd ;
struct group * grp ;
struct group * grp ;
uid_t duid ;
uid_t duid ;
gid_t dgid ;
gid_t dgid ;
const char * pws ;
const char * pws ;
Display * dpy ;
Display * dpy ;
int s , nlocks ;
int s , nlocks , nscreens ;
ARGBEGIN {
ARGBEGIN {
case ' v ' :
case ' v ' :
@ -360,16 +336,14 @@ main(int argc, char **argv) {
die ( " slock: setuid: %s \n " , strerror ( errno ) ) ;
die ( " slock: setuid: %s \n " , strerror ( errno ) ) ;
/* check for Xrandr support */
/* check for Xrandr support */
rr = XRRQueryExtension ( dpy , & rrevbase , & rrerrbase ) ;
rr . active = XRRQueryExtension ( dpy , & rr . evbase , & rr . errbase ) ;
/* get number of screens in display "dpy" and blank them */
/* get number of screens in display "dpy" and blank them */
nscreens = ScreenCount ( dpy ) ;
nscreens = ScreenCount ( dpy ) ;
if ( ! ( locks = calloc ( nscreens , sizeof ( Lock * ) ) ) ) {
if ( ! ( locks = calloc ( nscreens , sizeof ( struct lock * ) ) ) )
XCloseDisplay ( dpy ) ;
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 , s ) ) ! = NULL )
if ( ( locks [ s ] = lockscreen ( dpy , & rr , s ) ) ! = NULL )
nlocks + + ;
nlocks + + ;
else
else
break ;
break ;
@ -377,16 +351,13 @@ main(int argc, char **argv) {
XSync ( dpy , 0 ) ;
XSync ( dpy , 0 ) ;
/* did we manage to lock everything? */
/* did we manage to lock everything? */
if ( nlocks ! = nscreens ) {
if ( nlocks ! = nscreens )
cleanup ( dpy ) ;
return 1 ;
return 1 ;
}
/* run post-lock command */
/* run post-lock command */
if ( argc > 0 ) {
if ( argc > 0 ) {
switch ( fork ( ) ) {
switch ( fork ( ) ) {
case - 1 :
case - 1 :
cleanup ( dpy ) ;
die ( " slock: fork failed: %s \n " , strerror ( errno ) ) ;
die ( " slock: fork failed: %s \n " , strerror ( errno ) ) ;
case 0 :
case 0 :
if ( close ( ConnectionNumber ( dpy ) ) < 0 )
if ( close ( ConnectionNumber ( dpy ) ) < 0 )
@ -399,10 +370,7 @@ 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 , pws ) ;
readpw ( dpy , & rr , locks , nscreens , pws ) ;
/* password ok, unlock everything and quit */
cleanup ( dpy ) ;
return 0 ;
return 0 ;
}
}