diff options
author | Sam Chudnick <sam@chudnick.com> | 2023-02-25 22:32:36 -0500 |
---|---|---|
committer | Sam Chudnick <sam@chudnick.com> | 2023-02-25 22:32:36 -0500 |
commit | 63cda0184f7964f541ec77ddb5f47f596acb963c (patch) | |
tree | 66cb36fd94bf7f74d705af3cef710a96584e2105 | |
parent | 4f045545a25cc02c64bfc08d27ed2ccecb962292 (diff) |
Applied foreground and background patch
-rw-r--r-- | config.def.h | 12 | ||||
-rw-r--r-- | config.h | 40 | ||||
-rw-r--r-- | config.mk | 16 | ||||
-rw-r--r-- | slock.c | 156 |
4 files changed, 199 insertions, 25 deletions
diff --git a/config.def.h b/config.def.h deleted file mode 100644 index 9855e21..0000000 --- a/config.def.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | /* user and group to drop privileges to */ | ||
2 | static const char *user = "nobody"; | ||
3 | static const char *group = "nogroup"; | ||
4 | |||
5 | static const char *colorname[NUMCOLS] = { | ||
6 | [INIT] = "black", /* after initialization */ | ||
7 | [INPUT] = "#005577", /* during input */ | ||
8 | [FAILED] = "#CC3333", /* wrong password */ | ||
9 | }; | ||
10 | |||
11 | /* treat a cleared input like a wrong password (color) */ | ||
12 | static const int failonclear = 1; | ||
diff --git a/config.h b/config.h new file mode 100644 index 0000000..ceceeb0 --- /dev/null +++ b/config.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* user and group to drop privileges to */ | ||
2 | static const char *user = "nobody"; | ||
3 | static const char *group = "nogroup"; | ||
4 | |||
5 | static const char *colorname[NUMCOLS] = { | ||
6 | [INIT] = "black", /* after initialization */ | ||
7 | [INPUT] = "#005577", /* during input */ | ||
8 | [FAILED] = "#CC3333", /* wrong password */ | ||
9 | }; | ||
10 | |||
11 | /* treat a cleared input like a wrong password (color) */ | ||
12 | static const int failonclear = 1; | ||
13 | |||
14 | /* insert grid pattern with scale 1:1, the size can be changed with logosize */ | ||
15 | static const int logosize = 75; | ||
16 | /* grid width and height for right center alignment */ | ||
17 | static const int logow = 12; | ||
18 | static const int logoh = 6; | ||
19 | |||
20 | static XRectangle rectangles[9] = { | ||
21 | /* x y w h */ | ||
22 | { 0, 3, 1, 3 }, | ||
23 | { 1, 3, 2, 1 }, | ||
24 | { 0, 5, 8, 1 }, | ||
25 | { 3, 0, 1, 5 }, | ||
26 | { 5, 3, 1, 2 }, | ||
27 | { 7, 3, 1, 2 }, | ||
28 | { 8, 3, 4, 1 }, | ||
29 | { 9, 4, 1, 2 }, | ||
30 | { 11, 4, 1, 2 }, | ||
31 | }; | ||
32 | |||
33 | /*Enable blur*/ | ||
34 | #define BLUR | ||
35 | /*Set blur radius*/ | ||
36 | static const int blurRadius=5; | ||
37 | /*Enable Pixelation*/ | ||
38 | //#define PIXELATION | ||
39 | /*Set pixelation radius*/ | ||
40 | static const int pixelSize=0; | ||
@@ -10,13 +10,21 @@ MANPREFIX = ${PREFIX}/share/man | |||
10 | X11INC = /usr/X11R6/include | 10 | X11INC = /usr/X11R6/include |
11 | X11LIB = /usr/X11R6/lib | 11 | X11LIB = /usr/X11R6/lib |
12 | 12 | ||
13 | # Xinerama | ||
14 | XINERAMALIBS = -lXinerama | ||
15 | XINERAMAFLAGS = -DXINERAMA | ||
16 | |||
17 | # freetype | ||
18 | FREETYPELIBS = -lXft | ||
19 | FREETYPEINC = /usr/include/freetype2 | ||
20 | |||
13 | # includes and libs | 21 | # includes and libs |
14 | INCS = -I. -I/usr/include -I${X11INC} | 22 | INCS = -I. -I/usr/include -I${X11INC} -I${FREETYPEINC} |
15 | LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr | 23 | LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXext -lXrandr -lImlib2 |
16 | 24 | ||
17 | # flags | 25 | # flags |
18 | CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H | 26 | CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ${XINERAMAFLAGS} |
19 | CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} | 27 | CFLAGS = -std=c99 -pedantic -Wall -Ofast ${INCS} ${CPPFLAGS} |
20 | LDFLAGS = -s ${LIBS} | 28 | LDFLAGS = -s ${LIBS} |
21 | COMPATSRC = explicit_bzero.c | 29 | COMPATSRC = explicit_bzero.c |
22 | 30 | ||
@@ -1,5 +1,6 @@ | |||
1 | /* See LICENSE file for license details. */ | 1 | /* See LICENSE file for license details. */ |
2 | #define _XOPEN_SOURCE 500 | 2 | #define _XOPEN_SOURCE 500 |
3 | #define LENGTH(X) (sizeof X / sizeof X[0]) | ||
3 | #if HAVE_SHADOW_H | 4 | #if HAVE_SHADOW_H |
4 | #include <shadow.h> | 5 | #include <shadow.h> |
5 | #endif | 6 | #endif |
@@ -15,9 +16,14 @@ | |||
15 | #include <unistd.h> | 16 | #include <unistd.h> |
16 | #include <sys/types.h> | 17 | #include <sys/types.h> |
17 | #include <X11/extensions/Xrandr.h> | 18 | #include <X11/extensions/Xrandr.h> |
19 | #ifdef XINERAMA | ||
20 | #include <X11/extensions/Xinerama.h> | ||
21 | #endif | ||
18 | #include <X11/keysym.h> | 22 | #include <X11/keysym.h> |
19 | #include <X11/Xlib.h> | 23 | #include <X11/Xlib.h> |
20 | #include <X11/Xutil.h> | 24 | #include <X11/Xutil.h> |
25 | #include <X11/Xft/Xft.h> | ||
26 | #include <Imlib2.h> | ||
21 | 27 | ||
22 | #include "arg.h" | 28 | #include "arg.h" |
23 | #include "util.h" | 29 | #include "util.h" |
@@ -31,11 +37,19 @@ enum { | |||
31 | NUMCOLS | 37 | NUMCOLS |
32 | }; | 38 | }; |
33 | 39 | ||
40 | #include "config.h" | ||
41 | |||
34 | struct lock { | 42 | struct lock { |
35 | int screen; | 43 | int screen; |
36 | Window root, win; | 44 | Window root, win; |
37 | Pixmap pmap; | 45 | Pixmap pmap; |
46 | Pixmap bgmap; | ||
38 | unsigned long colors[NUMCOLS]; | 47 | unsigned long colors[NUMCOLS]; |
48 | unsigned int x, y; | ||
49 | unsigned int xoff, yoff, mw, mh; | ||
50 | Drawable drawable; | ||
51 | GC gc; | ||
52 | XRectangle rectangles[LENGTH(rectangles)]; | ||
39 | }; | 53 | }; |
40 | 54 | ||
41 | struct xrandr { | 55 | struct xrandr { |
@@ -44,7 +58,7 @@ struct xrandr { | |||
44 | int errbase; | 58 | int errbase; |
45 | }; | 59 | }; |
46 | 60 | ||
47 | #include "config.h" | 61 | Imlib_Image image; |
48 | 62 | ||
49 | static void | 63 | static void |
50 | die(const char *errstr, ...) | 64 | die(const char *errstr, ...) |
@@ -125,6 +139,34 @@ gethash(void) | |||
125 | } | 139 | } |
126 | 140 | ||
127 | static void | 141 | static void |
142 | resizerectangles(struct lock *lock) | ||
143 | { | ||
144 | int i; | ||
145 | |||
146 | for (i = 0; i < LENGTH(rectangles); i++){ | ||
147 | lock->rectangles[i].x = (rectangles[i].x * logosize) | ||
148 | + lock->xoff + ((lock->mw) / 2) - (logow / 2 * logosize); | ||
149 | lock->rectangles[i].y = (rectangles[i].y * logosize) | ||
150 | + lock->yoff + ((lock->mh) / 2) - (logoh / 2 * logosize); | ||
151 | lock->rectangles[i].width = rectangles[i].width * logosize; | ||
152 | lock->rectangles[i].height = rectangles[i].height * logosize; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static void | ||
157 | drawlogo(Display *dpy, struct lock *lock, int color) | ||
158 | { | ||
159 | /* | ||
160 | XSetForeground(dpy, lock->gc, lock->colors[BACKGROUND]); | ||
161 | XFillRectangle(dpy, lock->drawable, lock->gc, 0, 0, lock->x, lock->y); */ | ||
162 | lock->drawable = lock->bgmap; | ||
163 | XSetForeground(dpy, lock->gc, lock->colors[color]); | ||
164 | XFillRectangles(dpy, lock->drawable, lock->gc, lock->rectangles, LENGTH(rectangles)); | ||
165 | XCopyArea(dpy, lock->drawable, lock->win, lock->gc, 0, 0, lock->x, lock->y, 0, 0); | ||
166 | XSync(dpy, False); | ||
167 | } | ||
168 | |||
169 | static void | ||
128 | readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, | 170 | readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, |
129 | const char *hash) | 171 | const char *hash) |
130 | { | 172 | { |
@@ -190,10 +232,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, | |||
190 | color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); | 232 | color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); |
191 | if (running && oldc != color) { | 233 | if (running && oldc != color) { |
192 | for (screen = 0; screen < nscreens; screen++) { | 234 | for (screen = 0; screen < nscreens; screen++) { |
193 | XSetWindowBackground(dpy, | 235 | drawlogo(dpy, locks[screen], color); |
194 | locks[screen]->win, | ||
195 | locks[screen]->colors[color]); | ||
196 | XClearWindow(dpy, locks[screen]->win); | ||
197 | } | 236 | } |
198 | oldc = color; | 237 | oldc = color; |
199 | } | 238 | } |
@@ -228,6 +267,10 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) | |||
228 | XColor color, dummy; | 267 | XColor color, dummy; |
229 | XSetWindowAttributes wa; | 268 | XSetWindowAttributes wa; |
230 | Cursor invisible; | 269 | Cursor invisible; |
270 | #ifdef XINERAMA | ||
271 | XineramaScreenInfo *info; | ||
272 | int n; | ||
273 | #endif | ||
231 | 274 | ||
232 | if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) | 275 | if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) |
233 | return NULL; | 276 | return NULL; |
@@ -235,27 +278,60 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) | |||
235 | lock->screen = screen; | 278 | lock->screen = screen; |
236 | lock->root = RootWindow(dpy, lock->screen); | 279 | lock->root = RootWindow(dpy, lock->screen); |
237 | 280 | ||
281 | if(image) | ||
282 | { | ||
283 | lock->bgmap = XCreatePixmap(dpy, lock->root, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), DefaultDepth(dpy, lock->screen)); | ||
284 | imlib_context_set_image(image); | ||
285 | imlib_context_set_display(dpy); | ||
286 | imlib_context_set_visual(DefaultVisual(dpy, lock->screen)); | ||
287 | imlib_context_set_colormap(DefaultColormap(dpy, lock->screen)); | ||
288 | imlib_context_set_drawable(lock->bgmap); | ||
289 | imlib_render_image_on_drawable(0, 0); | ||
290 | imlib_free_image(); | ||
291 | } | ||
238 | for (i = 0; i < NUMCOLS; i++) { | 292 | for (i = 0; i < NUMCOLS; i++) { |
239 | XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), | 293 | XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), |
240 | colorname[i], &color, &dummy); | 294 | colorname[i], &color, &dummy); |
241 | lock->colors[i] = color.pixel; | 295 | lock->colors[i] = color.pixel; |
242 | } | 296 | } |
243 | 297 | ||
298 | lock->x = DisplayWidth(dpy, lock->screen); | ||
299 | lock->y = DisplayHeight(dpy, lock->screen); | ||
300 | #ifdef XINERAMA | ||
301 | if ((info = XineramaQueryScreens(dpy, &n))) { | ||
302 | lock->xoff = info[0].x_org; | ||
303 | lock->yoff = info[0].y_org; | ||
304 | lock->mw = info[0].width; | ||
305 | lock->mh = info[0].height; | ||
306 | } else | ||
307 | #endif | ||
308 | { | ||
309 | lock->xoff = lock->yoff = 0; | ||
310 | lock->mw = lock->x; | ||
311 | lock->mh = lock->y; | ||
312 | } | ||
313 | lock->drawable = XCreatePixmap(dpy, lock->root, | ||
314 | lock->x, lock->y, DefaultDepth(dpy, screen)); | ||
315 | lock->gc = XCreateGC(dpy, lock->root, 0, NULL); | ||
316 | XSetLineAttributes(dpy, lock->gc, 1, LineSolid, CapButt, JoinMiter); | ||
317 | |||
244 | /* init */ | 318 | /* init */ |
245 | wa.override_redirect = 1; | 319 | wa.override_redirect = 1; |
246 | wa.background_pixel = lock->colors[INIT]; | ||
247 | lock->win = XCreateWindow(dpy, lock->root, 0, 0, | 320 | lock->win = XCreateWindow(dpy, lock->root, 0, 0, |
248 | DisplayWidth(dpy, lock->screen), | 321 | lock->x, lock->y, |
249 | DisplayHeight(dpy, lock->screen), | ||
250 | 0, DefaultDepth(dpy, lock->screen), | 322 | 0, DefaultDepth(dpy, lock->screen), |
251 | CopyFromParent, | 323 | CopyFromParent, |
252 | DefaultVisual(dpy, lock->screen), | 324 | DefaultVisual(dpy, lock->screen), |
253 | CWOverrideRedirect | CWBackPixel, &wa); | 325 | CWOverrideRedirect | CWBackPixel, &wa); |
326 | if(lock->bgmap) | ||
327 | XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap); | ||
254 | lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8); | 328 | lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8); |
255 | invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, | 329 | invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, |
256 | &color, &color, 0, 0); | 330 | &color, &color, 0, 0); |
257 | XDefineCursor(dpy, lock->win, invisible); | 331 | XDefineCursor(dpy, lock->win, invisible); |
258 | 332 | ||
333 | resizerectangles(lock); | ||
334 | |||
259 | /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ | 335 | /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ |
260 | for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { | 336 | for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { |
261 | if (ptgrab != GrabSuccess) { | 337 | if (ptgrab != GrabSuccess) { |
@@ -276,6 +352,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) | |||
276 | XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); | 352 | XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); |
277 | 353 | ||
278 | XSelectInput(dpy, lock->root, SubstructureNotifyMask); | 354 | XSelectInput(dpy, lock->root, SubstructureNotifyMask); |
355 | drawlogo(dpy, lock, INIT); | ||
279 | return lock; | 356 | return lock; |
280 | } | 357 | } |
281 | 358 | ||
@@ -355,6 +432,60 @@ main(int argc, char **argv) { | |||
355 | if (setuid(duid) < 0) | 432 | if (setuid(duid) < 0) |
356 | die("slock: setuid: %s\n", strerror(errno)); | 433 | die("slock: setuid: %s\n", strerror(errno)); |
357 | 434 | ||
435 | /*Create screenshot Image*/ | ||
436 | Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy)); | ||
437 | image = imlib_create_image(scr->width,scr->height); | ||
438 | imlib_context_set_image(image); | ||
439 | imlib_context_set_display(dpy); | ||
440 | imlib_context_set_visual(DefaultVisual(dpy,0)); | ||
441 | imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr))); | ||
442 | imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1); | ||
443 | |||
444 | #ifdef BLUR | ||
445 | |||
446 | /*Blur function*/ | ||
447 | imlib_image_blur(blurRadius); | ||
448 | #endif // BLUR | ||
449 | |||
450 | #ifdef PIXELATION | ||
451 | /*Pixelation*/ | ||
452 | int width = scr->width; | ||
453 | int height = scr->height; | ||
454 | |||
455 | for(int y = 0; y < height; y += pixelSize) | ||
456 | { | ||
457 | for(int x = 0; x < width; x += pixelSize) | ||
458 | { | ||
459 | int red = 0; | ||
460 | int green = 0; | ||
461 | int blue = 0; | ||
462 | |||
463 | Imlib_Color pixel; | ||
464 | Imlib_Color* pp; | ||
465 | pp = &pixel; | ||
466 | for(int j = 0; j < pixelSize && j < height; j++) | ||
467 | { | ||
468 | for(int i = 0; i < pixelSize && i < width; i++) | ||
469 | { | ||
470 | imlib_image_query_pixel(x+i,y+j,pp); | ||
471 | red += pixel.red; | ||
472 | green += pixel.green; | ||
473 | blue += pixel.blue; | ||
474 | } | ||
475 | } | ||
476 | red /= (pixelSize*pixelSize); | ||
477 | green /= (pixelSize*pixelSize); | ||
478 | blue /= (pixelSize*pixelSize); | ||
479 | imlib_context_set_color(red,green,blue,pixel.alpha); | ||
480 | imlib_image_fill_rectangle(x,y,pixelSize,pixelSize); | ||
481 | red = 0; | ||
482 | green = 0; | ||
483 | blue = 0; | ||
484 | } | ||
485 | } | ||
486 | |||
487 | |||
488 | #endif | ||
358 | /* check for Xrandr support */ | 489 | /* check for Xrandr support */ |
359 | rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); | 490 | rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); |
360 | 491 | ||
@@ -391,5 +522,12 @@ main(int argc, char **argv) { | |||
391 | /* everything is now blank. Wait for the correct password */ | 522 | /* everything is now blank. Wait for the correct password */ |
392 | readpw(dpy, &rr, locks, nscreens, hash); | 523 | readpw(dpy, &rr, locks, nscreens, hash); |
393 | 524 | ||
525 | for (nlocks = 0, s = 0; s < nscreens; s++) { | ||
526 | XFreePixmap(dpy, locks[s]->drawable); | ||
527 | XFreeGC(dpy, locks[s]->gc); | ||
528 | } | ||
529 | |||
530 | XSync(dpy, 0); | ||
531 | XCloseDisplay(dpy); | ||
394 | return 0; | 532 | return 0; |
395 | } | 533 | } |