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 | } |
