summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimeon Simeonov2020-12-10 23:57:33 +0100
committerSimeon Simeonov2020-12-10 23:57:33 +0100
commitb16438a23b237aa44fe9358a0b8954888bf81ea2 (patch)
tree9e0fcb3e8f3d4b1707bd702f2bf4429299d1e2e3
parent12a06184e733554bafc76e643b49067fcd758fc0 (diff)
Add support for counting to a specific calendar time (absolute time)
-rw-r--r--extras.c102
-rw-r--r--extras.h6
-rw-r--r--i3lock-extended.114
-rw-r--r--i3lock.c10
-rw-r--r--unlock_indicator.c26
5 files changed, 150 insertions, 8 deletions
diff --git a/extras.c b/extras.c
index 37819f5..bde4172 100644
--- a/extras.c
+++ b/extras.c
@@ -132,6 +132,61 @@ static void i3lock_draw_led(cairo_t *cr,
132} 132}
133 133
134 134
135static char * i3lock_replace_str(char *to,
136 const char *from,
137 const char *old_substr,
138 const char *new_substr,
139 size_t max_length) {
140
141 int offset; /* the offset in the tmp_str after each match */
142
143 /* the offset in from needed to pick up the right side after a match */
144 int from_offset;
145
146 int from_len = strlen(from);
147 int new_substr_len = strlen(new_substr);
148 int old_substr_len = strlen(old_substr);
149 int len_diff = old_substr_len - new_substr_len;
150 size_t free_space = max_length - 1;
151 char tmp_str[max_length];
152 char *tmp_str_ptr;
153
154 /* reserve the last byte for '\0' in case of clipping */
155 strncpy(tmp_str, from, free_space);
156
157 for (int i = 0; ; ++i) {
158 tmp_str_ptr = strstr(tmp_str, old_substr);
159 if (tmp_str_ptr == NULL) {
160 /* no more instances of old_substr */
161 break;
162 }
163
164 offset = tmp_str_ptr - tmp_str;
165 free_space -= offset;
166 if (free_space <= new_substr_len) {
167 strncpy(tmp_str_ptr, new_substr, free_space);
168 break;
169 }
170 strncpy(tmp_str_ptr, new_substr, new_substr_len);
171 free_space -= new_substr_len;
172 /* tmp_str offset -> from_offset mapping */
173 from_offset = offset + old_substr_len + i * len_diff;
174 if (free_space <= from_len - from_offset) {
175 strncpy(tmp_str_ptr + new_substr_len, from + from_offset, free_space);
176 break;
177 }
178 strncpy(tmp_str_ptr + new_substr_len, from + from_offset, from_len - from_offset + 1);
179
180 }
181
182 strncpy(to, tmp_str, max_length - 1);
183 *(to + (max_length - 1)) = '\0';
184
185 return to;
186
187}
188
189
135void i3lock_draw_digital_clock(cairo_t *cr, 190void i3lock_draw_digital_clock(cairo_t *cr,
136 const i3lock_digital_clock_t *dc, 191 const i3lock_digital_clock_t *dc,
137 const uint32_t *resolution, 192 const uint32_t *resolution,
@@ -440,9 +495,56 @@ void i3lock_draw_led_clock(cairo_t *cr,
440 brokentime->tm_sec & 1, 495 brokentime->tm_sec & 1,
441 lc); 496 lc);
442 } 497 }
498
443 return; 499 return;
500
444 } 501 }
445 502
446} 503}
447 504
448 505
506char * i3lock_format_elapsed_time(char *to,
507 const char *template,
508 int max_size,
509 int seconds) {
510
511 char tmp_str[max_size];
512 char int_str[32]; /* more than enough for int */
513 int days = seconds / 86400;
514 int hours = (seconds - days * 86400) / 3600;
515 int minutes = (seconds - days * 86400 - hours * 3600) / 60;
516 int rest_seconds = seconds - days * 86400 - hours * 3600 - minutes * 60;
517
518 strncpy(tmp_str, template, max_size);
519 if (strlen(template) >= max_size) {
520 /* do a proper clipping */
521 *(tmp_str + (max_size - 1)) = '\0';
522 }
523
524 /* days */
525 snprintf(int_str, 32, "%d", days);
526 i3lock_replace_str(to, tmp_str, "%d", int_str, max_size);
527 strcpy(tmp_str, to);
528
529 /* hours */
530 snprintf(int_str, 32, "%d", hours);
531 i3lock_replace_str(to, tmp_str, "%h", int_str, max_size);
532 strcpy(tmp_str, to);
533
534 /* minutes */
535 snprintf(int_str, 32, "%d", minutes);
536 i3lock_replace_str(to, tmp_str, "%m", int_str, max_size);
537 strcpy(tmp_str, to);
538
539 /* rest. seconds */
540 snprintf(int_str, 32, "%d", rest_seconds);
541 i3lock_replace_str(to, tmp_str, "%s", int_str, max_size);
542 strcpy(tmp_str, to);
543
544 /* seconds */
545 snprintf(int_str, 32, "%d", seconds);
546 i3lock_replace_str(to, tmp_str, "%S", int_str, max_size);
547
548 return to;
549
550}
diff --git a/extras.h b/extras.h
index d4a353e..c78ffff 100644
--- a/extras.h
+++ b/extras.h
@@ -88,7 +88,6 @@ void i3lock_draw_elapsed_time(cairo_t *cr,
88 const uint32_t *resolution, 88 const uint32_t *resolution,
89 const time_t *now); 89 const time_t *now);
90 90
91
92void i3lock_draw_led_clock(cairo_t *cr, 91void i3lock_draw_led_clock(cairo_t *cr,
93 const i3lock_led_clock_t *lc, 92 const i3lock_led_clock_t *lc,
94 const uint32_t *resolution, 93 const uint32_t *resolution,
@@ -99,4 +98,9 @@ void i3lock_draw_string(cairo_t *cr,
99 const char *formatted_string, 98 const char *formatted_string,
100 const i3lock_elapsed_time_t *et, 99 const i3lock_elapsed_time_t *et,
101 const uint32_t *resolution); 100 const uint32_t *resolution);
101
102char * i3lock_format_elapsed_time(char *to,
103 const char *template,
104 int max_size,
105 int seconds);
102#endif 106#endif
diff --git a/i3lock-extended.1 b/i3lock-extended.1
index b0f51a7..34ea2a3 100644
--- a/i3lock-extended.1
+++ b/i3lock-extended.1
@@ -8,7 +8,7 @@
8.fi 8.fi
9.. 9..
10 10
11.TH i3lock\-extended 1 "MARCH 2020" Linux "User Manuals" 11.TH i3lock\-extended 1 "DECEMBER 2020" Linux "User Manuals"
12 12
13.SH NAME 13.SH NAME
14i3lock\-extended \- improved screen locker 14i3lock\-extended \- improved screen locker
@@ -18,6 +18,8 @@ i3lock\-extended \- improved screen locker
18.RB [\|\-B 18.RB [\|\-B
19.IR color \|] 19.IR color \|]
20.RB [\|\-b\|] 20.RB [\|\-b\|]
21.RB [\|\-C
22.IR seconds \|]
21.RB [\|\-c 23.RB [\|\-c
22.IR color \|] 24.IR color \|]
23.RB [\|\-D\|] 25.RB [\|\-D\|]
@@ -94,6 +96,8 @@ Digital clock
94Elapsed time since activation 96Elapsed time since activation
95.IP \[bu] 97.IP \[bu]
96Display-text 98Display-text
99.IP \[bu]
100Count to a specific calendar time (absolute time)
97 101
98.SH OPTIONS 102.SH OPTIONS
99.TP 103.TP
@@ -112,6 +116,14 @@ Turn the screen into the given color instead of white.
112Color must be given in 3-byte. Default: ffffff (white). 116Color must be given in 3-byte. Default: ffffff (white).
113 117
114.TP 118.TP
119.BI \-C\ seconds \fR,\ \fB\-\-count\-until= seconds
120Sets the seconds since the Epoch to count to. date +%s -d ... can be used to
121get the Epoch time. Then the following macros will become available for the
122display-text parameter: %d - days remaining until the time set,
123%h - hours remaining, %m - minutes remaining, %s - seconds remaining,
124%S - total amount of seconds remaining. Default: 0 (count until is off).
125
126.TP
115.B \-D, \-\-digital\-clock 127.B \-D, \-\-digital\-clock
116Display digital clock. 128Display digital clock.
117 129
diff --git a/i3lock.c b/i3lock.c
index f7c5bdc..d492e5a 100644
--- a/i3lock.c
+++ b/i3lock.c
@@ -84,6 +84,7 @@ static void input_done(void);
84bool digital_clock = false; 84bool digital_clock = false;
85bool led_clock = false; 85bool led_clock = false;
86bool elapsed_time = false; 86bool elapsed_time = false;
87int count_until = 0; /* count seconds until */
87int refresh_rate = 2; /* 2 frames per second */ 88int refresh_rate = 2; /* 2 frames per second */
88i3lock_digital_clock_t i3lock_digital_clock = {28, 89i3lock_digital_clock_t i3lock_digital_clock = {28,
89 "000000", 90 "000000",
@@ -1083,6 +1084,7 @@ int main(int argc, char *argv[]) {
1083 {"dpms", no_argument, NULL, 'd'}, 1084 {"dpms", no_argument, NULL, 'd'},
1084 {"color", required_argument, NULL, 'c'}, 1085 {"color", required_argument, NULL, 'c'},
1085#ifdef EXTRAS 1086#ifdef EXTRAS
1087 {"count-until", no_argument, NULL, 'C'},
1086 {"digital-clock", no_argument, NULL, 'D'}, 1088 {"digital-clock", no_argument, NULL, 'D'},
1087 {"digital-clock-color", required_argument, NULL, 'G'}, 1089 {"digital-clock-color", required_argument, NULL, 'G'},
1088 {"digital-clock-template", required_argument, NULL, 'T'}, 1090 {"digital-clock-template", required_argument, NULL, 'T'},
@@ -1122,7 +1124,7 @@ int main(int argc, char *argv[]) {
1122 errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead"); 1124 errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead");
1123 1125
1124#ifdef EXTRAS 1126#ifdef EXTRAS
1125 char *optstring = "hvnbDdELc:B:G:F:J:O:R:r:S:T:W:X:x:Y:y:Z:p:ui:teI:f"; 1127 char *optstring = "hvnbDdELC:c:B:G:F:J:O:R:r:S:T:W:X:x:Y:y:Z:p:ui:teI:f";
1126#else 1128#else
1127 char *optstring = "hvnbdc:p:ui:teI:f"; 1129 char *optstring = "hvnbdc:p:ui:teI:f";
1128#endif 1130#endif
@@ -1156,6 +1158,12 @@ int main(int argc, char *argv[]) {
1156 break; 1158 break;
1157 } 1159 }
1158#ifdef EXTRAS 1160#ifdef EXTRAS
1161 case 'C': /* count until */
1162 if (optarg != NULL && atoi(optarg) > 0) /* not nice with -1 and 0 */
1163 count_until = atoi(optarg);
1164 DEBUG("count_until: %d\n",
1165 count_until);
1166 break;
1159 case 'D': 1167 case 'D':
1160 digital_clock = true; 1168 digital_clock = true;
1161 break; 1169 break;
diff --git a/unlock_indicator.c b/unlock_indicator.c
index 73320cb..8f69972 100644
--- a/unlock_indicator.c
+++ b/unlock_indicator.c
@@ -58,12 +58,15 @@ extern bool debug_mode;
58 58
59#ifdef EXTRAS 59#ifdef EXTRAS
60/* timekeeping */ 60/* timekeeping */
61#define I3LOCK_COUNT_UNTIL_BUFFER 128
62char count_until_str[I3LOCK_COUNT_UNTIL_BUFFER];
61time_t now; 63time_t now;
62struct tm *brokentime; 64struct tm *brokentime;
63/* enable the digital clock */ 65/* enable the digital clock */
64extern bool digital_clock; 66extern bool digital_clock;
65extern bool led_clock; 67extern bool led_clock;
66extern bool elapsed_time; 68extern bool elapsed_time;
69extern int count_until;
67extern i3lock_digital_clock_t i3lock_digital_clock; 70extern i3lock_digital_clock_t i3lock_digital_clock;
68extern i3lock_elapsed_time_t i3lock_elapsed_time; 71extern i3lock_elapsed_time_t i3lock_elapsed_time;
69extern i3lock_led_clock_t i3lock_led_clock; 72extern i3lock_led_clock_t i3lock_led_clock;
@@ -359,17 +362,30 @@ void draw_image(xcb_pixmap_t bg_pixmap, uint32_t *resolution) {
359 resolution, 362 resolution,
360 brokentime); 363 brokentime);
361 } 364 }
362 /* elapsed time or display text */ 365 /* elapsed time or counter with display text or only display text */
363 if (elapsed_time) { 366 if (elapsed_time) {
364 i3lock_draw_elapsed_time(xcb_ctx, 367 i3lock_draw_elapsed_time(xcb_ctx,
365 &i3lock_elapsed_time, 368 &i3lock_elapsed_time,
366 resolution, 369 resolution,
367 &now); 370 &now);
368 } else if (display_text != NULL) { 371 } else if (display_text != NULL) {
369 i3lock_draw_string(xcb_ctx, 372 if (count_until) {
370 display_text, 373 if (i3lock_format_elapsed_time(
371 &i3lock_elapsed_time, 374 count_until_str,
372 resolution); 375 display_text,
376 I3LOCK_COUNT_UNTIL_BUFFER,
377 count_until - (int) now) != NULL) {
378 i3lock_draw_string(xcb_ctx,
379 count_until_str,
380 &i3lock_elapsed_time,
381 resolution);
382 }
383 } else {
384 i3lock_draw_string(xcb_ctx,
385 display_text,
386 &i3lock_elapsed_time,
387 resolution);
388 }
373 } 389 }
374#endif 390#endif
375 if (xr_screens > 0) { 391 if (xr_screens > 0) {