diff --git a/suckless/slock/config.def.h b/suckless/slock/config.def.h index 5b9bb95..3c60cfc 100644 --- a/suckless/slock/config.def.h +++ b/suckless/slock/config.def.h @@ -10,16 +10,28 @@ static const char *colorname[NUMCOLS] = { [BLOCKS] = "#ffffff", /* key feedback block */ }; +/* default message */ +static const char * message = "Suckless: Software that sucks less."; + +/* text color */ +static const char * text_color = "#ffffff"; + +/* text size (must be a valid size) */ +static const char * font_name = "6x10"; + /* * Xresources preferences to load at startup */ ResourcePref resources[] = { - { "color0", STRING, &colorname[INIT] }, - { "color4", STRING, &colorname[INPUT] }, - { "color1", STRING, &colorname[FAILED] }, - { "color3", STRING, &colorname[CAPS] }, + { "locked", STRING, &colorname[INIT] }, + { "input", STRING, &colorname[INPUT] }, + { "failed", STRING, &colorname[FAILED] }, + { "capslock", STRING, &colorname[CAPS] }, + { "message", STRING, &message }, + { "text_color", STRING, &text_color }, + { "font_name", STRING, &font_name }, }; /* lock screen opacity */ @@ -31,7 +43,17 @@ static const int failonclear = 1; +/* Enable blur */ +#define BLUR +/* Set blur radius */ +static const int blurRadius = 5; +/* Enable Pixelation */ +//#define PIXELATION +/* Set pixelation radius */ +static const int pixelSize = 10; +/* allow control key to trigger fail on clear */ +static const int controlkeyclear = 0; /* time in seconds before the monitor shuts down */ static const int monitortime = 5; @@ -48,3 +70,5 @@ static const int blocks_y = 0; static const int blocks_count = 10; +/* time in seconds to cancel lock with mouse movement */ +static const int timetocancel = 4; diff --git a/suckless/slock/config.h b/suckless/slock/config.h index 9c76a3a..aa64841 100644 --- a/suckless/slock/config.h +++ b/suckless/slock/config.h @@ -10,16 +10,28 @@ static const char *colorname[NUMCOLS] = { [BLOCKS] = "#ffffff", /* key feedback block */ }; +/* default message */ +static const char * message = "Suckless: Software that sucks less."; + +/* text color */ +static const char * text_color = "#ffffff"; + +/* text size (must be a valid size) */ +static const char * font_name = "6x13"; + /* * Xresources preferences to load at startup */ ResourcePref resources[] = { - { "color0", STRING, &colorname[INIT] }, - { "color4", STRING, &colorname[INPUT] }, - { "color1", STRING, &colorname[FAILED] }, - { "color3", STRING, &colorname[CAPS] }, + { "locked", STRING, &colorname[INIT] }, + { "input", STRING, &colorname[INPUT] }, + { "failed", STRING, &colorname[FAILED] }, + { "capslock", STRING, &colorname[CAPS] }, + { "message", STRING, &message }, + { "text_color", STRING, &text_color }, + { "font_name", STRING, &font_name }, }; /* lock screen opacity */ @@ -28,6 +40,21 @@ static const float alpha = 0.9; /* treat a cleared input like a wrong password (color) */ static const int failonclear = 1; + + + +/* Enable blur */ +//#define BLUR +/* Set blur radius */ +static const int blurRadius = 5; +/* Enable Pixelation */ +#define PIXELATION +/* Set pixelation radius */ +static const int pixelSize = 10; + +/* allow control key to trigger fail on clear */ +static const int controlkeyclear = 1; + /* time in seconds before the monitor shuts down */ static const int monitortime = 5; @@ -41,3 +68,7 @@ static const int blocks_y = 0; // Number of blocks static const int blocks_count = 10; + + +/* time in seconds to cancel lock with mouse movement */ +static const int timetocancel = 3; diff --git a/suckless/slock/config.mk b/suckless/slock/config.mk index 4eff4ab..8570b63 100644 --- a/suckless/slock/config.mk +++ b/suckless/slock/config.mk @@ -10,22 +10,28 @@ MANPREFIX = ${PREFIX}/share/man X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib +# Uncomment for BSD +#BSD=-D_BSD_SOURCE + +# Uncomment for NetBSD +#NETBSD=-D_NETBSD_SOURCE + # Uncomment for message patch / MESSAGE_PATCH / COLORMESSAGE_PATCH / DWM_LOGO_PATCH -#XINERAMA=-lXinerama -#XINERAMAFLAGS = -DXINERAMA +XINERAMA=-lXinerama +XINERAMAFLAGS = -DXINERAMA # Uncomment for pam auth patch / PAMAUTH_PATCH #PAM=-lpam -# Uncomment for blur pixelated screen patch / BLUR_PIXELATED_SCREEN_PATCH -#IMLIB=-lImlib2 +# Uncomment for blur pixelated screen and background image patches / BLUR_PIXELATED_SCREEN_PATCH, BACKGROUND_IMAGE_PATCH +IMLIB=-lImlib2 # includes and libs INCS = -I. -I/usr/include -I${X11INC} LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ${XINERAMA} ${PAM} ${IMLIB} # flags -CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ${XINERAMAFLAGS} +CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H ${XINERAMAFLAGS} ${BSD} ${NETBSD} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} COMPATSRC = explicit_bzero.c diff --git a/suckless/slock/patch/blur_pixelated_screen.c b/suckless/slock/patch/blur_pixelated_screen.c new file mode 100644 index 0000000..eecdf51 --- /dev/null +++ b/suckless/slock/patch/blur_pixelated_screen.c @@ -0,0 +1,70 @@ +#include + +Imlib_Image image; + +void +render_lock_image(Display *dpy, struct lock *lock, Imlib_Image image) +{ + 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(); + } +} + +void +create_lock_image(Display *dpy) +{ + /* 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 +} diff --git a/suckless/slock/patch/blur_pixelated_screen.h b/suckless/slock/patch/blur_pixelated_screen.h new file mode 100644 index 0000000..a6b3397 --- /dev/null +++ b/suckless/slock/patch/blur_pixelated_screen.h @@ -0,0 +1,4 @@ +#include + +static void create_lock_image(Display *dpy); +static void render_lock_image(Display *dpy, struct lock *lock, Imlib_Image image); diff --git a/suckless/slock/patch/colormessage.c b/suckless/slock/patch/colormessage.c new file mode 100644 index 0000000..9d1b49d --- /dev/null +++ b/suckless/slock/patch/colormessage.c @@ -0,0 +1,128 @@ +#include + +/* global count to prevent repeated error messages */ +int count_error = 0; + +static int +readescapedint(const char *str, int *i) { + int n = 0; + if (str[*i]) + ++*i; + while(str[*i] && str[*i] != ';' && str[*i] != 'm') { + n = 10 * n + str[*i] - '0'; + ++*i; + } + return n; +} + +static void +writemessage(Display *dpy, Window win, int screen) +{ + int len, line_len, width, height, s_width, s_height, i, k, tab_size, r, g, b, escaped_int, curr_line_len; + XGCValues gr_values; + XFontStruct *fontinfo; + XColor color, dummy; + XineramaScreenInfo *xsi; + GC gc; + fontinfo = XLoadQueryFont(dpy, font_name); + + if (fontinfo == NULL) { + if (count_error == 0) { + fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name); + fprintf(stderr, "slock: Try listing fonts with 'slock -f'\n"); + count_error++; + } + return; + } + + tab_size = 8 * XTextWidth(fontinfo, " ", 1); + + XAllocNamedColor(dpy, DefaultColormap(dpy, screen), + text_color, &color, &dummy); + + gr_values.font = fontinfo->fid; + gr_values.foreground = color.pixel; + gc=XCreateGC(dpy,win,GCFont+GCForeground, &gr_values); + + /* To prevent "Uninitialized" warnings. */ + xsi = NULL; + + /* + * Start formatting and drawing text + */ + + len = strlen(message); + + /* Max max line length (cut at '\n') */ + line_len = curr_line_len = 0; + k = 0; + for (i = 0; i < len; i++) { + if (message[i] == '\n') { + curr_line_len = 0; + k++; + } else if (message[i] == 0x1b) { + while (i < len && message[i] != 'm') { + i++; + } + if (i == len) + die("slock: unclosed escape sequence\n"); + } else { + curr_line_len += XTextWidth(fontinfo, message + i, 1); + if (curr_line_len > line_len) + line_len = curr_line_len; + } + } + /* If there is only one line */ + if (line_len == 0) + line_len = len; + + if (XineramaIsActive(dpy)) { + xsi = XineramaQueryScreens(dpy, &i); + s_width = xsi[0].width; + s_height = xsi[0].height; + } else { + s_width = DisplayWidth(dpy, screen); + s_height = DisplayHeight(dpy, screen); + } + height = s_height*3/7 - (k*20)/3; + width = (s_width - line_len)/2; + + line_len = 0; + /* print the text while parsing 24 bit color ANSI escape codes*/ + for (i = k = 0; i < len; i++) { + switch (message[i]) { + case '\n': + line_len = 0; + while (message[i + 1] == '\t') { + line_len += tab_size; + i++; + } + k++; + break; + case 0x1b: + i++; + if (message[i] == '[') { + escaped_int = readescapedint(message, &i); + if (escaped_int == 39) + continue; + if (escaped_int != 38) + die("slock: unknown escape sequence%d\n", escaped_int); + if (readescapedint(message, &i) != 2) + die("slock: only 24 bit color supported\n"); + r = readescapedint(message, &i) & 0xff; + g = readescapedint(message, &i) & 0xff; + b = readescapedint(message, &i) & 0xff; + XSetForeground(dpy, gc, r << 16 | g << 8 | b); + } else + die("slock: unknown escape sequence\n"); + break; + default: + XDrawString(dpy, win, gc, width + line_len, height + 20 * k, message + i, 1); + line_len += XTextWidth(fontinfo, message + i, 1); + } + } + + /* xsi should not be NULL anyway if Xinerama is active, but to be safe */ + if (XineramaIsActive(dpy) && xsi != NULL) + XFree(xsi); +} diff --git a/suckless/slock/patch/include.c b/suckless/slock/patch/include.c index 342c3cf..23e0660 100644 --- a/suckless/slock/patch/include.c +++ b/suckless/slock/patch/include.c @@ -1,5 +1,7 @@ /* Patches */ +#include "blur_pixelated_screen.c" +#include "colormessage.c" #include "keypress_feedback.c" diff --git a/suckless/slock/patch/include.h b/suckless/slock/patch/include.h index 527729b..d3551df 100644 --- a/suckless/slock/patch/include.h +++ b/suckless/slock/patch/include.h @@ -1,4 +1,5 @@ /* Patches */ +#include "blur_pixelated_screen.h" diff --git a/suckless/slock/slock.c b/suckless/slock/slock.c index 141ff79..f6834a1 100644 --- a/suckless/slock/slock.c +++ b/suckless/slock/slock.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #ifdef XINERAMA #include @@ -33,6 +35,7 @@ char *argv0; +static time_t locktime; enum { INIT, @@ -56,16 +59,17 @@ typedef struct { void *dst; } ResourcePref; + #include "config.h" struct lock { int screen; Window root, win; Pixmap pmap; + Pixmap bgmap; unsigned long colors[NUMCOLS]; }; - struct xrandr { int active; int evbase; @@ -178,6 +182,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, while (running && !XNextEvent(dpy, &ev)) { + running = !((time(NULL) - locktime < timetocancel) && (ev.type == MotionNotify)); if (ev.type == KeyPress) { explicit_bzero(&buf, sizeof(buf)); num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0); @@ -221,9 +226,19 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, case XK_Caps_Lock: caps = !caps; break; + case XF86XK_AudioLowerVolume: + case XF86XK_AudioMute: + case XF86XK_AudioRaiseVolume: + case XF86XK_AudioPlay: + case XF86XK_AudioStop: + case XF86XK_AudioPrev: + case XF86XK_AudioNext: + XSendEvent(dpy, DefaultRootWindow(dpy), True, KeyPressMask, &ev); + break; default: - if (num && !iscntrl((int)buf[0]) && - (len + num < sizeof(passwd))) + if (controlkeyclear && iscntrl((int)buf[0])) + continue; + if (num && (len + num < sizeof(passwd))) { memcpy(passwd + len, buf, num); len += num; @@ -236,10 +251,12 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, 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]); + 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); + writemessage(dpy, locks[screen]->win, screen); } oldc = color; } @@ -282,6 +299,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) lock->screen = screen; lock->root = RootWindow(dpy, lock->screen); + render_lock_image(dpy, lock, image); for (i = 0; i < NUMCOLS; i++) { XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), @@ -300,6 +318,8 @@ lockscreen(Display *dpy, struct xrandr *rr, int 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); @@ -328,6 +348,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); XSelectInput(dpy, lock->root, SubstructureNotifyMask); + locktime = time(NULL); unsigned int opacity = (unsigned int)(alpha * 0xffffffff); XChangeProperty(dpy, lock->win, XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False), XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&opacity, 1L); XSync(dpy, False); @@ -355,7 +376,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) static void usage(void) { - die("usage: slock [-v] [cmd [arg ...]]\n"); + die("usage: slock [-v] [-f] [-m message] [cmd [arg ...]]\n"); } int @@ -370,10 +391,23 @@ main(int argc, char **argv) { Display *dpy; int s, nlocks, nscreens; CARD16 standby, suspend, off; + int i, count_fonts; + char **font_names; ARGBEGIN { case 'v': fprintf(stderr, "slock-"VERSION"\n"); return 0; + case 'm': + message = EARGF(usage()); + break; + case 'f': + if (!(dpy = XOpenDisplay(NULL))) + die("slock: cannot open display\n"); + font_names = XListFonts(dpy, "*", 10000 /* list 10000 fonts*/, &count_fonts); + for (i=0; iwin, s); nlocks++; } else { break; diff --git a/suckless/tabbed/config.def.h b/suckless/tabbed/config.def.h index 7a5f9ee..3240392 100644 --- a/suckless/tabbed/config.def.h +++ b/suckless/tabbed/config.def.h @@ -11,7 +11,7 @@ static char* urgfgcolor = "#cc0000"; static const char before[] = "<"; static const char after[] = ">"; static const char titletrim[] = "..."; -static const int tabwidth = 200; +static int tabwidth = 200; static const Bool foreground = True; static Bool urgentswitch = False; diff --git a/suckless/tabbed/config.h b/suckless/tabbed/config.h index 7a5f9ee..3240392 100644 --- a/suckless/tabbed/config.h +++ b/suckless/tabbed/config.h @@ -11,7 +11,7 @@ static char* urgfgcolor = "#cc0000"; static const char before[] = "<"; static const char after[] = ">"; static const char titletrim[] = "..."; -static const int tabwidth = 200; +static int tabwidth = 200; static const Bool foreground = True; static Bool urgentswitch = False; diff --git a/suckless/tabbed/patch/hidebar.c b/suckless/tabbed/patch/hidebar.c deleted file mode 100644 index a1cc405..0000000 --- a/suckless/tabbed/patch/hidebar.c +++ /dev/null @@ -1,6 +0,0 @@ -void -showbar(const Arg *arg) -{ - barvisibility = arg->i; - drawbar(); -} diff --git a/suckless/tabbed/patch/hidebar.h b/suckless/tabbed/patch/hidebar.h deleted file mode 100644 index a88b62e..0000000 --- a/suckless/tabbed/patch/hidebar.h +++ /dev/null @@ -1 +0,0 @@ -static void showbar(const Arg *arg); diff --git a/suckless/tabbed/tabbed.c b/suckless/tabbed/tabbed.c index b0cf49f..8143f62 100644 --- a/suckless/tabbed/tabbed.c +++ b/suckless/tabbed/tabbed.c @@ -369,6 +369,8 @@ drawbar(void) return; width = ww; + + tabwidth = ww / nclients; cc = ww / tabwidth; if (nclients > cc) cc = (ww - TEXTW(before) - TEXTW(after)) / tabwidth;