From 8236f48674193872ee77f66f4d959abe959c1d38 Mon Sep 17 00:00:00 2001 From: knolax <1339802534.kk@gmail.com> Date: Mon, 17 Jul 2017 14:24:58 -0400 Subject: added functional keypress image spec, loads slow if you use many high res images. --- i3lock.c | 40 ++++++++++++++++++++++++++++++++++++---- unlock_indicator.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 9 deletions(-) diff --git a/i3lock.c b/i3lock.c index 988c32e..17587b3 100644 --- a/i3lock.c +++ b/i3lock.c @@ -86,8 +86,12 @@ static uint8_t xkb_base_event; static uint8_t xkb_base_error; cairo_surface_t *img = NULL; // image buffer to background image -cairo_surface_t *auth_images[5]; // array of image buffers to background image; +cairo_surface_t *auth_images[5]; // array of image buffers to auth status images; bool use_auth_images = false; +cairo_surface_t * * keypress_images; // array of image buffers to keypress images; +//this is a long because atoi is considered deprecated and we don'y want truncation errors +long num_keypress_images = 0; // how many keypress images are there, 0 means not to use keypress images + bool tile = false; bool ignore_empty_password = false; bool skip_repeated_empty_password = false; @@ -839,6 +843,7 @@ int main(int argc, char *argv[]) { {"image", required_argument, NULL, 'i'}, {"auth-image-dir", required_argument, NULL, 'a'}, {"keypress-image-dir", required_argument, NULL, 'k'}, + {"num-keypress-images", required_argument, NULL, 'K'}, {"tiling", no_argument, NULL, 't'}, {"ignore-empty-password", no_argument, NULL, 'e'}, {"inactivity-timeout", required_argument, NULL, 'I'}, @@ -850,7 +855,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:a:k:teI:f"; + char *optstring = "hvnbdc:p:ui:a:k:K:teI:f"; while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) { switch (o) { case 'v': @@ -892,6 +897,9 @@ int main(int argc, char *argv[]) { case 'k': keypress_image_path = strdup(optarg); break; + case 'K': + num_keypress_images = strtol(optarg,NULL,10); + break; case 't': tile = true; break; @@ -916,7 +924,7 @@ int main(int argc, char *argv[]) { break; default: errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" - " [-i image.png] [-a auth-image-dir] [-k keypress-image-dir] [-t] [-e] [-I timeout] [-f]"); + " [-i image.png] [-a auth-image-dir] [-k keypress-image-dir] [-c number of keypress images] [-t] [-e] [-I timeout] [-f]"); } } @@ -1039,7 +1047,7 @@ int main(int argc, char *argv[]) { sprintf(auth_image_path_buffer,"%s%s%d%s",auth_image_path,"/",auth_image_counter,".png"); /* Create a pixmap to render on, fill it with the background color */ auth_images[auth_image_counter] = cairo_image_surface_create_from_png(auth_image_path_buffer); - /* In case loading failed, we just pretend no -i was specified. */ + /* In case loading failed, we just pretend no -a was specified. */ if (cairo_surface_status(auth_images[auth_image_counter]) != CAIRO_STATUS_SUCCESS) { fprintf(stderr, "Could not load image \"%s\": %s\n", auth_image_path_buffer, cairo_status_to_string(cairo_surface_status(auth_images[auth_image_counter]))); @@ -1050,6 +1058,30 @@ int main(int argc, char *argv[]) { } free(auth_image_path); } + //loads images to use for keypress indicators + //all images up to num_keypress_images -1 must exist otherwise num_keypress_images is set to 0 and this option is ignored + if (keypress_image_path) { + keypress_images = calloc(num_keypress_images, sizeof(cairo_surface_t *)); + int keypress_image_counter = 0; // counter to loop through the states + char * keypress_image_path_buffer; // string to store the pathes of each image as it loads + while (keypress_image_counter < num_keypress_images) { + //allocates string of exactly 25chars larger tan keypress_image_path, since /$keypress_image_counter.png is can at most be 20 + 5 chars as max of uint64 is 20 digits with decimal radix; + keypress_image_path_buffer = calloc(strlen(keypress_image_path) + 25,sizeof(char)); + sprintf(keypress_image_path_buffer,"%s%s%d%s",keypress_image_path,"/",keypress_image_counter,".png"); + /* Create a pixmap to render on, fill it with the background color */ + keypress_images[keypress_image_counter] = cairo_image_surface_create_from_png(keypress_image_path_buffer); + /* In case loading failed, we just pretend no -k was specified. */ + if (cairo_surface_status(keypress_images[keypress_image_counter]) != CAIRO_STATUS_SUCCESS) { + fprintf(stderr, "Could not load image \"%s\": %s\n", + keypress_image_path_buffer, cairo_status_to_string(cairo_surface_status(keypress_images[keypress_image_counter]))); + num_keypress_images = 0; + free(keypress_images); + } + free(keypress_image_path_buffer); + keypress_image_counter++; + } + free(keypress_image_path); + } /* Pixmap on which the image is rendered to (if any) */ xcb_pixmap_t bg_pixmap = draw_image(last_resolution); diff --git a/unlock_indicator.c b/unlock_indicator.c index cf7a391..bf0c31d 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -52,9 +52,12 @@ extern char *modifier_string; extern cairo_surface_t *img; /* array of Cairo surfaces containing the authorization status images (-a), if any. */ extern cairo_surface_t * auth_images[5]; +/*Switch on whether to use said images*/ extern bool use_auth_images; -/* Path of directory containing indicator keypress images (-k), if any. */ -extern char * keypress_image_path; +/* array of Cairo surfaces containing the keypress images (-k), if any. */ +extern cairo_surface_t * * keypress_images; +/*number of images, 0 if this option is turned off (-K)*/ +extern long num_keypress_images; /*Whether the image should be tiled. */ extern bool tile; /* The background color to use (in hex). */ @@ -83,7 +86,8 @@ static xcb_visualtype_t *vistype; * indicator. */ unlock_state_t unlock_state; auth_state_t auth_state; - +/*maintains which keypress image to use*/ +long keypress_image = 0; /* * Returns the scaling factor of the current screen. E.g., on a 227 DPI MacBook * Pro 13" Retina screen, the scaling factor is 227/96 = 2.36. @@ -143,9 +147,26 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_fill(xcb_ctx); } + //increment and decrement the keypress_image used + if((num_keypress_images > 0)&&(unlock_state == STATE_KEY_ACTIVE)) { + keypress_image++; + if (keypress_image >= num_keypress_images) { + keypress_image = num_keypress_images - 1; + } + } + if((num_keypress_images > 0)&&(unlock_state == STATE_BACKSPACE_ACTIVE)) { + keypress_image--; + if (keypress_image < 0) { + keypress_image = 0; + } + } + //if an attempt failed. reset keypress_image + if (auth_state == STATE_AUTH_WRONG) { + keypress_image = 0; + } + //if auth images are used just draw the corresponding image - if (use_auth_images && unlock_indicator && - (unlock_state >= STATE_KEY_PRESSED || auth_state > STATE_AUTH_IDLE)) { + if (use_auth_images && unlock_indicator) { if (!tile) { cairo_set_source_surface(xcb_ctx, auth_images[auth_state], 0, 0); cairo_paint(xcb_ctx); @@ -160,6 +181,22 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { cairo_pattern_destroy(pattern); } } + //if keypress images are used just draw the corresponding image + if ((num_keypress_images > 0) &&(unlock_state >= STATE_KEY_PRESSED)) { + if (!tile) { + cairo_set_source_surface(xcb_ctx, keypress_images[keypress_image], 0, 0); + cairo_paint(xcb_ctx); + } else { + /* create a pattern and fill a rectangle as big as the screen */ + cairo_pattern_t *pattern; + pattern = cairo_pattern_create_for_surface(keypress_images[keypress_image]); + cairo_set_source(xcb_ctx, pattern); + cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); + cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); + cairo_fill(xcb_ctx); + cairo_pattern_destroy(pattern); + } + } //otherwise draw the circle indicator if ((!use_auth_images) && unlock_indicator && (unlock_state >= STATE_KEY_PRESSED || auth_state > STATE_AUTH_IDLE)) { -- cgit v1.1