aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.h9
-rw-r--r--config.mk2
-rw-r--r--slock.17
-rw-r--r--slock.c119
4 files changed, 132 insertions, 5 deletions
diff --git a/config.h b/config.h
index 6991d6b..26e00b8 100644
--- a/config.h
+++ b/config.h
@@ -39,3 +39,12 @@ static const int blurRadius=5;
39//#define PIXELATION 39//#define PIXELATION
40/*Set pixelation radius*/ 40/*Set pixelation radius*/
41static const int pixelSize=0; 41static const int pixelSize=0;
42
43/* default message */
44static const char * message = "Suckless: Software that sucks less.";
45
46/* text color */
47static const char * text_color = "#ffffff";
48
49/* text size (must be a valid size) */
50static const char * font_name = "6x10";
diff --git a/config.mk b/config.mk
index 1ff42e9..dd58a49 100644
--- a/config.mk
+++ b/config.mk
@@ -37,4 +37,4 @@ COMPATSRC = explicit_bzero.c
37#COMPATSRC = 37#COMPATSRC =
38 38
39# compiler and linker 39# compiler and linker
40CC = cc 40CC = cc -w
diff --git a/slock.1 b/slock.1
index 82cdcd6..946165f 100644
--- a/slock.1
+++ b/slock.1
@@ -6,6 +6,8 @@
6.Sh SYNOPSIS 6.Sh SYNOPSIS
7.Nm 7.Nm
8.Op Fl v 8.Op Fl v
9.Op Fl f
10.Op Fl m Ar message
9.Op Ar cmd Op Ar arg ... 11.Op Ar cmd Op Ar arg ...
10.Sh DESCRIPTION 12.Sh DESCRIPTION
11.Nm 13.Nm
@@ -16,6 +18,11 @@ is executed after the screen has been locked.
16.Bl -tag -width Ds 18.Bl -tag -width Ds
17.It Fl v 19.It Fl v
18Print version information to stdout and exit. 20Print version information to stdout and exit.
21.It Fl f
22List all valid X fonts and exit.
23.It Fl m Ar message
24Overrides default slock lock message.
25.TP
19.El 26.El
20.Sh SECURITY CONSIDERATIONS 27.Sh SECURITY CONSIDERATIONS
21To make sure a locked screen can not be bypassed by switching VTs 28To make sure a locked screen can not be bypassed by switching VTs
diff --git a/slock.c b/slock.c
index b8be41a..1edc02a 100644
--- a/slock.c
+++ b/slock.c
@@ -30,6 +30,9 @@
30 30
31char *argv0; 31char *argv0;
32 32
33/* global count to prevent repeated error messages */
34int count_error = 0;
35
33enum { 36enum {
34 INIT, 37 INIT,
35 INPUT, 38 INPUT,
@@ -98,6 +101,98 @@ dontkillme(void)
98} 101}
99#endif 102#endif
100 103
104static void
105writemessage(Display *dpy, Window win, int screen)
106{
107 int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size;
108 XGCValues gr_values;
109 XFontStruct *fontinfo;
110 XColor color, dummy;
111 XineramaScreenInfo *xsi;
112 GC gc;
113 fontinfo = XLoadQueryFont(dpy, font_name);
114
115 if (fontinfo == NULL) {
116 if (count_error == 0) {
117 fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name);
118 fprintf(stderr, "slock: Try listing fonts with 'slock -f'\n");
119 count_error++;
120 }
121 return;
122 }
123
124 tab_size = 8 * XTextWidth(fontinfo, " ", 1);
125
126 XAllocNamedColor(dpy, DefaultColormap(dpy, screen),
127 text_color, &color, &dummy);
128
129 gr_values.font = fontinfo->fid;
130 gr_values.foreground = color.pixel;
131 gc=XCreateGC(dpy,win,GCFont+GCForeground, &gr_values);
132
133 /* To prevent "Uninitialized" warnings. */
134 xsi = NULL;
135
136 /*
137 * Start formatting and drawing text
138 */
139
140 len = strlen(message);
141
142 /* Max max line length (cut at '\n') */
143 line_len = 0;
144 k = 0;
145 for (i = j = 0; i < len; i++) {
146 if (message[i] == '\n') {
147 if (i - j > line_len)
148 line_len = i - j;
149 k++;
150 i++;
151 j = i;
152 }
153 }
154 /* If there is only one line */
155 if (line_len == 0)
156 line_len = len;
157
158 if (XineramaIsActive(dpy)) {
159 xsi = XineramaQueryScreens(dpy, &i);
160 s_width = xsi[0].width;
161 s_height = xsi[0].height;
162 } else {
163 s_width = DisplayWidth(dpy, screen);
164 s_height = DisplayHeight(dpy, screen);
165 }
166
167 height = s_height*3/7 - (k*20)/3;
168 width = (s_width - XTextWidth(fontinfo, message, line_len))/2;
169
170 /* Look for '\n' and print the text between them. */
171 for (i = j = k = 0; i <= len; i++) {
172 /* i == len is the special case for the last line */
173 if (i == len || message[i] == '\n') {
174 tab_replace = 0;
175 while (message[j] == '\t' && j < i) {
176 tab_replace++;
177 j++;
178 }
179
180 XDrawString(dpy, win, gc, width + tab_size*tab_replace, height + 20*k, message + j, i - j);
181 while (i < len && message[i] == '\n') {
182 i++;
183 j = i;
184 k++;
185 }
186 }
187 }
188
189 /* xsi should not be NULL anyway if Xinerama is active, but to be safe */
190 if (XineramaIsActive(dpy) && xsi != NULL)
191 XFree(xsi);
192}
193
194
195
101static const char * 196static const char *
102gethash(void) 197gethash(void)
103{ 198{
@@ -241,6 +336,7 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
241 if (running && oldc != color) { 336 if (running && oldc != color) {
242 for (screen = 0; screen < nscreens; screen++) { 337 for (screen = 0; screen < nscreens; screen++) {
243 drawlogo(dpy, locks[screen], color); 338 drawlogo(dpy, locks[screen], color);
339 writemessage(dpy, locks[screen]->win, screen);
244 } 340 }
245 oldc = color; 341 oldc = color;
246 } 342 }
@@ -385,7 +481,7 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
385static void 481static void
386usage(void) 482usage(void)
387{ 483{
388 die("usage: slock [-v] [cmd [arg ...]]\n"); 484 die("usage: slock [-v] [-f] [-m message] [cmd [arg ...]]\n");
389} 485}
390 486
391int 487int
@@ -398,12 +494,25 @@ main(int argc, char **argv) {
398 gid_t dgid; 494 gid_t dgid;
399 const char *hash; 495 const char *hash;
400 Display *dpy; 496 Display *dpy;
401 int s, nlocks, nscreens; 497 int i, s, nlocks, nscreens;
498 int count_fonts;
499 char **font_names;
402 500
403 ARGBEGIN { 501 ARGBEGIN {
404 case 'v': 502 case 'v':
405 fprintf(stderr, "slock-"VERSION"\n"); 503 fprintf(stderr, "slock-"VERSION"\n");
406 return 0; 504 return 0;
505 case 'm':
506 message = EARGF(usage());
507 break;
508 case 'f':
509 if (!(dpy = XOpenDisplay(NULL)))
510 die("slock: cannot open display\n");
511 font_names = XListFonts(dpy, "*", 10000 /* list 10000 fonts*/, &count_fonts);
512 for (i=0; i<count_fonts; i++) {
513 fprintf(stderr, "%s\n", *(font_names+i));
514 }
515 return 0;
407 default: 516 default:
408 usage(); 517 usage();
409 } ARGEND 518 } ARGEND
@@ -502,10 +611,12 @@ main(int argc, char **argv) {
502 if (!(locks = calloc(nscreens, sizeof(struct lock *)))) 611 if (!(locks = calloc(nscreens, sizeof(struct lock *))))
503 die("slock: out of memory\n"); 612 die("slock: out of memory\n");
504 for (nlocks = 0, s = 0; s < nscreens; s++) { 613 for (nlocks = 0, s = 0; s < nscreens; s++) {
505 if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) 614 if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) {
615 writemessage(dpy, locks[s]->win, s);
506 nlocks++; 616 nlocks++;
507 else 617 } else {
508 break; 618 break;
619 }
509 } 620 }
510 XSync(dpy, 0); 621 XSync(dpy, 0);
511 622