Implement options for forking, beeping and DPMS. Bump version to 1.0.

pull/1/head
Michael Stapelberg 2009-05-10 12:48:16 +02:00
parent 715e46b45e
commit 4a9d3d7365
3 changed files with 123 additions and 58 deletions

View File

@ -1,5 +1,5 @@
# slock version
VERSION = 0.9
# i3lock version
VERSION = 1.0
# Customize below to fit your system
@ -13,16 +13,13 @@ MANDIR = $(DESTDIR)$(PREFIX)/share/man
# includes and libs
INCS = -I. -I/usr/include -I${X11INC}
LIBS = -L/usr/lib -L${X11LIB} -lX11 -lpam
LIBS = -L${X11LIB} -lX11 -lpam -lXext
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\" -DHAVE_SHADOW_H
CPPFLAGS = -DVERSION=\"${VERSION}\"
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS}
# On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS and add -DHAVE_BSD_AUTH
# On OpenBSD and Darwin remove -lcrypt from LIBS
# compiler and linker
CC = cc
INSTALL=install

View File

@ -8,13 +8,17 @@
.fi
..
.TH i3lock 1 "MARCH 2009" Linux "User Manuals"
.TH i3lock 1 "MAY 2009" Linux "User Manuals"
.SH NAME
i3lock \- slightly improved version of slock
.SH SYNOPSIS
i3lock takes no arguments
.B i3lock
.RB [\|\-v\|]
.RB [\|\-n\|]
.RB [\|\-b\|]
.RB [\|\-d\|]
.SH DESCRIPTION
.B i3lock
@ -37,8 +41,28 @@ does not call XBell(). This is important because
.B i3lock/slock
think you've entered a password when resuming from suspend, at least sometimes.
Since version 1.0, i3lock supports PAM.
.SH OPTIONS
.TP
.B \-v, \-\-version
Display the version of your
.B i3lock
was forked from slock-0.9
.TP
.B \-n, \-\-nofork
Don't fork after starting.
.TP
.B \-b, \-\-beep
Enable beeping. Be sure to not do this when you are about to annoy other people,
like when opening your laptop in a boring lecture.
.TP
.B \-d, \-\-dpms
Enable turning off your screen using DPMS. Note that, when you do not specify this
option, DPMS will turn off your screen after 15 minutes of inactivity anyways (if
you did not disable this in your X server).
.SH AUTHOR
Michael Stapelberg <michael+i3lock at stapelberg dot de>

140
i3lock.c
View File

@ -26,7 +26,9 @@
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/dpms.h>
#include <stdbool.h>
#include <getopt.h>
#include <security/pam_appl.h>
@ -75,10 +77,16 @@ static int conv_callback(int num_msg, const struct pam_message **msg,
int main(int argc, char *argv[]) {
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
char buf[32];
char *username;
int num, screen;
unsigned int len;
bool running = true;
/* By default, fork, dont beep and dont turn off monitor */
bool dont_fork = false;
bool beep = false;
bool dpms = false;
Cursor invisible;
Display *dpy;
KeySym ksym;
@ -88,30 +96,54 @@ int main(int argc, char *argv[]) {
XEvent ev;
XSetWindowAttributes wa;
/* TODO: use getopt */
if((argc == 2) && !strcmp("-v", argv[1]))
die("i3lock-"VERSION", © 2009 Michael Stapelberg\n"
"based on slock, which is © 2006-2008 Anselm R Garbe\n");
else if(argc != 1)
die("usage: i3lock [-v]\n");
pam_handle_t *handle;
struct pam_conv conv = {conv_callback, NULL};
struct pam_conv conv;
conv.conv = conv_callback;
char opt;
int optind = 0;
static struct option long_options[] = {
{"version", no_argument, NULL, 'v'},
{"nofork", no_argument, NULL, 'n'},
{"beep", no_argument, NULL, 'b'},
{"dpms", no_argument, NULL, 'd'},
{NULL, no_argument, NULL, 0}
};
int ret = pam_start("i3lock", getenv("USER"), &conv, &handle);
printf("pam_start = %d\n", ret);
while ((opt = getopt_long(argc, argv, "vnbd", long_options, &optind)) != -1) {
switch (opt) {
case 'v':
die("i3lock-"VERSION", © 2009 Michael Stapelberg\n"
"based on slock, which is © 2006-2008 Anselm R Garbe\n");
case 'n':
dont_fork = true;
break;
case 'b':
beep = true;
break;
case 'd':
dpms = true;
break;
default:
die("i3lock: Unknown option. Syntax: i3lock [-v] [-n] [-b] [-d]\n");
}
}
if ((username = getenv("USER")) == NULL)
die("USER environment variable not set, please set it.\n");
int ret = pam_start("i3lock", username, &conv, &handle);
if (ret != PAM_SUCCESS)
die("error = %s\n", pam_strerror(handle, ret));
die("PAM: %s\n", pam_strerror(handle, ret));
if(!(dpy = XOpenDisplay(0)))
die("slock: cannot open display\n");
die("i3lock: cannot open display\n");
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if (fork() != 0)
return 0;
if (!dont_fork) {
if (fork() != 0)
return 0;
}
/* init */
wa.override_redirect = 1;
@ -144,41 +176,53 @@ int main(int argc, char *argv[]) {
/* main event loop */
while(running && !XNextEvent(dpy, &ev)) {
if(ev.type == KeyPress) {
buf[0] = 0;
num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0);
if(IsKeypadKey(ksym)) {
if(ksym == XK_KP_Enter)
ksym = XK_Return;
else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
ksym = (ksym - XK_KP_0) + XK_0;
if (len == 0 && dpms && DPMSCapable(dpy)) {
DPMSEnable(dpy);
DPMSForceLevel(dpy, DPMSModeOff);
}
if(ev.type != KeyPress)
continue;
buf[0] = 0;
num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0);
if(IsKeypadKey(ksym)) {
if(ksym == XK_KP_Enter)
ksym = XK_Return;
else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
ksym = (ksym - XK_KP_0) + XK_0;
}
if(IsFunctionKey(ksym) ||
IsKeypadKey(ksym) ||
IsMiscFunctionKey(ksym) ||
IsPFKey(ksym) ||
IsPrivateKeypadKey(ksym))
continue;
switch(ksym) {
case XK_Return:
passwd[len] = 0;
if ((ret = pam_authenticate(handle, 0)) == PAM_SUCCESS)
running = false;
else {
fprintf(stderr, "PAM: %s\n", pam_strerror(handle, ret));
if (beep)
XBell(dpy, 100);
}
if(IsFunctionKey(ksym) || IsKeypadKey(ksym)
|| IsMiscFunctionKey(ksym) || IsPFKey(ksym)
|| IsPrivateKeypadKey(ksym))
continue;
switch(ksym) {
case XK_Return:
passwd[len] = 0;
if ((ret = pam_authenticate(handle, 0)) == PAM_SUCCESS)
running = false;
else fprintf(stderr, "PAM: %s\n", pam_strerror(handle, ret));
len = 0;
break;
case XK_Escape:
len = 0;
break;
case XK_BackSpace:
if (len > 0)
len--;
break;
default:
if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) {
memcpy(passwd + len, buf, num);
len += num;
}
break;
len = 0;
break;
case XK_Escape:
len = 0;
break;
case XK_BackSpace:
if (len > 0)
len--;
break;
default:
if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) {
memcpy(passwd + len, buf, num);
len += num;
}
break;
}
}
XUngrabPointer(dpy, CurrentTime);