diff --git a/i3lock.c b/i3lock.c index 0b63550..86d309c 100644 --- a/i3lock.c +++ b/i3lock.c @@ -175,6 +175,18 @@ bool tile = false; bool ignore_empty_password = false; bool skip_repeated_empty_password = false; + +// experimental bar stuff +bool bar_enabled = false; +int *bar_heights = NULL; +int num_bars = 0; +int bar_width = 15; +#define BAR_VERT 0 +#define BAR_FLAT 1 +int bar_orientation = BAR_FLAT; +int bar_step = 15; +int max_bar_height = 50; + /* isutf, u8_dec © 2005 Jeff Bezanson, public domain */ #define isutf(c) (((c)&0xC0) != 0x80) @@ -1055,6 +1067,15 @@ int main(int argc, char *argv[]) { {"modsize", required_argument, NULL, 0}, {"radius", required_argument, NULL, 0}, {"ring-width", required_argument, NULL, 0}, + + {"bar-indicator", no_argument, NULL, 0}, + {"bar-width", required_argument, NULL, 0}, + {"bar-orientation", required_argument, NULL, 0}, + {"bar-step", required_argument, NULL, 0}, + {"bar-height", required_argument, NULL, 0}, + // color options + // bar base? + // time tick decrease rate {NULL, no_argument, NULL, 0}}; @@ -1405,8 +1426,8 @@ int main(int argc, char *argv[]) { else if (strcmp(longopts[longoptind].name, "refresh-rate") == 0) { char* arg = optarg; refresh_rate = strtof(arg, NULL); - if (refresh_rate < 1.0) { - fprintf(stderr, "The given refresh rate of %fs is less than one second and was ignored.\n", refresh_rate); + if (refresh_rate < 0.0) { + fprintf(stderr, "The given refresh rate of %fs is less than zero seconds and was ignored.\n", refresh_rate); refresh_rate = 1.0; } } @@ -1480,6 +1501,31 @@ int main(int argc, char *argv[]) { show_clock = true; always_show_clock = true; } + else if (strcmp(longopts[longoptind].name, "bar-indicator") == 0) { + bar_enabled = true; + } + else if (strcmp(longopts[longoptind].name, "bar-width") == 0) { + int width = atoi(optarg); + if (width < 1) width = 15; + // num_bars and bar_heights* initialized later when we grab display info + } + else if (strcmp(longopts[longoptind].name, "bar-orientation") == 0) { + char* arg = optarg; + if (strcmp(arg, "vertical") == 0) + bar_orientation = BAR_VERT; + else if (strcmp(arg, "horizontal") == 0) + bar_orientation = BAR_FLAT; + else + errx(1, "bar orientation must be \"vertical\" or \"horizontal\"\n"); + } + else if (strcmp(longopts[longoptind].name, "bar-step") == 0) { + bar_step = atoi(optarg); + if (bar_step < 1) bar_step = 15; + } + else if (strcmp(longopts[longoptind].name, "bar-height") == 0) { + max_bar_height = atoi(optarg); + if (max_bar_height < 1) max_bar_height = 50; + } break; case 'f': @@ -1587,6 +1633,15 @@ int main(int argc, char *argv[]) { last_resolution[0] = screen->width_in_pixels; last_resolution[1] = screen->height_in_pixels; + if (bar_enabled && bar_width > 0) { + int tmp = screen->width_in_pixels; + if (bar_orientation == BAR_VERT) tmp = screen->height_in_pixels; + num_bars = tmp / bar_width; + if (tmp % bar_width != 0) ++num_bars; + + bar_heights = calloc(num_bars, sizeof(int)); + } + xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK, (uint32_t[]){XCB_EVENT_MASK_STRUCTURE_NOTIFY}); @@ -1702,7 +1757,7 @@ 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) { + if (show_clock || bar_enabled) { start_time_redraw_tick(main_loop); } ev_loop(main_loop, 0); diff --git a/unlock_indicator.c b/unlock_indicator.c index 4a2f0c0..3edf5d8 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -162,6 +162,17 @@ rgba_t sep16[4]; // just rgb rgb_t rgb16[3]; +// experimental bar stuff +extern bool bar_enabled; +extern int *bar_heights; +extern int num_bars; +extern int bar_width; +#define BAR_VERT 0 +#define BAR_FLAT 1 +extern int bar_orientation; +extern int bar_step; +extern int max_bar_height; + /* * Initialize all the color arrays once. * Called once after options are parsed. @@ -464,6 +475,21 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { * keypress. */ if (unlock_state == STATE_KEY_ACTIVE || unlock_state == STATE_BACKSPACE_ACTIVE) { + if (bar_enabled) { + // note: might be biased to cause more hits on lower indices + // maybe see about doing ((double) rand() / RAND_MAX) * num_bars + int index = rand() % num_bars; + bar_heights[index] = max_bar_height; + for(int i = 0; i < ((max_bar_height / bar_step) + 1); ++i) { + int low_ind = (index - i) % num_bars; + int high_ind = (index + i) % num_bars; + int tmp_height = max_bar_height - (bar_step * i); + if (tmp_height < 0) tmp_height = 0; + bar_heights[low_ind] = tmp_height; + bar_heights[high_ind] = tmp_height; + if (tmp_height == 0) break; + } + } cairo_set_line_width(ctx, RING_WIDTH); cairo_new_sub_path(ctx); double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0; @@ -766,14 +792,34 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { cairo_fill(xcb_ctx); } } - - cairo_set_source_rgba(bar_ctx, 1.0, 0, 0, 0.55); - cairo_rectangle(bar_ctx, 0, 0, resolution[0], RING_WIDTH); - cairo_fill(bar_ctx); - - cairo_set_source_surface(xcb_ctx, bar_output, 0, 0); - cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); - cairo_fill(xcb_ctx); + + if (bar_enabled) { + + cairo_set_source_rgba(bar_ctx, 0.0, 0, 0, 0.55); + cairo_rectangle(bar_ctx, 0, 0, resolution[0], bar_step); + cairo_fill(bar_ctx); + + // note: might be biased to cause more hits on lower indices + // maybe see about doing ((double) rand() / RAND_MAX) * num_bars + for(int i = 0; i < num_bars; ++i) { + cairo_set_source_rgba(bar_ctx, 1.0, 0, 0, 1.0); + if (bar_orientation == BAR_VERT) { // showerthought: this if statement would be better outside the for loop, or something + cairo_rectangle(bar_ctx, 0, i * bar_width, bar_heights[i], bar_width); + cairo_fill(bar_ctx); + } else { + cairo_rectangle(bar_ctx, i * bar_width, 0, bar_width, bar_heights[i]); + cairo_fill(bar_ctx); + } + } + + cairo_set_source_surface(xcb_ctx, bar_output, 0, 0); + cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); + cairo_fill(xcb_ctx); + for(int i = 0; i < num_bars; ++i) { + if (bar_heights[i] > 0) + --(bar_heights[i]); + } + } cairo_surface_destroy(xcb_output); cairo_surface_destroy(time_output);