diff options
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | resources/spinner.svg | 5 | ||||
-rw-r--r-- | screenshots/achelocker.png | bin | 0 -> 14337 bytes | |||
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/render.c | 47 | ||||
-rw-r--r-- | src/render.h | 4 |
6 files changed, 75 insertions, 9 deletions
@@ -1,10 +1,10 @@ -# the buzzert screen locker +# The buzzert screen locker This is a graphical screen locker for X11, for use in conjunction with [XSecureLock](https://github.com/google/xsecurelock). It uses PAM for authentication, so you can use it with your Yubikey/fingerprint scanner, etc. as well. - + ## Building @@ -17,6 +17,7 @@ ninja -C build ``` ## Installing + By building buzzlocker by itself, you'll end up with a binary called `auth_buzzlocker`. This is meant to be used in conjunction with [XSecureLock](https://github.com/google/xsecurelock), which does all the heavy-lifting with regards to properly locking an X session and ensuring other @@ -43,3 +44,6 @@ If you have multiple monitors, buzzlocker will appear only on whatever the prima to XRandR). If you want to override this behavior, set the environment variable `BUZZLOCKER_MONITOR_NUM` to whichever monitor you wish to have buzzlocker appear on. +## Copyrigth + +The original project is from [buzzert](https://github.com/buzzert/buzzlocker), which I adapt for myself. diff --git a/resources/spinner.svg b/resources/spinner.svg index 339dccb..6261e41 100644 --- a/resources/spinner.svg +++ b/resources/spinner.svg @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="windows-1252"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 512 512" style="fill:white;enable-background:new 0 0 512 512;" xml:space="preserve"><link xmlns="" type="text/css" id="dark-mode" rel="stylesheet" href=""/><style xmlns="" type="text/css" id="dark-mode-custom-style"/> +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 50 50" style="fill:white;enable-background:new 0 0 512 512;" xml:space="preserve"><link xmlns="" type="text/css" id="dark-mode" rel="stylesheet" href=""/><style xmlns="" type="text/css" id="dark-mode-custom-style"/> <g> - <path d="M96,255.006c0-6.09,0.352-12.098,1.015-18.011l-92.49-30.052C1.567,222.513,0,238.575,0,255.006 c0,73.615,31.083,139.96,80.827,186.662l57.142-78.647C111.907,334.557,96,296.641,96,255.006z M416,255.006 c0,41.634-15.906,79.55-41.969,108.014l57.143,78.647C480.916,394.967,512,328.621,512,255.006c0-16.431-1.566-32.493-4.523-48.063 l-92.49,30.052C415.648,242.909,416,248.917,416,255.006z M288,98.21c45.967,9.331,84.771,38.371,107.225,77.913l92.49-30.051 C451.115,68.362,376.594,12.042,288,0.994V98.21z M116.775,176.123c22.453-39.542,61.258-68.582,107.225-77.913V0.994 C135.406,12.042,60.885,68.362,24.287,146.071L116.775,176.123z M322.277,400.67c-20.195,9.205-42.635,14.336-66.277,14.336 c-23.642,0-46.083-5.131-66.277-14.334l-57.146,78.654c36.603,20.184,78.668,31.68,123.423,31.68 c44.756,0,86.82-11.496,123.424-31.68L322.277,400.67z"/> + + <path d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" fill="#FF6700" /> </g> </svg> diff --git a/screenshots/achelocker.png b/screenshots/achelocker.png Binary files differnew file mode 100644 index 0000000..7529b1e --- /dev/null +++ b/screenshots/achelocker.png @@ -14,6 +14,7 @@ #include <stdlib.h> #include <time.h> #include <unistd.h> +#include <locale.h> static const int kXSecureLockCharFD = 0; @@ -93,7 +94,9 @@ static void handle_xsl_key_input(saver_state_t *state, const char c) break; case '\r': // Return. case '\n': // Return. - accept_password(state); + if(pw_len > 0) { + accept_password(state); + } break; default: if (pw_len + 1 < kMaxPasswordLength) { @@ -108,6 +111,7 @@ static void handle_xsl_key_input(saver_state_t *state, const char c) // (See comment above for why this is separate) static bool handle_key_event(saver_state_t *state, XKeyEvent *event) { + static int forceEmptyPass = 0; if (!state->input_allowed) return false; KeySym key; @@ -123,7 +127,14 @@ static bool handle_key_event(saver_state_t *state, XKeyEvent *event) password_buf[length - 1] = '\0'; } } else if (XK_Return == key) { - accept_password(state); + char *password_buf = state->password_buffer; + size_t pw_len = strlen(password_buf); + + if( pw_len > 0 || forceEmptyPass) { + accept_password(state); + } else { + forceEmptyPass = 4; + } } else if (strlen(keybuf) > 0) { if (length + 1 < kMaxPasswordLength) { password_buf[length] = keybuf[0]; @@ -133,6 +144,8 @@ static bool handle_key_event(saver_state_t *state, XKeyEvent *event) handled = false; } + forceEmptyPass >>= 1; + return handled; } @@ -355,6 +368,8 @@ static void draw(saver_state_t *state) draw_logo(state); } + draw_date_field(state); + draw_password_field(state); // Automatically reset this after every draw call @@ -456,6 +471,7 @@ static int runloop(cairo_surface_t *surface) int main(int argc, char **argv) { + setlocale(LC_ALL, ""); cairo_surface_t *surface = x11_helper_acquire_cairo_surface(); if (surface == NULL) { fprintf(stderr, "Error creating cairo surface\n"); diff --git a/src/render.c b/src/render.c index e3ed98f..ba9c845 100644 --- a/src/render.c +++ b/src/render.c @@ -104,7 +104,7 @@ static void update_single_animation(saver_state_t *state, animation_t *anim) // Spinner animation else if (anim->type == ASpinnerAnimation) { - anim->anim.spinner_anim.rotation += 0.07; + anim->anim.spinner_anim.rotation += 0.27; } } @@ -281,6 +281,39 @@ void draw_logo(saver_state_t *state) set_layer_needs_draw(state, LAYER_LOGO, false); } +void draw_date_field(saver_state_t *state) +{ + const double cursor_height = 40.0; + const double cursor_width = 30.0; + const double field_x = kLogoBackgroundWidth + 50.0; + const double field_y = (state->canvas_height - cursor_height) / 2.0; + const double field_padding = 10.0; + + cairo_t *cr = state->ctx; + + // Common color for status and password field + cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, state->password_opacity); + + char date[256] = ""; + char datePrompt[256] = ""; + time_t nowInstant = time(NULL); + struct tm* now = localtime(&nowInstant); + + strftime(date, 256, "%T %a %d/%m/%y", now); + sprintf(datePrompt, "%s/%s", date, state->password_prompt); + + // Measure status text + const char *prompt = datePrompt; + pango_layout_set_font_description(state->pango_layout, state->status_font); + pango_layout_set_text(state->pango_layout, prompt, -1); + + int t_width, t_height; + pango_layout_get_size(state->pango_layout, &t_width, &t_height); + double line_height = t_height / PANGO_SCALE; + + + +} void draw_password_field(saver_state_t *state) { const double cursor_height = 40.0; @@ -288,14 +321,22 @@ void draw_password_field(saver_state_t *state) const double field_x = kLogoBackgroundWidth + 50.0; const double field_y = (state->canvas_height - cursor_height) / 2.0; const double field_padding = 10.0; - + cairo_t *cr = state->ctx; // Common color for status and password field cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, state->password_opacity); + char date[256] = ""; + char datePrompt[256] = ""; + time_t nowInstant = time(NULL); + struct tm* now = localtime(&nowInstant); + + strftime(date, 256, "%T %a %d/%m/%y", now); + sprintf(datePrompt, "%s\n%s", date, state->password_prompt); + // Measure status text - const char *prompt = state->password_prompt; + const char *prompt = datePrompt; pango_layout_set_font_description(state->pango_layout, state->status_font); pango_layout_set_text(state->pango_layout, prompt, -1); diff --git a/src/render.h b/src/render.h index 5bc7016..27b917f 100644 --- a/src/render.h +++ b/src/render.h @@ -18,6 +18,7 @@ #define kMaxAnimations 32 #define kMaxPasswordLength 128 #define kMaxPromptLength 128 +#define kMaxPromptLength 128 #define kMaxTimers 16 typedef unsigned animation_key_t; @@ -28,6 +29,7 @@ typedef enum { LAYER_PROMPT = 1 << 1, LAYER_LOGO = 1 << 2, LAYER_PASSWORD = 1 << 3, + LAYER_DATE = 1 << 4, } layer_type_t; @@ -67,6 +69,8 @@ typedef struct { RsvgHandle *spinner_svg_handle; animation_key_t spinner_anim_key; + char date_prompt[kMaxPromptLength]; + char password_prompt[kMaxPromptLength]; char password_buffer[kMaxPasswordLength]; double password_opacity; |