sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 6a58ac2eaa8ec0cf6eaeccd045de40f70e722e2e
parent 90a64ac81acd3329cd04cf5c9058902ac1e7cde1
Author: Guy Shefy <guyshefyb@gmail.com>
Date:   Wed, 10 Feb 2021 01:33:27 +0200

[slock][patch] patch that allows full color messages

`colormessage` is a derivative of `message`. The
difference is that it allows 24 bit color messages
using ANSI escape codes.

Diffstat:
Atools.suckless.org/slock/patches/colormessage/index.md | 40++++++++++++++++++++++++++++++++++++++++
Atools.suckless.org/slock/patches/colormessage/slock-colormessage-20200210-35633d4.diff | 284+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 324 insertions(+), 0 deletions(-)

diff --git a/tools.suckless.org/slock/patches/colormessage/index.md b/tools.suckless.org/slock/patches/colormessage/index.md @@ -0,0 +1,40 @@ +Color Message +============= + +Description +----------- +Based on the message patch, This patch lets you add a message to your lock screen, using 24 bit color ANSI escape codes. + +Exactly like in the original patch, You can place a default message in `config.h`, and you can also pass a message with `-m message` + +For example, you can run + + slock -m "$(printf "text colored \x1b[38;2;0;255;0m green\x1b[39m\n")" + +to color a single word + +Or, you can go all in and run + + slock -m "$(cowsay "$(fortune)" | lolcat -ft)" + +Notes +----- +This adds three items to `config.h`: + +* `message` - the default message +* `text_color` - the color used when no color codes are in effect. can be a hex color or a colorname +* `font_name` - which must be some valid X11 font name like "6x10". + +*A list of font names can be generated with* `slock -f` + +*When using lolcat you should add the -ft options* + +Download +-------- +* [slock-colormessage-20200210-35633d4.diff](slock-colormessage-20200210-35633d4.diff) + + +Authors +------- +* Guy Shefy - guyshefyb@gmail.com +* Based on patch by Blair Drummond - blair.robert.drummond@gmail.com diff --git a/tools.suckless.org/slock/patches/colormessage/slock-colormessage-20200210-35633d4.diff b/tools.suckless.org/slock/patches/colormessage/slock-colormessage-20200210-35633d4.diff @@ -0,0 +1,284 @@ +From 53ba5a8d3608ca9c9c406b12c51c2bfdfb3e01d3 Mon Sep 17 00:00:00 2001 +From: Guy Shefy <guyshefyb@gmail.com> +Date: Wed, 10 Feb 2021 00:17:46 +0200 +Subject: [PATCH] Add a message command with 24 bit color support + +--- + config.def.h | 9 +++ + config.mk | 2 +- + slock.1 | 7 +++ + slock.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 4 files changed, 167 insertions(+), 5 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 9855e21..c2a0ab2 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -10,3 +10,12 @@ static const char *colorname[NUMCOLS] = { + + /* treat a cleared input like a wrong password (color) */ + static const int failonclear = 1; ++ ++/* 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"; +diff --git a/config.mk b/config.mk +index 74429ae..c4ccf66 100644 +--- a/config.mk ++++ b/config.mk +@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib + + # includes and libs + INCS = -I. -I/usr/include -I${X11INC} +-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr ++LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lXinerama + + # flags + CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +diff --git a/slock.1 b/slock.1 +index 82cdcd6..946165f 100644 +--- a/slock.1 ++++ b/slock.1 +@@ -6,6 +6,8 @@ + .Sh SYNOPSIS + .Nm + .Op Fl v ++.Op Fl f ++.Op Fl m Ar message + .Op Ar cmd Op Ar arg ... + .Sh DESCRIPTION + .Nm +@@ -16,6 +18,11 @@ is executed after the screen has been locked. + .Bl -tag -width Ds + .It Fl v + Print version information to stdout and exit. ++.It Fl f ++List all valid X fonts and exit. ++.It Fl m Ar message ++Overrides default slock lock message. ++.TP + .El + .Sh SECURITY CONSIDERATIONS + To make sure a locked screen can not be bypassed by switching VTs +diff --git a/slock.c b/slock.c +index 5ae738c..b8b7fe4 100644 +--- a/slock.c ++++ b/slock.c +@@ -15,6 +15,7 @@ + #include <unistd.h> + #include <sys/types.h> + #include <X11/extensions/Xrandr.h> ++#include <X11/extensions/Xinerama.h> + #include <X11/keysym.h> + #include <X11/Xlib.h> + #include <X11/Xutil.h> +@@ -24,6 +25,9 @@ + + char *argv0; + ++/* global count to prevent repeated error messages */ ++int count_error = 0; ++ + enum { + INIT, + INPUT, +@@ -83,6 +87,132 @@ dontkillme(void) + } + #endif + ++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); ++} ++ ++ ++ + static const char * + gethash(void) + { +@@ -194,6 +324,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + locks[screen]->win, + locks[screen]->colors[color]); + XClearWindow(dpy, locks[screen]->win); ++ writemessage(dpy, locks[screen]->win, screen); + } + oldc = color; + } +@@ -300,7 +431,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 +@@ -313,12 +444,25 @@ main(int argc, char **argv) { + gid_t dgid; + const char *hash; + Display *dpy; +- int s, nlocks, nscreens; ++ int i, s, nlocks, nscreens; ++ int 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; i<count_fonts; i++) { ++ fprintf(stderr, "%s\n", *(font_names+i)); ++ } ++ return 0; + default: + usage(); + } ARGEND +@@ -363,10 +507,12 @@ main(int argc, char **argv) { + if (!(locks = calloc(nscreens, sizeof(struct lock *)))) + die("slock: out of memory\n"); + for (nlocks = 0, s = 0; s < nscreens; s++) { +- if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) ++ if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) { ++ writemessage(dpy, locks[s]->win, s); + nlocks++; +- else ++ } else { + break; ++ } + } + XSync(dpy, 0); + +-- +2.30.0 +