From bbd2196326bbcb4cb96e8a8e3d68c25e414510d5 Mon Sep 17 00:00:00 2001 From: Thomas Osterland Date: Wed, 21 Mar 2018 15:59:45 +0100 Subject: [PATCH] added slideshow functionality --- i3lock.c | 104 +++++++++++++++++++++++++++++++++++++-------- unlock_indicator.c | 20 +++++++++ 2 files changed, 106 insertions(+), 18 deletions(-) diff --git a/i3lock.c b/i3lock.c index 72d8ab8..e68d60e 100644 --- a/i3lock.c +++ b/i3lock.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -91,6 +92,7 @@ int screen_number = 0; int internal_line_source = 0; /* bool for showing the clock; why am I commenting this? */ bool show_clock = false; +bool slideshow_enabled = false; bool always_show_clock = false; bool show_indicator = false; float refresh_rate = 1.0; @@ -200,6 +202,10 @@ static int randr_base = -1; cairo_surface_t *img = NULL; cairo_surface_t *blur_img = NULL; +cairo_surface_t *img_slideshow[256]; +int slideshow_image_count = 0; +int slideshow_interval = 10; + bool tile = false; bool ignore_empty_password = false; bool skip_repeated_empty_password = false; @@ -234,6 +240,15 @@ bool bar_reversed = false; /* isutf, u8_dec © 2005 Jeff Bezanson, public domain */ #define isutf(c) (((c)&0xC0) != 0x80) +/* + * Checks if the given path leads to an actual file or something else, e.g. a directory + */ +int is_regular_file(const char *path) { + struct stat path_stat; + stat(path, &path_stat); + return S_ISREG(path_stat.st_mode); +} + /* * Decrements i to point to the previous unicode glyph * @@ -1046,6 +1061,44 @@ static void raise_loop(xcb_window_t window) { } } +/* + * Loads the images from the provided directory and stores them in the pointer array + * img_slideshow + */ +void load_slideshow_images(const char *path) { + slideshow_enabled = true; + DIR *d; + struct dirent *dir; + int file_count = 0; + + d = opendir(path); + if (d == NULL) { + printf("Could not open directory: %s\n", path); + exit(0); + } + + while ((dir = readdir(d)) != NULL) { + if (file_count >= 256) { + break; + } + + char path_to_image[256]; + strcpy(path_to_image, path); + strcat(path_to_image, "/"); + strcat(path_to_image, dir->d_name); + + if (verify_png_image(path_to_image)) { + img_slideshow[file_count] = cairo_image_surface_create_from_png(path_to_image); + ++file_count; + } + + } + + slideshow_image_count = file_count; + + closedir(d); +} + int main(int argc, char *argv[]) { struct passwd *pw; char *username; @@ -1166,6 +1219,9 @@ int main(int argc, char *argv[]) { {"refresh-rate", required_argument, NULL, 901}, {"composite", no_argument, NULL, 902}, + /* slideshow options */ + {"slideshow-interval", required_argument, NULL, 1000}, + {NULL, no_argument, NULL, 0}}; if ((pw = getpwuid(getuid())) == NULL) @@ -1619,6 +1675,13 @@ int main(int argc, char *argv[]) { case 999: debug_mode = true; break; + case 1000: + slideshow_interval = atoi(optarg); + + if (slideshow_interval < 0) { + slideshow_interval = 10; + } + break; default: errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" " [-i image.png] [-t] [-e] [-f]\n" @@ -1743,23 +1806,28 @@ int main(int argc, char *argv[]) { (uint32_t[]){XCB_EVENT_MASK_STRUCTURE_NOTIFY}); init_colors_once(); - if (verify_png_image(image_path)) { - /* Create a pixmap to render on, fill it with the background color */ - img = cairo_image_surface_create_from_png(image_path); - } else if (file_is_jpg(image_path)) { - DEBUG("Image looks like a jpeg, decoding\n"); - unsigned char* jpg_data = read_JPEG_file(image_path, &jpg_info); - if (jpg_data != NULL) { - img = cairo_image_surface_create_for_data(jpg_data, - CAIRO_FORMAT_ARGB32, jpg_info.width, jpg_info.height, - jpg_info.stride); - } - } - /* In case loading failed, we just pretend no -i was specified. */ - if (img && cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) { - fprintf(stderr, "Could not load image \"%s\": %s\n", - image_path, cairo_status_to_string(cairo_surface_status(img))); - img = NULL; + if (is_regular_file(image_path)) { + if (verify_png_image(image_path)) { + /* Create a pixmap to render on, fill it with the background color */ + img = cairo_image_surface_create_from_png(image_path); + } else if (file_is_jpg(image_path)) { + DEBUG("Image looks like a jpeg, decoding\n"); + unsigned char* jpg_data = read_JPEG_file(image_path, &jpg_info); + if (jpg_data != NULL) { + img = cairo_image_surface_create_for_data(jpg_data, + CAIRO_FORMAT_ARGB32, jpg_info.width, jpg_info.height, + jpg_info.stride); + } + } + /* In case loading failed, we just pretend no -i was specified. */ + if (img && cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) { + fprintf(stderr, "Could not load image \"%s\": %s\n", + image_path, cairo_status_to_string(cairo_surface_status(img))); + img = NULL; + } + } else { + /* Path to a directory is provided -> use slideshow mode */ + load_slideshow_images(image_path); } free(image_path); @@ -1881,7 +1949,7 @@ int main(int argc, char *argv[]) { * file descriptor becomes readable). */ ev_invoke(main_loop, xcb_check, 0); - if (show_clock || bar_enabled) { + if (show_clock || bar_enabled || slideshow_enabled) { if (redraw_thread) { struct timespec ts; double s; diff --git a/unlock_indicator.c b/unlock_indicator.c index 528e406..dbd8ba0 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -59,6 +59,11 @@ extern char *modifier_string; /* A Cairo surface containing the specified image (-i), if any. */ extern cairo_surface_t *img; extern cairo_surface_t *blur_img; +extern cairo_surface_t *img_slideshow[256]; +extern int slideshow_image_count; +extern int slideshow_interval; + +unsigned long lastCheck = -1; /* Whether the image should be tiled. */ extern bool tile; @@ -144,6 +149,8 @@ static struct ev_periodic *time_redraw_tick; /* Cache the screen’s visual, necessary for creating a Cairo context. */ static xcb_visualtype_t *vistype; +int current_slideshow_index = 0; + /* Maintain the current unlock/PAM state to draw the appropriate unlock * indicator. */ unlock_state_t unlock_state; @@ -678,6 +685,19 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); cairo_t *xcb_ctx = cairo_create(xcb_output); + /*update image according to the slideshow_interval*/ + if (slideshow_image_count > 0) { + unsigned long now = (unsigned long)time(NULL); + if (-1 == lastCheck || now - lastCheck >= slideshow_interval) { + img = img_slideshow[current_slideshow_index++]; + + if (current_slideshow_index >= slideshow_image_count) { + current_slideshow_index = 0; + } + lastCheck = now; + } + } + if (blur_img || img) { if (blur_img) { cairo_set_source_surface(xcb_ctx, blur_img, 0, 0);