Another copy of my dotfiles. Because I don't completely trust GitHub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

250 lines
6.1 KiB

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