summaryrefslogtreecommitdiff
path: root/slock.c
diff options
context:
space:
mode:
authorJakub Trzeciak <jptrzy@gmail.com>2023-09-11 11:52:04 +0200
committerJakub Trzeciak <jptrzy@gmail.com>2023-09-11 11:52:04 +0200
commit2bac9f3f40bc7006cc2bf57e9c9dcc6dc67a0db4 (patch)
treef0777df5793186484627dd4c3b5b4fabba0f4a6e /slock.c
parent4f045545a25cc02c64bfc08d27ed2ccecb962292 (diff)
downloadslock-2bac9f3f40bc7006cc2bf57e9c9dcc6dc67a0db4.tar.gz
slock-2bac9f3f40bc7006cc2bf57e9c9dcc6dc67a0db4.tar.bz2
slock-2bac9f3f40bc7006cc2bf57e9c9dcc6dc67a0db4.zip
Jp3's ChangesHEADmaster
Diffstat (limited to 'slock.c')
-rw-r--r--slock.c263
1 files changed, 240 insertions, 23 deletions
diff --git a/slock.c b/slock.c
index 5ae738c..d3d3814 100644
--- a/slock.c
+++ b/slock.c
@@ -1,11 +1,13 @@
/* See LICENSE file for license details. */
-#define _XOPEN_SOURCE 500
+#define _XOPEN_SOURCE 500
+#define LENGTH(X) (sizeof X / sizeof X[0])
#if HAVE_SHADOW_H
#include <shadow.h>
#endif
#include <ctype.h>
#include <errno.h>
+#include <math.h>
#include <grp.h>
#include <pwd.h>
#include <stdarg.h>
@@ -15,9 +17,15 @@
#include <unistd.h>
#include <sys/types.h>
#include <X11/extensions/Xrandr.h>
+#ifdef XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include <X11/XKBlib.h>
+#include <X11/Xresource.h>
+#include <Imlib2.h>
#include "arg.h"
#include "util.h"
@@ -25,27 +33,50 @@
char *argv0;
enum {
+ BACKGROUND,
INIT,
INPUT,
FAILED,
+ CAPS,
NUMCOLS
};
-struct lock {
- int screen;
- Window root, win;
- Pixmap pmap;
- unsigned long colors[NUMCOLS];
-};
-
struct xrandr {
int active;
int evbase;
int errbase;
};
+/* Xresources preferences */
+enum resource_type {
+ STRING = 0,
+ INTEGER = 1,
+ FLOAT = 2
+};
+
+typedef struct {
+ char *name;
+ enum resource_type type;
+ void *dst;
+} ResourcePref;
+
#include "config.h"
+struct lock {
+ int screen;
+ Window root, win;
+ Pixmap pmap;
+ Pixmap bgmap;
+ unsigned long colors[NUMCOLS];
+ unsigned int x, y;
+ unsigned int xoff, yoff, mw, mh;
+ Drawable drawable;
+ GC gc;
+ XRectangle rectangles[LENGTH(rectangles)];
+};
+
+Imlib_Image image;
+
static void
die(const char *errstr, ...)
{
@@ -125,21 +156,48 @@ gethash(void)
}
static void
+resizerectangles(struct lock *lock)
+{
+ int i;
+
+ for (i = 0; i < LENGTH(rectangles); i++){
+ lock->rectangles[i].x = (rectangles[i].x * logosize)
+ + lock->xoff + ((lock->mw) / 2) - (logow / 2 * logosize);
+ lock->rectangles[i].y = (rectangles[i].y * logosize)
+ + lock->yoff + ((lock->mh) / 2) - (logoh / 2 * logosize);
+ lock->rectangles[i].width = rectangles[i].width * logosize;
+ lock->rectangles[i].height = rectangles[i].height * logosize;
+ }
+}
+
+static void
+drawlogo(Display *dpy, struct lock *lock, int color)
+{
+ XSetForeground(dpy, lock->gc, lock->colors[color]);
+ XFillRectangles(dpy, lock->win, lock->gc, lock->rectangles, LENGTH(rectangles));
+ XSync(dpy, False);
+}
+
+static void
readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
const char *hash)
{
XRRScreenChangeNotifyEvent *rre;
char buf[32], passwd[256], *inputhash;
- int num, screen, running, failure, oldc;
- unsigned int len, color;
+ int caps, num, screen, running, failure, oldc;
+ unsigned int len, color, indicators;
KeySym ksym;
XEvent ev;
len = 0;
+ caps = 0;
running = 1;
failure = 0;
oldc = INIT;
+ if (!XkbGetIndicatorState(dpy, XkbUseCoreKbd, &indicators))
+ caps = indicators & 1;
+
while (running && !XNextEvent(dpy, &ev)) {
if (ev.type == KeyPress) {
explicit_bzero(&buf, sizeof(buf));
@@ -179,6 +237,9 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
if (len)
passwd[--len] = '\0';
break;
+ case XK_Caps_Lock:
+ caps = !caps;
+ break;
default:
if (num && !iscntrl((int)buf[0]) &&
(len + num < sizeof(passwd))) {
@@ -187,13 +248,15 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
}
break;
}
- color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
+ color = len ? (caps ? CAPS : 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]);
+ //XClearWindow(dpy, locks[screen]->win);
+ drawlogo(dpy, locks[screen], color);
}
oldc = color;
}
@@ -228,6 +291,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
XColor color, dummy;
XSetWindowAttributes wa;
Cursor invisible;
+#ifdef XINERAMA
+ XineramaScreenInfo *info;
+ int n;
+#endif
if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
return NULL;
@@ -235,27 +302,61 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
lock->screen = screen;
lock->root = RootWindow(dpy, lock->screen);
+ if(image)
+ {
+ 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();
+ }
for (i = 0; i < NUMCOLS; i++) {
XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen),
colorname[i], &color, &dummy);
lock->colors[i] = color.pixel;
}
+ lock->x = DisplayWidth(dpy, lock->screen);
+ lock->y = DisplayHeight(dpy, lock->screen);
+#ifdef XINERAMA
+ if ((info = XineramaQueryScreens(dpy, &n))) {
+ lock->xoff = info[0].x_org;
+ lock->yoff = info[0].y_org;
+ lock->mw = info[0].width;
+ lock->mh = info[0].height;
+ } else
+#endif
+ {
+ lock->xoff = lock->yoff = 0;
+ lock->mw = lock->x;
+ lock->mh = lock->y;
+ }
+ lock->drawable = XCreatePixmap(dpy, lock->root,
+ lock->x, lock->y, DefaultDepth(dpy, screen));
+ lock->gc = XCreateGC(dpy, lock->root, 0, NULL);
+ XSetLineAttributes(dpy, lock->gc, 1, LineSolid, CapButt, JoinMiter);
+
/* init */
wa.override_redirect = 1;
- wa.background_pixel = lock->colors[INIT];
+ wa.background_pixel = lock->colors[BACKGROUND];
lock->win = XCreateWindow(dpy, lock->root, 0, 0,
- DisplayWidth(dpy, lock->screen),
- DisplayHeight(dpy, lock->screen),
+ lock->x, lock->y,
0, DefaultDepth(dpy, lock->screen),
CopyFromParent,
DefaultVisual(dpy, lock->screen),
CWOverrideRedirect | CWBackPixel, &wa);
+ if(lock->bgmap)
+ XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap);
lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8);
invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap,
&color, &color, 0, 0);
XDefineCursor(dpy, lock->win, invisible);
+ resizerectangles(lock);
+
/* 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) {
@@ -276,6 +377,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
XSelectInput(dpy, lock->root, SubstructureNotifyMask);
+ drawlogo(dpy, lock, INIT);
return lock;
}
@@ -297,6 +399,57 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
return NULL;
}
+int
+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
+{
+ char **sdst = dst;
+ int *idst = dst;
+ float *fdst = dst;
+
+ char fullname[256];
+ char fullclass[256];
+ char *type;
+ XrmValue ret;
+
+ snprintf(fullname, sizeof(fullname), "%s.%s", "slock", name);
+ snprintf(fullclass, sizeof(fullclass), "%s.%s", "Slock", name);
+ fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0';
+
+ XrmGetResource(db, fullname, fullclass, &type, &ret);
+ if (ret.addr == NULL || strncmp("String", type, 64))
+ return 1;
+
+ switch (rtype) {
+ case STRING:
+ *sdst = ret.addr;
+ break;
+ case INTEGER:
+ *idst = strtoul(ret.addr, NULL, 10);
+ break;
+ case FLOAT:
+ *fdst = strtof(ret.addr, NULL);
+ break;
+ }
+ return 0;
+}
+
+void
+config_init(Display *dpy)
+{
+ char *resm;
+ XrmDatabase db;
+ ResourcePref *p;
+
+ XrmInitialize();
+ resm = XResourceManagerString(dpy);
+ if (!resm)
+ return;
+
+ db = XrmGetStringDatabase(resm);
+ for (p = resources; p < resources + LEN(resources); p++)
+ resource_load(db, p->name, p->type, p->dst);
+}
+
static void
usage(void)
{
@@ -325,13 +478,13 @@ main(int argc, char **argv) {
/* validate drop-user and -group */
errno = 0;
- if (!(pwd = getpwnam(user)))
- die("slock: getpwnam %s: %s\n", user,
+ if (!(pwd = getpwnam(getenv("USER"))))
+ die("slock: getpwnam %s: %s\n", getenv("USER"),
errno ? strerror(errno) : "user entry not found");
duid = pwd->pw_uid;
errno = 0;
- if (!(grp = getgrnam(group)))
- die("slock: getgrnam %s: %s\n", group,
+ if (!(grp = getgrnam(getenv("USER"))))
+ die("slock: getgrnam %s: %s\n", getenv("USER"),
errno ? strerror(errno) : "group entry not found");
dgid = grp->gr_gid;
@@ -355,7 +508,64 @@ main(int argc, char **argv) {
if (setuid(duid) < 0)
die("slock: setuid: %s\n", strerror(errno));
- /* check for Xrandr support */
+ /*Create screenshot Image*/
+ Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy));
+ image = imlib_create_image(scr->width,scr->height);
+ imlib_context_set_image(image);
+ imlib_context_set_display(dpy);
+ imlib_context_set_visual(DefaultVisual(dpy,0));
+ imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr)));
+ imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1);
+
+#ifdef BLUR
+
+ /*Blur function*/
+ imlib_image_blur(blurRadius);
+#endif // BLUR
+
+#ifdef PIXELATION
+ /*Pixelation*/
+ int width = scr->width;
+ int height = scr->height;
+
+ for(int y = 0; y < height; y += pixelSize)
+ {
+ for(int x = 0; x < width; x += pixelSize)
+ {
+ int red = 0;
+ int green = 0;
+ int blue = 0;
+
+ Imlib_Color pixel;
+ Imlib_Color* pp;
+ pp = &pixel;
+ for(int j = 0; j < pixelSize && j < height; j++)
+ {
+ for(int i = 0; i < pixelSize && i < width; i++)
+ {
+ imlib_image_query_pixel(x+i,y+j,pp);
+ red += pixel.red;
+ green += pixel.green;
+ blue += pixel.blue;
+ }
+ }
+ red /= (pixelSize*pixelSize);
+ green /= (pixelSize*pixelSize);
+ blue /= (pixelSize*pixelSize);
+ imlib_context_set_color(red,green,blue,pixel.alpha);
+ imlib_image_fill_rectangle(x,y,pixelSize,pixelSize);
+ red = 0;
+ green = 0;
+ blue = 0;
+ }
+ }
+
+
+#endif
+
+ config_init(dpy);
+
+/* check for Xrandr support */
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
/* get number of screens in display "dpy" and blank them */
@@ -391,5 +601,12 @@ main(int argc, char **argv) {
/* everything is now blank. Wait for the correct password */
readpw(dpy, &rr, locks, nscreens, hash);
+ for (nlocks = 0, s = 0; s < nscreens; s++) {
+ XFreePixmap(dpy, locks[s]->drawable);
+ XFreeGC(dpy, locks[s]->gc);
+ }
+
+ XSync(dpy, 0);
+ XCloseDisplay(dpy);
return 0;
}
Software created with 💖