sites

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

slock-message-20191002-b46028b.diff (6269B)


      1 From b46028b2797b886154258dcafe71c349cdc68b43 Mon Sep 17 00:00:00 2001
      2 From: Blair Drummond <blair.robert.drummond@gmail.com>
      3 Date: Wed, 2 Oct 2019 14:59:00 -0400
      4 Subject: [PATCH] Add a message command. Fixes old version's bugs.
      5 
      6 ---
      7  config.def.h |   9 ++++
      8  config.mk    |   2 +-
      9  slock.1      |   7 +++
     10  slock.c      | 120 +++++++++++++++++++++++++++++++++++++++++++++++++--
     11  4 files changed, 133 insertions(+), 5 deletions(-)
     12 
     13 diff --git a/config.def.h b/config.def.h
     14 index 9855e21..c2a0ab2 100644
     15 --- a/config.def.h
     16 +++ b/config.def.h
     17 @@ -10,3 +10,12 @@ static const char *colorname[NUMCOLS] = {
     18  
     19  /* treat a cleared input like a wrong password (color) */
     20  static const int failonclear = 1;
     21 +
     22 +/* default message */
     23 +static const char * message = "Suckless: Software that sucks less.";
     24 +
     25 +/* text color */
     26 +static const char * text_color = "#ffffff";
     27 +
     28 +/* text size (must be a valid size) */
     29 +static const char * font_name = "6x10";
     30 diff --git a/config.mk b/config.mk
     31 index 74429ae..c4ccf66 100644
     32 --- a/config.mk
     33 +++ b/config.mk
     34 @@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib
     35  
     36  # includes and libs
     37  INCS = -I. -I/usr/include -I${X11INC}
     38 -LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
     39 +LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lXinerama
     40  
     41  # flags
     42  CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
     43 diff --git a/slock.1 b/slock.1
     44 index 82cdcd6..946165f 100644
     45 --- a/slock.1
     46 +++ b/slock.1
     47 @@ -6,6 +6,8 @@
     48  .Sh SYNOPSIS
     49  .Nm
     50  .Op Fl v
     51 +.Op Fl f
     52 +.Op Fl m Ar message
     53  .Op Ar cmd Op Ar arg ...
     54  .Sh DESCRIPTION
     55  .Nm
     56 @@ -16,6 +18,11 @@ is executed after the screen has been locked.
     57  .Bl -tag -width Ds
     58  .It Fl v
     59  Print version information to stdout and exit.
     60 +.It Fl f
     61 +List all valid X fonts and exit.
     62 +.It Fl m Ar message
     63 +Overrides default slock lock message.
     64 +.TP
     65  .El
     66  .Sh SECURITY CONSIDERATIONS
     67  To make sure a locked screen can not be bypassed by switching VTs
     68 diff --git a/slock.c b/slock.c
     69 index 5ae738c..610929b 100644
     70 --- a/slock.c
     71 +++ b/slock.c
     72 @@ -15,6 +15,7 @@
     73  #include <unistd.h>
     74  #include <sys/types.h>
     75  #include <X11/extensions/Xrandr.h>
     76 +#include <X11/extensions/Xinerama.h>
     77  #include <X11/keysym.h>
     78  #include <X11/Xlib.h>
     79  #include <X11/Xutil.h>
     80 @@ -24,6 +25,9 @@
     81  
     82  char *argv0;
     83  
     84 +/* global count to prevent repeated error messages */
     85 +int count_error = 0;
     86 +
     87  enum {
     88  	INIT,
     89  	INPUT,
     90 @@ -83,6 +87,98 @@ dontkillme(void)
     91  }
     92  #endif
     93  
     94 +static void
     95 +writemessage(Display *dpy, Window win, int screen)
     96 +{
     97 +	int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size;
     98 +	XGCValues gr_values;
     99 +	XFontStruct *fontinfo;
    100 +	XColor color, dummy;
    101 +	XineramaScreenInfo *xsi;
    102 +	GC gc;
    103 +	fontinfo = XLoadQueryFont(dpy, font_name);
    104 +
    105 +	if (fontinfo == NULL) {
    106 +		if (count_error == 0) {
    107 +			fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name);
    108 +			fprintf(stderr, "slock: Try listing fonts with 'slock -f'\n");
    109 +			count_error++;
    110 +		}
    111 +		return;
    112 +	}
    113 +
    114 +	tab_size = 8 * XTextWidth(fontinfo, " ", 1);
    115 +
    116 +	XAllocNamedColor(dpy, DefaultColormap(dpy, screen),
    117 +		 text_color, &color, &dummy);
    118 +
    119 +	gr_values.font = fontinfo->fid;
    120 +	gr_values.foreground = color.pixel;
    121 +	gc=XCreateGC(dpy,win,GCFont+GCForeground, &gr_values);
    122 +
    123 +	/*  To prevent "Uninitialized" warnings. */
    124 +	xsi = NULL;
    125 +
    126 +	/*
    127 +	 * Start formatting and drawing text
    128 +	 */
    129 +
    130 +	len = strlen(message);
    131 +
    132 +	/* Max max line length (cut at '\n') */
    133 +	line_len = 0;
    134 +	k = 0;
    135 +	for (i = j = 0; i < len; i++) {
    136 +		if (message[i] == '\n') {
    137 +			if (i - j > line_len)
    138 +				line_len = i - j;
    139 +			k++;
    140 +			i++;
    141 +			j = i;
    142 +		}
    143 +	}
    144 +	/* If there is only one line */
    145 +	if (line_len == 0)
    146 +		line_len = len;
    147 +
    148 +	if (XineramaIsActive(dpy)) {
    149 +		xsi = XineramaQueryScreens(dpy, &i);
    150 +		s_width = xsi[0].width;
    151 +		s_height = xsi[0].height;
    152 +	} else {
    153 +		s_width = DisplayWidth(dpy, screen);
    154 +		s_height = DisplayHeight(dpy, screen);
    155 +	}
    156 +
    157 +	height = s_height*3/7 - (k*20)/3;
    158 +	width  = (s_width - XTextWidth(fontinfo, message, line_len))/2;
    159 +
    160 +	/* Look for '\n' and print the text between them. */
    161 +	for (i = j = k = 0; i <= len; i++) {
    162 +		/* i == len is the special case for the last line */
    163 +		if (i == len || message[i] == '\n') {
    164 +			tab_replace = 0;
    165 +			while (message[j] == '\t' && j < i) {
    166 +				tab_replace++;
    167 +				j++;
    168 +			}
    169 +
    170 +			XDrawString(dpy, win, gc, width + tab_size*tab_replace, height + 20*k, message + j, i - j);
    171 +			while (i < len && message[i] == '\n') {
    172 +				i++;
    173 +				j = i;
    174 +				k++;
    175 +			}
    176 +		}
    177 +	}
    178 +
    179 +	/* xsi should not be NULL anyway if Xinerama is active, but to be safe */
    180 +	if (XineramaIsActive(dpy) && xsi != NULL)
    181 +			XFree(xsi);
    182 +}
    183 +
    184 +
    185 +
    186  static const char *
    187  gethash(void)
    188  {
    189 @@ -194,6 +290,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
    190  					                     locks[screen]->win,
    191  					                     locks[screen]->colors[color]);
    192  					XClearWindow(dpy, locks[screen]->win);
    193 +					writemessage(dpy, locks[screen]->win, screen);
    194  				}
    195  				oldc = color;
    196  			}
    197 @@ -300,7 +397,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
    198  static void
    199  usage(void)
    200  {
    201 -	die("usage: slock [-v] [cmd [arg ...]]\n");
    202 +	die("usage: slock [-v] [-f] [-m message] [cmd [arg ...]]\n");
    203  }
    204  
    205  int
    206 @@ -313,12 +410,25 @@ main(int argc, char **argv) {
    207  	gid_t dgid;
    208  	const char *hash;
    209  	Display *dpy;
    210 -	int s, nlocks, nscreens;
    211 +	int i, s, nlocks, nscreens;
    212 +	int count_fonts;
    213 +	char **font_names;
    214  
    215  	ARGBEGIN {
    216  	case 'v':
    217  		fprintf(stderr, "slock-"VERSION"\n");
    218  		return 0;
    219 +	case 'm':
    220 +		message = EARGF(usage());
    221 +		break;
    222 +	case 'f':
    223 +		if (!(dpy = XOpenDisplay(NULL)))
    224 +			die("slock: cannot open display\n");
    225 +		font_names = XListFonts(dpy, "*", 10000 /* list 10000 fonts*/, &count_fonts);
    226 +		for (i=0; i<count_fonts; i++) {
    227 +			fprintf(stderr, "%s\n", *(font_names+i));
    228 +		}
    229 +		return 0;
    230  	default:
    231  		usage();
    232  	} ARGEND
    233 @@ -363,10 +473,12 @@ main(int argc, char **argv) {
    234  	if (!(locks = calloc(nscreens, sizeof(struct lock *))))
    235  		die("slock: out of memory\n");
    236  	for (nlocks = 0, s = 0; s < nscreens; s++) {
    237 -		if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL)
    238 +		if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) {
    239 +			writemessage(dpy, locks[s]->win, s);
    240  			nlocks++;
    241 -		else
    242 +		} else {
    243  			break;
    244 +		}
    245  	}
    246  	XSync(dpy, 0);
    247  
    248 -- 
    249 2.20.1
    250