slock

Mahdi's build of slock
git clone git://mahdi.pw/slock.git
Log | Files | Refs | README | LICENSE

slock-message-xft-20210315-ae681c5.patch (6259B)


      1 From ae681c5a52a2b4b257f9432204deedc8b5570e8d Mon Sep 17 00:00:00 2001
      2 From: Nathaniel Evan <[email protected]>
      3 Date: Mon, 15 Mar 2021 05:50:20 +0700
      4 Subject: [PATCH] Updates message patch with Xft font support
      5 
      6 ---
      7  config.def.h |   9 +++++
      8  config.mk    |   4 +-
      9  slock.1      |   4 ++
     10  slock.c      | 110 +++++++++++++++++++++++++++++++++++++++++++++++++--
     11  4 files changed, 122 insertions(+), 5 deletions(-)
     12 
     13 diff --git a/config.def.h b/config.def.h
     14 index 9855e21..2c83077 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 = "sans-serif:size:pixelsize=24:antialias=true:autohint=true";
     30 diff --git a/config.mk b/config.mk
     31 index 74429ae..69ef27a 100644
     32 --- a/config.mk
     33 +++ b/config.mk
     34 @@ -11,8 +11,8 @@ X11INC = /usr/X11R6/include
     35  X11LIB = /usr/X11R6/lib
     36  
     37  # includes and libs
     38 -INCS = -I. -I/usr/include -I${X11INC}
     39 -LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
     40 +INCS = -I. -I/usr/include -I${X11INC} -I/usr/include/freetype2
     41 +LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lXinerama -lXft
     42  
     43  # flags
     44  CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
     45 diff --git a/slock.1 b/slock.1
     46 index 82cdcd6..541a264 100644
     47 --- a/slock.1
     48 +++ b/slock.1
     49 @@ -6,6 +6,7 @@
     50  .Sh SYNOPSIS
     51  .Nm
     52  .Op Fl v
     53 +.Op Fl m Ar message
     54  .Op Ar cmd Op Ar arg ...
     55  .Sh DESCRIPTION
     56  .Nm
     57 @@ -16,6 +17,9 @@ is executed after the screen has been locked.
     58  .Bl -tag -width Ds
     59  .It Fl v
     60  Print version information to stdout and exit.
     61 +.It Fl m Ar message
     62 +Overrides default slock lock message.
     63 +.TP
     64  .El
     65  .Sh SECURITY CONSIDERATIONS
     66  To make sure a locked screen can not be bypassed by switching VTs
     67 diff --git a/slock.c b/slock.c
     68 index 5ae738c..ef569f8 100644
     69 --- a/slock.c
     70 +++ b/slock.c
     71 @@ -14,16 +14,22 @@
     72  #include <string.h>
     73  #include <unistd.h>
     74  #include <sys/types.h>
     75 +#include <fontconfig/fontconfig.h>
     76  #include <X11/extensions/Xrandr.h>
     77 +#include <X11/extensions/Xinerama.h>
     78  #include <X11/keysym.h>
     79  #include <X11/Xlib.h>
     80  #include <X11/Xutil.h>
     81 +#include <X11/Xft/Xft.h>
     82  
     83  #include "arg.h"
     84  #include "util.h"
     85  
     86  char *argv0;
     87  
     88 +/* global count to prevent repeated error messages */
     89 +int count_error = 0;
     90 +
     91  enum {
     92  	INIT,
     93  	INPUT,
     94 @@ -83,6 +89,98 @@ dontkillme(void)
     95  }
     96  #endif
     97  
     98 +static void
     99 +writemessage(Display *dpy, Window win, int screen)
    100 +{
    101 +	int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size;
    102 +	XftFont *fontinfo;
    103 +	XftColor xftcolor;
    104 +	XftDraw *xftdraw;
    105 +	XGlyphInfo ext_msg, ext_space;
    106 +	XineramaScreenInfo *xsi;
    107 +	xftdraw = XftDrawCreate(dpy, win, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));
    108 +	fontinfo = XftFontOpenName(dpy, screen, font_name);
    109 +	XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), text_color, &xftcolor);
    110 +
    111 +	if (fontinfo == NULL) {
    112 +		if (count_error == 0) {
    113 +			fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name);
    114 +			count_error++;
    115 +		}
    116 +		return;
    117 +	}
    118 +
    119 +	XftTextExtentsUtf8(dpy, fontinfo, (XftChar8 *) " ", 1, &ext_space);
    120 +	tab_size = 8 * ext_space.width;
    121 +
    122 +	/*  To prevent "Uninitialized" warnings. */
    123 +	xsi = NULL;
    124 +
    125 +	/*
    126 +	 * Start formatting and drawing text
    127 +	 */
    128 +
    129 +	len = strlen(message);
    130 +
    131 +	/* Max max line length (cut at '\n') */
    132 +	line_len = 0;
    133 +	k = 0;
    134 +	for (i = j = 0; i < len; i++) {
    135 +		if (message[i] == '\n') {
    136 +			if (i - j > line_len)
    137 +				line_len = i - j;
    138 +			k++;
    139 +			i++;
    140 +			j = i;
    141 +		}
    142 +	}
    143 +	/* If there is only one line */
    144 +	if (line_len == 0)
    145 +		line_len = len;
    146 +
    147 +	if (XineramaIsActive(dpy)) {
    148 +		xsi = XineramaQueryScreens(dpy, &i);
    149 +		s_width = xsi[0].width;
    150 +		s_height = xsi[0].height;
    151 +	} else {
    152 +		s_width = DisplayWidth(dpy, screen);
    153 +		s_height = DisplayHeight(dpy, screen);
    154 +	}
    155 +
    156 +	XftTextExtentsUtf8(dpy, fontinfo, (XftChar8 *)message, line_len, &ext_msg);
    157 +	height = s_height*3/7 - (k*20)/3;
    158 +	width  = (s_width - ext_msg.width)/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 +			XftDrawStringUtf8(xftdraw, &xftcolor, fontinfo, width + tab_size*tab_replace, height + 20*k, (XftChar8 *)(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 +	XftFontClose(dpy, fontinfo);
    184 +	XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &xftcolor);
    185 +	XftDrawDestroy(xftdraw);
    186 +}
    187 +
    188 +
    189 +
    190  static const char *
    191  gethash(void)
    192  {
    193 @@ -194,6 +292,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
    194  					                     locks[screen]->win,
    195  					                     locks[screen]->colors[color]);
    196  					XClearWindow(dpy, locks[screen]->win);
    197 +					writemessage(dpy, locks[screen]->win, screen);
    198  				}
    199  				oldc = color;
    200  			}
    201 @@ -300,7 +399,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
    202  static void
    203  usage(void)
    204  {
    205 -	die("usage: slock [-v] [cmd [arg ...]]\n");
    206 +	die("usage: slock [-v] [-m message] [cmd [arg ...]]\n");
    207  }
    208  
    209  int
    210 @@ -319,6 +418,9 @@ main(int argc, char **argv) {
    211  	case 'v':
    212  		fprintf(stderr, "slock-"VERSION"\n");
    213  		return 0;
    214 +	case 'm':
    215 +		message = EARGF(usage());
    216 +		break;
    217  	default:
    218  		usage();
    219  	} ARGEND
    220 @@ -363,10 +465,12 @@ main(int argc, char **argv) {
    221  	if (!(locks = calloc(nscreens, sizeof(struct lock *))))
    222  		die("slock: out of memory\n");
    223  	for (nlocks = 0, s = 0; s < nscreens; s++) {
    224 -		if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL)
    225 +		if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) {
    226 +			writemessage(dpy, locks[s]->win, s);
    227  			nlocks++;
    228 -		else
    229 +		} else {
    230  			break;
    231 +		}
    232  	}
    233  	XSync(dpy, 0);
    234  
    235 -- 
    236 2.30.1
    237