From 158623508a2c64eeda4971c0b75a0d91c3e8a160 Mon Sep 17 00:00:00 2001 From: Chris Guillott Date: Fri, 14 Oct 2016 14:48:43 -0400 Subject: [PATCH] add basic clock feature --- i3lock.c | 17 ++++++++++-- unlock_indicator.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-- unlock_indicator.h | 1 + 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/i3lock.c b/i3lock.c index cb25062..bd17661 100644 --- a/i3lock.c +++ b/i3lock.c @@ -62,9 +62,13 @@ char keyhlcolor[9] = "33db00ff"; char bshlcolor[9] = "db3300ff"; char separatorcolor[9] = "000000ff"; +/* int defining which display the lock indicator should be shown on. If -1, then show on all displays.*/ int screen_number = -1; /* default is to use the supplied line color, 1 will be ring color, 2 will be to use the inside color for ver/wrong/etc */ int internal_line_source = 0; +/* bool for showing the clock; why am I commenting this? */ +bool show_clock = false; + uint32_t last_resolution[2]; xcb_window_t win; static xcb_cursor_t cursor; @@ -845,6 +849,8 @@ int main(int argc, char *argv[]) { {"line-uses-inside", no_argument, NULL, 's'}, /* s for in_s_ide; ideally I'd use -I but that's used for timeout, which should use -T, but compatibility argh */ {"screen", required_argument, NULL, 'S'}, + {"clock", no_argument, NULL, 'k'}, + {"ignore-empty-password", no_argument, NULL, 'e'}, {"inactivity-timeout", required_argument, NULL, 'I'}, {"show-failed-attempts", no_argument, NULL, 'f'}, @@ -855,7 +861,7 @@ int main(int argc, char *argv[]) { if ((username = pw->pw_name) == NULL) errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); - char *optstring = "hvnbdc:p:ui:teI:frsS:"; + char *optstring = "hvnbdc:p:ui:teI:frsS:k"; while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) { switch (o) { case 'v': @@ -921,6 +927,10 @@ int main(int argc, char *argv[]) { case 'S': screen_number = atoi(optarg); break; + + case 'k': + show_clock = true; + break; case 0: if (strcmp(longopts[optind].name, "debug") == 0) debug_mode = true; @@ -1040,7 +1050,7 @@ int main(int argc, char *argv[]) { break; default: errx(EXIT_FAILURE, "Syntax: i3lock-color [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" - " [-i image.png] [-t] [-e] [-I timeout] [-f] [-r|s] [-S screen_number] [--fuckton-of-color-args=rrggbbaa]"); + " [-i image.png] [-t] [-e] [-I timeout] [-f] [-r|s] [-S screen_number] [-k] [--fuckton-of-color-args=rrggbbaa]"); } } @@ -1205,5 +1215,8 @@ int main(int argc, char *argv[]) { * received up until now. ev will only pick up new events (when the X11 * file descriptor becomes readable). */ ev_invoke(main_loop, xcb_check, 0); + if (show_clock) { + start_time_redraw_tick(main_loop); + } ev_loop(main_loop, 0); } diff --git a/unlock_indicator.c b/unlock_indicator.c index 9ca3b5b..f282f14 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -21,6 +21,9 @@ #include "unlock_indicator.h" #include "xinerama.h" +/* clock stuff */ +#include + #define BUTTON_RADIUS 90 #define BUTTON_SPACE (BUTTON_RADIUS + 5) #define BUTTON_CENTER (BUTTON_RADIUS + 5) @@ -71,6 +74,8 @@ extern int internal_line_source; extern int screen_number; +extern bool show_clock; + /* Whether the failed attempts should be displayed. */ extern bool show_failed_attempts; /* Number of failed unlock attempts. */ @@ -87,6 +92,9 @@ extern xcb_screen_t *screen; * Local variables. ******************************************************************************/ +/* time stuff */ +static struct ev_periodic *time_redraw_tick; + /* Cache the screen’s visual, necessary for creating a Cairo context. */ static xcb_visualtype_t *vistype; @@ -245,8 +253,14 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { (strtol(strgroupss[2], NULL, 16)), (strtol(strgroupss[3], NULL, 16))}; + /* https://github.com/ravinrabbid/i3lock-clock/commit/0de3a411fa5249c3a4822612c2d6c476389a1297 */ + time_t rawtime; + struct tm* timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + if (unlock_indicator && - (unlock_state >= STATE_KEY_PRESSED || pam_state > STATE_PAM_IDLE)) { + (unlock_state >= STATE_KEY_PRESSED || pam_state > STATE_PAM_IDLE || show_clock)) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 10.0); @@ -324,6 +338,11 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { /* Display a (centered) text of the current PAM state. */ char *text = NULL; + + char *date = NULL; + char time_text[40] = {0}; + char date_text[40] = {0}; + /* We don't want to show more than a 3-digit number. */ char buf[4]; @@ -353,6 +372,12 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { } cairo_set_source_rgba(ctx, (double)text16[0]/255, (double)text16[1]/255, (double)text16[2]/255, (double)text16[3]/255); cairo_set_font_size(ctx, 32.0); + } else if (show_clock) { + // TODO: allow for custom string times + strftime(time_text, 40, "%R", timeinfo); + strftime(date_text, 40, "%a %m. %b", timeinfo); + text = time_text; + date = date_text; } break; } @@ -363,13 +388,35 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { cairo_text_extents(ctx, text, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); - y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing); + if (date) { + y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) - 6; + } else { + y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing); + } cairo_move_to(ctx, x, y); cairo_show_text(ctx, text); cairo_close_path(ctx); } + if (date) { + cairo_text_extents_t extents; + double x, y; + + // TODO: different date/time colors + cairo_set_source_rgba(ctx, (double)text16[0]/255, (double)text16[1]/255, (double)text16[2]/255, (double)text16[3]/255); + cairo_set_font_size(ctx, 14.0); + + cairo_text_extents(ctx, date, &extents); + x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); + y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 14; + + cairo_move_to(ctx, x, y); + cairo_show_text(ctx, date); + cairo_close_path(ctx); + } + + if (pam_state == STATE_PAM_WRONG && (modifier_string != NULL)) { cairo_text_extents_t extents; double x, y; @@ -490,3 +537,21 @@ void clear_indicator(void) { unlock_state = STATE_KEY_PRESSED; redraw_screen(); } + +static void time_redraw_cb(struct ev_loop *loop, ev_periodic *w, int revents) { + redraw_screen(); +} + +void start_time_redraw_tick(struct ev_loop* main_loop) { + if (time_redraw_tick) { + ev_periodic_set(time_redraw_tick, 1.0, 60., 0); + ev_periodic_again(main_loop, time_redraw_tick); + } else { + if (!(time_redraw_tick = calloc(sizeof(struct ev_periodic), 1))) { + return; + } + ev_periodic_init(time_redraw_tick, time_redraw_cb, 1.0, 60., 0); + ev_periodic_start(main_loop, time_redraw_tick); + } +} + diff --git a/unlock_indicator.h b/unlock_indicator.h index acfe768..909ecfb 100644 --- a/unlock_indicator.h +++ b/unlock_indicator.h @@ -21,5 +21,6 @@ typedef enum { xcb_pixmap_t draw_image(uint32_t* resolution); void redraw_screen(void); void clear_indicator(void); +void start_time_redraw_timeout(void); #endif