summaryrefslogtreecommitdiff
path: root/i3lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'i3lock.c')
-rw-r--r--i3lock.c287
1 files changed, 282 insertions, 5 deletions
diff --git a/i3lock.c b/i3lock.c
index 134fdda..7f8763a 100644
--- a/i3lock.c
+++ b/i3lock.c
@@ -1,11 +1,30 @@
1/* 1/*
2 * vim:ts=4:sw=4:expandtab 2 * This file is part of i3lock-extended
3 * Copyright (C) 2020 Simeon Simeonov
4
5 * i3lock-extended is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9
10 * i3lock-extended is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* This file includes software copyrighted by Michael Stapelberg and
20 * distributed under the following license: See LICENSE for more information
3 * 21 *
4 * © 2010 Michael Stapelberg 22 * © 2010 Michael Stapelberg
5 * 23 *
6 * See LICENSE for licensing information 24 * See LICENSE for licensing information
7 * 25 *
8 */ 26 */
27
9#include <config.h> 28#include <config.h>
10 29
11#include <stdio.h> 30#include <stdio.h>
@@ -48,6 +67,10 @@
48#include "randr.h" 67#include "randr.h"
49#include "dpi.h" 68#include "dpi.h"
50 69
70#ifdef EXTRAS
71#include "extras.h"
72#endif
73
51#define TSTAMP_N_SECS(n) (n * 1.0) 74#define TSTAMP_N_SECS(n) (n * 1.0)
52#define TSTAMP_N_MINS(n) (60 * TSTAMP_N_SECS(n)) 75#define TSTAMP_N_MINS(n) (60 * TSTAMP_N_SECS(n))
53#define START_TIMER(timer_obj, timeout, callback) \ 76#define START_TIMER(timer_obj, timeout, callback) \
@@ -58,6 +81,31 @@
58typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents); 81typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents);
59static void input_done(void); 82static void input_done(void);
60 83
84#ifdef EXTRAS
85bool digital_clock = false;
86bool led_clock = false;
87bool elapsed_time = false;
88int refresh_rate = 2; /* 2 frames per second */
89i3lock_digital_clock_t i3lock_digital_clock = {28,
90 "000000",
91 "%H:%M:%S",
92 I3LOCK_ALIGN_LEFT,
93 I3LOCK_ALIGN_TOP};
94
95i3lock_elapsed_time_t i3lock_elapsed_time = {28,
96 "000000",
97 0,
98 I3LOCK_ALIGN_RIGHT,
99 I3LOCK_ALIGN_BOTTOM};
100
101i3lock_led_clock_t i3lock_led_clock = {"ffff00",
102 "7f7f7f",
103 "000000",
104 I3LOCK_ALIGN_CENTER,
105 I3LOCK_ALIGN_BOTTOM};
106char *display_text = NULL;
107#endif
108
61char color[7] = "ffffff"; 109char color[7] = "ffffff";
62uint32_t last_resolution[2]; 110uint32_t last_resolution[2];
63xcb_window_t win; 111xcb_window_t win;
@@ -305,7 +353,10 @@ static void input_done(void) {
305 return; 353 return;
306 } 354 }
307#endif 355#endif
308 356#ifdef EXTRAS
357 /* reset the time elapsed counter */
358 i3lock_elapsed_time.start_time = time(NULL);
359#endif
309 if (debug_mode) 360 if (debug_mode)
310 fprintf(stderr, "Authentication failure\n"); 361 fprintf(stderr, "Authentication failure\n");
311 362
@@ -1005,6 +1056,15 @@ static void raise_loop(xcb_window_t window) {
1005 } 1056 }
1006} 1057}
1007 1058
1059#ifdef EXTRAS
1060/* called periodically by the ticking system */
1061static void refresh_tick_cb (EV_P_ ev_timer *w, int revents) {
1062
1063 redraw_screen();
1064
1065}
1066#endif
1067
1008int main(int argc, char *argv[]) { 1068int main(int argc, char *argv[]) {
1009 struct passwd *pw; 1069 struct passwd *pw;
1010 char *username; 1070 char *username;
@@ -1023,6 +1083,26 @@ int main(int argc, char *argv[]) {
1023 {"beep", no_argument, NULL, 'b'}, 1083 {"beep", no_argument, NULL, 'b'},
1024 {"dpms", no_argument, NULL, 'd'}, 1084 {"dpms", no_argument, NULL, 'd'},
1025 {"color", required_argument, NULL, 'c'}, 1085 {"color", required_argument, NULL, 'c'},
1086#ifdef EXTRAS
1087 {"digital-clock", no_argument, NULL, 'D'},
1088 {"digital-clock-color", required_argument, NULL, 'G'},
1089 {"digital-clock-template", required_argument, NULL, 'T'},
1090 {"digital-clock-halign", required_argument, NULL, 'x'},
1091 {"digital-clock-valign", required_argument, NULL, 'y'},
1092 {"display-text", no_argument, NULL, 'J'},
1093 {"elapsed-time", no_argument, NULL, 'E'},
1094 {"elapsed-time-color", required_argument, NULL, 'R'},
1095 {"elapsed-time-halign", required_argument, NULL, 'W'},
1096 {"elapsed-time-valign", required_argument, NULL, 'Z'},
1097 {"led-clock", no_argument, NULL, 'L'},
1098 {"led-clock-halign", required_argument, NULL, 'X'},
1099 {"led-clock-valign", required_argument, NULL, 'Y'},
1100 {"led-border-color", required_argument, NULL, 'B'},
1101 {"led-off-color", required_argument, NULL, 'F'},
1102 {"led-on-color", required_argument, NULL, 'O'},
1103 {"refresh-rate", required_argument, NULL, 'r'},
1104 {"text-size", required_argument, NULL, 'S'},
1105#endif
1026 {"pointer", required_argument, NULL, 'p'}, 1106 {"pointer", required_argument, NULL, 'p'},
1027 {"debug", no_argument, NULL, 0}, 1107 {"debug", no_argument, NULL, 0},
1028 {"help", no_argument, NULL, 'h'}, 1108 {"help", no_argument, NULL, 'h'},
@@ -1040,11 +1120,15 @@ int main(int argc, char *argv[]) {
1040 if ((username = pw->pw_name) == NULL) 1120 if ((username = pw->pw_name) == NULL)
1041 errx(EXIT_FAILURE, "pw->pw_name is NULL."); 1121 errx(EXIT_FAILURE, "pw->pw_name is NULL.");
1042 1122
1123#ifdef EXTRAS
1124 char *optstring = "hvnbDdELc:B:G:F:J:O:R:r:S:T:W:X:x:Y:y:Z:p:ui:teI:f";
1125#else
1043 char *optstring = "hvnbdc:p:ui:teI:f"; 1126 char *optstring = "hvnbdc:p:ui:teI:f";
1127#endif
1044 while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) { 1128 while ((o = getopt_long(argc, argv, optstring, longopts, &longoptind)) != -1) {
1045 switch (o) { 1129 switch (o) {
1046 case 'v': 1130 case 'v':
1047 errx(EXIT_SUCCESS, "version " I3LOCK_VERSION " © 2010 Michael Stapelberg"); 1131 errx(EXIT_SUCCESS, "version " I3LOCK_VERSION " © 2010 Michael Stapelberg, 2017-2020 Simeon Simeonov");
1048 case 'n': 1132 case 'n':
1049 dont_fork = true; 1133 dont_fork = true;
1050 break; 1134 break;
@@ -1052,10 +1136,10 @@ int main(int argc, char *argv[]) {
1052 beep = true; 1136 beep = true;
1053 break; 1137 break;
1054 case 'd': 1138 case 'd':
1055 fprintf(stderr, "DPMS support has been removed from i3lock. Please see the manpage i3lock(1).\n"); 1139 fprintf(stderr, "DPMS support has been removed from i3lock. Please see the manpage i3lock-extended(1).\n");
1056 break; 1140 break;
1057 case 'I': { 1141 case 'I': {
1058 fprintf(stderr, "Inactivity timeout only makes sense with DPMS, which was removed. Please see the manpage i3lock(1).\n"); 1142 fprintf(stderr, "Inactivity timeout only makes sense with DPMS, which was removed. Please see the manpage i3lock-extended(1).\n");
1059 break; 1143 break;
1060 } 1144 }
1061 case 'c': { 1145 case 'c': {
@@ -1070,6 +1154,181 @@ int main(int argc, char *argv[]) {
1070 1154
1071 break; 1155 break;
1072 } 1156 }
1157#ifdef EXTRAS
1158 case 'D':
1159 digital_clock = true;
1160 break;
1161 case 'E':
1162 elapsed_time = true;
1163 i3lock_elapsed_time.start_time = time(NULL);
1164 break;
1165 case 'L':
1166 led_clock = true;
1167 break;
1168 case 'B': {
1169 char *arg = optarg;
1170
1171 /* Skip # if present */
1172 if (arg[0] == '#')
1173 arg++;
1174
1175 if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", i3lock_led_clock.led_border_color) != 1)
1176 errx(EXIT_FAILURE, "led-border-color is invalid, it must be given in 3-byte hexadecimal format: rrggbb\n");
1177 DEBUG("led-border-color: %s\n", i3lock_led_clock.led_border_color);
1178 break;
1179 }
1180 case 'G': { /* digital-clock-color */
1181 char *arg = optarg;
1182
1183 /* Skip # if present */
1184 if (arg[0] == '#')
1185 arg++;
1186
1187 if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", i3lock_digital_clock.color) != 1)
1188 errx(EXIT_FAILURE, "digital-clock-color is invalid, it must be given in 3-byte hexadecimal format: rrggbb\n");
1189 DEBUG("digital-clock-color: %s\n", i3lock_digital_clock.color);
1190 break;
1191 }
1192 case 'F': { /* led-off-color */
1193 char *arg = optarg;
1194
1195 /* Skip # if present */
1196 if (arg[0] == '#')
1197 arg++;
1198
1199 if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", i3lock_led_clock.led_off_color) != 1)
1200 errx(EXIT_FAILURE, "led-off-color is invalid, it must be given in 3-byte hexadecimal format: rrggbb\n");
1201 DEBUG("led-off-color: %s\n", i3lock_led_clock.led_off_color);
1202 break;
1203 }
1204 case 'J': {
1205 display_text = strdup(optarg);
1206 if (display_text == NULL) {
1207 errx(EXIT_FAILURE,
1208 "Unable to initialize display_text\n");
1209 }
1210 DEBUG("display_text: %s\n", display_text);
1211 break;
1212 }
1213 case 'O': { /* led-on-color */
1214 char *arg = optarg;
1215
1216 /* Skip # if present */
1217 if (arg[0] == '#')
1218 arg++;
1219
1220 if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", i3lock_led_clock.led_on_color) != 1)
1221 errx(EXIT_FAILURE, "led-on-color is invalid, it must be given in 3-byte hexadecimal format: rrggbb\n");
1222 DEBUG("led-on-color: %s\n", i3lock_led_clock.led_on_color);
1223 break;
1224 }
1225 case 'R': { /* elapsed-time-color */
1226 char *arg = optarg;
1227
1228 /* Skip # if present */
1229 if (arg[0] == '#')
1230 arg++;
1231
1232 if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", i3lock_elapsed_time.color) != 1)
1233 errx(EXIT_FAILURE, "elapsed-time-color is invalid, it must be given in 3-byte hexadecimal format: rrggbb\n");
1234 DEBUG("elapsed-time-color: %s\n", i3lock_elapsed_time.color);
1235 break;
1236 }
1237 case 'r': /* refresh-rate */
1238 if (atoi(optarg)) /* not nice with 0 */
1239 refresh_rate = atoi(optarg);
1240 DEBUG("refresh-rate: %d\n",
1241 refresh_rate);
1242 break;
1243 case 'S': /* text-size */
1244 i3lock_elapsed_time.text_size = i3lock_digital_clock.text_size = atoi(optarg);
1245 DEBUG("text-size: %d\n",
1246 i3lock_digital_clock.text_size);
1247 break;
1248 case 'T': /* digital-clock-template */
1249 i3lock_digital_clock.template = strdup(optarg);
1250 DEBUG("digital-clock-template: %s\n",
1251 i3lock_digital_clock.template);
1252 break;
1253 case 'W': /* elapsed-time-halign */
1254 /* the default is right */
1255 if (strcasecmp(optarg, "left") == 0) {
1256 i3lock_elapsed_time.horizontal_alignment = I3LOCK_ALIGN_LEFT;
1257 DEBUG("elapsed-time-halign: left\n");
1258 } else if (strcasecmp(optarg, "center") == 0) {
1259 i3lock_elapsed_time.horizontal_alignment = I3LOCK_ALIGN_CENTER;
1260 DEBUG("elapsed-time-halign: center\n");
1261 } else {
1262 /* value already set */
1263 DEBUG("elapsed-time-halign: right\n");
1264 }
1265 break;
1266 case 'X': /* led-clock-halign */
1267 /* the default is center */
1268 if (strcasecmp(optarg, "left") == 0) {
1269 i3lock_led_clock.horizontal_alignment = I3LOCK_ALIGN_LEFT;
1270 DEBUG("led-clock-halign: left\n");
1271 } else if (strcasecmp(optarg, "right") == 0) {
1272 i3lock_led_clock.horizontal_alignment = I3LOCK_ALIGN_RIGHT;
1273 DEBUG("led-clock-halign: right\n");
1274 } else {
1275 /* value already set */
1276 DEBUG("led-clock-halign: center\n");
1277 }
1278 break;
1279 case 'Y': /* led-clock-valign */
1280 /* the default is bottom */
1281 if (strcasecmp(optarg, "middle") == 0) {
1282 i3lock_led_clock.vertical_alignment = I3LOCK_ALIGN_MIDDLE;
1283 DEBUG("led-clock-valign: middle\n");
1284 } else if (strcasecmp(optarg, "top") == 0) {
1285 i3lock_led_clock.vertical_alignment = I3LOCK_ALIGN_TOP;
1286 DEBUG("led-clock-valign: top\n");
1287 } else {
1288 /* value already set */
1289 DEBUG("led-clock-valign: bottom\n");
1290 }
1291 break;
1292 case 'x': /* digital-clock-halign */
1293 /* the default is left */
1294 if (strcasecmp(optarg, "center") == 0) {
1295 i3lock_digital_clock.horizontal_alignment = I3LOCK_ALIGN_CENTER;
1296 DEBUG("digital-clock-halign: center\n");
1297 } else if (strcasecmp(optarg, "right") == 0) {
1298 i3lock_digital_clock.horizontal_alignment = I3LOCK_ALIGN_RIGHT;
1299 DEBUG("digital-clock-halign: right\n");
1300 } else {
1301 /* value already set */
1302 DEBUG("digital-clock-halign: left\n");
1303 }
1304 break;
1305 case 'y': /* digital-clock-valign */
1306 /* the default is top */
1307 if (strcasecmp(optarg, "middle") == 0) {
1308 i3lock_digital_clock.vertical_alignment = I3LOCK_ALIGN_MIDDLE;
1309 DEBUG("digital-clock-valign: middle\n");
1310 } else if (strcasecmp(optarg, "bottom") == 0) {
1311 i3lock_digital_clock.vertical_alignment = I3LOCK_ALIGN_BOTTOM;
1312 DEBUG("digital-clock-valign: bottom\n");
1313 } else {
1314 /* value already set */
1315 DEBUG("digital-clock-valign: top\n");
1316 }
1317 break;
1318 case 'Z': /* elapsed-time-valign */
1319 /* the default is bottom */
1320 if (strcasecmp(optarg, "middle") == 0) {
1321 i3lock_elapsed_time.vertical_alignment = I3LOCK_ALIGN_MIDDLE;
1322 DEBUG("elapsed-time-valign: middle\n");
1323 } else if (strcasecmp(optarg, "top") == 0) {
1324 i3lock_elapsed_time.vertical_alignment = I3LOCK_ALIGN_TOP;
1325 DEBUG("elapsed-time-valign: top\n");
1326 } else {
1327 /* value already set */
1328 DEBUG("elapsed-time-valign: bottom\n");
1329 }
1330 break;
1331#endif
1073 case 'u': 1332 case 'u':
1074 unlock_indicator = false; 1333 unlock_indicator = false;
1075 break; 1334 break;
@@ -1101,8 +1360,21 @@ int main(int argc, char *argv[]) {
1101 show_failed_attempts = true; 1360 show_failed_attempts = true;
1102 break; 1361 break;
1103 default: 1362 default:
1363#ifdef EXTRAS
1364 errx(
1365 EXIT_FAILURE,
1366 "Syntax: i3lock-extended [-v] [-n] [-b] [-D] [-d] [-E] "
1367 "[-L] [-c color] [-B color] [-F color] [-G color] "
1368 "[-J text] [-O color] [-R color] [-r refresh rate] [-u] "
1369 "[-W horizontal-alignment] [-X horizontal-alignment] "
1370 "[-x horizontal-alignment] [-Y vertical-alignment] "
1371 "[-y vertical-alignment] [-Z vertical-alignment] "
1372 "[-p win|default] [-i image.png] [-t] [-e] [-I timeout] "
1373 "[-f]");
1374#else
1104 errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" 1375 errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]"
1105 " [-i image.png] [-t] [-e] [-I timeout] [-f]"); 1376 " [-i image.png] [-t] [-e] [-I timeout] [-f]");
1377#endif
1106 } 1378 }
1107 } 1379 }
1108 1380
@@ -1291,6 +1563,11 @@ int main(int argc, char *argv[]) {
1291 ev_prepare_init(xcb_prepare, xcb_prepare_cb); 1563 ev_prepare_init(xcb_prepare, xcb_prepare_cb);
1292 ev_prepare_start(main_loop, xcb_prepare); 1564 ev_prepare_start(main_loop, xcb_prepare);
1293 1565
1566#ifdef EXTRAS
1567 ev_timer refresh_tick_watcher;
1568 ev_timer_init (&refresh_tick_watcher, refresh_tick_cb, 1.0, 1.0 / refresh_rate);
1569 ev_timer_start (main_loop, &refresh_tick_watcher);
1570#endif
1294 /* Invoke the event callback once to catch all the events which were 1571 /* Invoke the event callback once to catch all the events which were
1295 * received up until now. ev will only pick up new events (when the X11 1572 * received up until now. ev will only pick up new events (when the X11
1296 * file descriptor becomes readable). */ 1573 * file descriptor becomes readable). */