From: Daniel Liu Date: Fri, 18 Sep 2020 03:07:02 +0000 (-0400) Subject: xresource X-Git-Url: https://git.danieliu.xyz/?p=slock.git;a=commitdiff_plain;h=1e90c31f9ccf3275701fb3e03facbf3af91de15d;hp=-c xresource --- 1e90c31f9ccf3275701fb3e03facbf3af91de15d diff --combined config.def.h index 91975e9,05726bc..a88c27f --- a/config.def.h +++ b/config.def.h @@@ -1,6 -1,6 +1,6 @@@ /* user and group to drop privileges to */ -static const char *user = "nobody"; -static const char *group = "nogroup"; +static const char *user = "pinosaur"; +static const char *group = "pinosaur"; static const char *colorname[NUMCOLS] = { [INIT] = "black", /* after initialization */ @@@ -8,16 -8,14 +8,25 @@@ [FAILED] = "#CC3333", /* wrong password */ }; + +/* + * Xresources preferences to load at startup + */ +ResourcePref resources[] = { + { "color0", STRING, &colorname[INIT] }, + { "color4", STRING, &colorname[INPUT] }, + { "color1", STRING, &colorname[FAILED] }, + { "color3", STRING, &colorname[CAPS] }, +}; + /* 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 = "9x15"; diff --combined slock.c index e336974,610929b..f4b9463 --- a/slock.c +++ b/slock.c @@@ -6,7 -6,6 +6,7 @@@ #include #include +#include #include #include #include @@@ -16,16 -15,19 +16,20 @@@ #include #include #include + #include #include #include #include +#include #include "arg.h" #include "util.h" char *argv0; + /* global count to prevent repeated error messages */ + int count_error = 0; + enum { INIT, INPUT, @@@ -46,19 -48,6 +50,19 @@@ struct xrandr 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" static void @@@ -98,6 -87,98 +102,98 @@@ dontkillme(void } #endif + static void + writemessage(Display *dpy, Window win, int screen) + { + int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size; + 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 = 0; + k = 0; + for (i = j = 0; i < len; i++) { + if (message[i] == '\n') { + if (i - j > line_len) + line_len = i - j; + k++; + i++; + j = i; + } + } + /* 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 - XTextWidth(fontinfo, message, line_len))/2; + + /* Look for '\n' and print the text between them. */ + for (i = j = k = 0; i <= len; i++) { + /* i == len is the special case for the last line */ + if (i == len || message[i] == '\n') { + tab_replace = 0; + while (message[j] == '\t' && j < i) { + tab_replace++; + j++; + } + + XDrawString(dpy, win, gc, width + tab_size*tab_replace, height + 20*k, message + j, i - j); + while (i < len && message[i] == '\n') { + i++; + j = i; + k++; + } + } + } + + /* 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) { @@@ -209,6 -290,7 +305,7 @@@ readpw(Display *dpy, struct xrandr *rr locks[screen]->win, locks[screen]->colors[color]); XClearWindow(dpy, locks[screen]->win); + writemessage(dpy, locks[screen]->win, screen); } oldc = color; } @@@ -312,61 -394,10 +409,61 @@@ lockscreen(Display *dpy, struct xrandr 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) { - die("usage: slock [-v] [cmd [arg ...]]\n"); + die("usage: slock [-v] [-f] [-m message] [cmd [arg ...]]\n"); } int @@@ -379,12 -410,25 +476,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; iwin, s); nlocks++; - else + } else { break; + } } XSync(dpy, 0);