refactor background types to use enum

This commit is contained in:
Rio6 2021-05-29 00:27:15 -04:00
parent de35e177fb
commit 91092a1bf1
3 changed files with 85 additions and 67 deletions

View File

@ -243,14 +243,13 @@ static uint8_t xkb_base_error;
static int randr_base = -1; static int randr_base = -1;
cairo_surface_t *img = NULL; cairo_surface_t *img = NULL;
cairo_surface_t *blur_img = NULL;
cairo_surface_t *img_slideshow[256]; cairo_surface_t *img_slideshow[256];
int slideshow_image_count = 0; int slideshow_image_count = 0;
int slideshow_interval = 10; int slideshow_interval = 10;
bool slideshow_random_selection = false; bool slideshow_random_selection = false;
bool tile = false; background_type_t bg_type = NONE;
bool centered = false;
bool ignore_empty_password = false; bool ignore_empty_password = false;
bool skip_repeated_empty_password = false; bool skip_repeated_empty_password = false;
bool pass_media_keys = false; bool pass_media_keys = false;
@ -1435,6 +1434,9 @@ int main(int argc, char *argv[]) {
{"raw", required_argument, NULL, 998}, {"raw", required_argument, NULL, 998},
{"tiling", no_argument, NULL, 't'}, {"tiling", no_argument, NULL, 't'},
{"centered", no_argument, NULL, 'C'}, {"centered", no_argument, NULL, 'C'},
{"fill", no_argument, NULL, 'F'},
{"scale", no_argument, NULL, 'L'},
{"scale", no_argument, NULL, 'M'},
{"ignore-empty-password", no_argument, NULL, 'e'}, {"ignore-empty-password", no_argument, NULL, 'e'},
{"inactivity-timeout", required_argument, NULL, 'I'}, {"inactivity-timeout", required_argument, NULL, 'I'},
{"show-failed-attempts", no_argument, NULL, 'f'}, {"show-failed-attempts", no_argument, NULL, 'f'},
@ -1624,16 +1626,33 @@ int main(int argc, char *argv[]) {
image_path = strdup(optarg); image_path = strdup(optarg);
break; break;
case 't': case 't':
if(centered) { if(bg_type != NONE) {
errx(EXIT_FAILURE, "i3lock-color: Options tiling and centered conflict."); errx(EXIT_FAILURE, "i3lock-color: Options tiling, centered, and fill conflict.");
} }
tile = true; bg_type = TILE;
break; break;
case 'C': case 'C':
if(tile) { if(bg_type != NONE) {
errx(EXIT_FAILURE, "i3lock-color: Options tiling and centered conflict."); errx(EXIT_FAILURE, "i3lock-color: Options tiling, centered, and fill conflict.");
} }
centered = true; bg_type = CENTER;
break;
case 'F':
if(bg_type != NONE) {
errx(EXIT_FAILURE, "i3lock-color: Options tiling, centered, and fill conflict.");
}
bg_type = FILL;
case 'L':
if(bg_type != NONE) {
errx(EXIT_FAILURE, "i3lock-color: Options tiling, centered, and fill conflict.");
}
bg_type = SCALE;
break;
case 'M':
if(bg_type != NONE) {
errx(EXIT_FAILURE, "i3lock-color: Options tiling, centered, and fill conflict.");
}
bg_type = MAX;
break; break;
case 'p': case 'p':
if (!strcmp(optarg, "win")) { if (!strcmp(optarg, "win")) {
@ -2349,20 +2368,21 @@ int main(int argc, char *argv[]) {
*blur_pixmap = capture_bg_pixmap(conn, screen, last_resolution); *blur_pixmap = capture_bg_pixmap(conn, screen, last_resolution);
cairo_surface_t *xcb_img = cairo_xcb_surface_create(conn, *blur_pixmap, vistype, last_resolution[0], last_resolution[1]); cairo_surface_t *xcb_img = cairo_xcb_surface_create(conn, *blur_pixmap, vistype, last_resolution[0], last_resolution[1]);
blur_img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, last_resolution[0], last_resolution[1]); cairo_surface_t *blur_img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, last_resolution[0], last_resolution[1]);
cairo_t *ctx = cairo_create(blur_img); cairo_t *ctx = cairo_create(blur_img);
cairo_set_source_surface(ctx, xcb_img, 0, 0); cairo_set_source_surface(ctx, xcb_img, 0, 0);
cairo_paint(ctx); cairo_paint(ctx);
blur_image_surface(blur_img, blur_sigma); blur_image_surface(blur_img, blur_sigma);
if (img) { if (img) {
// Display image centered on all outputs. // Display image on all outputs.
draw_image(last_resolution, ctx); draw_image(last_resolution, img, ctx);
cairo_surface_destroy(img); cairo_surface_destroy(img);
img = NULL;
} }
cairo_destroy(ctx); cairo_destroy(ctx);
cairo_surface_destroy(xcb_img); cairo_surface_destroy(xcb_img);
img = blur_img;
} }
xcb_window_t stolen_focus = find_focused_window(conn, screen->root); xcb_window_t stolen_focus = find_focused_window(conn, screen->root);

View File

@ -62,7 +62,6 @@ extern char *modifier_string;
/* A Cairo surface containing the specified image (-i), if any. */ /* A Cairo surface containing the specified image (-i), if any. */
extern cairo_surface_t *img; extern cairo_surface_t *img;
extern cairo_surface_t *blur_img;
extern cairo_surface_t *img_slideshow[256]; extern cairo_surface_t *img_slideshow[256];
extern int slideshow_image_count; extern int slideshow_image_count;
extern int slideshow_interval; extern int slideshow_interval;
@ -70,9 +69,8 @@ extern bool slideshow_random_selection;
unsigned long lastCheck; unsigned long lastCheck;
/* Whether the image should be tiled or centered. */ /* How the background image should be displayed */
extern bool centered; extern background_type_t bg_type;
extern bool tile;
/* The background color to use (in hex). */ /* The background color to use (in hex). */
extern char color[9]; extern char color[9];
/* indicator color options */ /* indicator color options */
@ -699,13 +697,8 @@ void render_lock(uint32_t *resolution, xcb_drawable_t drawable) {
} }
} }
if (blur_img || img) { if (img) {
if (blur_img) { draw_image(resolution, img, xcb_ctx);
cairo_set_source_surface(xcb_ctx, blur_img, 0, 0);
cairo_paint(xcb_ctx);
} else { // img can no longer be non-NULL if blur_img is not null
draw_image(resolution, xcb_ctx);
}
} else { } else {
cairo_set_source_rgba(xcb_ctx, background.red, background.green, background.blue, background.alpha); cairo_set_source_rgba(xcb_ctx, background.red, background.green, background.blue, background.alpha);
cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]);
@ -1108,54 +1101,50 @@ void render_lock(uint32_t *resolution, xcb_drawable_t drawable) {
* Draws the configured image on the provided context. The image is drawn centered on all monitors, tiled, or just * Draws the configured image on the provided context. The image is drawn centered on all monitors, tiled, or just
* painted starting from 0,0. * painted starting from 0,0.
*/ */
void draw_image(uint32_t* resolution, cairo_t* xcb_ctx) { void draw_image(uint32_t* root_resolution, cairo_surface_t *img, cairo_t* xcb_ctx) {
if (centered) { double image_width = cairo_image_surface_get_width(img);
double image_width = cairo_image_surface_get_width(img); double image_height = cairo_image_surface_get_height(img);
double image_height = cairo_image_surface_get_height(img);
xcb_randr_get_screen_resources_current_reply_t *reply = xcb_randr_get_screen_resources_current_reply( switch (bg_type) {
conn, xcb_randr_get_screen_resources_current(conn, screen->root), NULL); case CENTER:
case FILL:
case SCALE:
case MAX:
cairo_save(xcb_ctx);
for (int i = 0; i < xr_screens; i++) {
// Paint around center of monitor
double origin_x = xr_resolutions[i].x + (xr_resolutions[i].width / 2.0 - image_width / 2.0);
double origin_y = xr_resolutions[i].y + (xr_resolutions[i].height / 2.0 - image_height / 2.0);
xcb_timestamp_t timestamp = reply->config_timestamp; if (bg_type == SCALE) {
int len = xcb_randr_get_screen_resources_current_outputs_length(reply); cairo_scale(xcb_ctx,
xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(reply); (double) xr_resolutions[i].width / image_width,
(double) xr_resolutions[i].height / image_height);
}
// For every output cairo_set_source_surface(xcb_ctx, img, origin_x, origin_y);
for (int i = 0; i < len; i++) { cairo_paint(xcb_ctx);
xcb_randr_get_output_info_reply_t *output = xcb_randr_get_output_info_reply( }
conn, xcb_randr_get_output_info(conn, randr_outputs[i], timestamp), NULL); cairo_restore(xcb_ctx);
if (output == NULL) break;
continue;
if (output->crtc == XCB_NONE || output->connection == XCB_RANDR_CONNECTION_DISCONNECTED) case TILE:
continue; {
/* create a pattern and fill a rectangle as big as the screen */
cairo_pattern_t *pattern;
pattern = cairo_pattern_create_for_surface(img);
cairo_set_source(xcb_ctx, pattern);
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
cairo_rectangle(xcb_ctx, 0, 0, root_resolution[0], root_resolution[1]);
cairo_fill(xcb_ctx);
cairo_pattern_destroy(pattern);
break;
}
xcb_randr_get_crtc_info_cookie_t infoCookie = xcb_randr_get_crtc_info(conn, output->crtc, default:
timestamp); cairo_set_source_surface(xcb_ctx, img, 0, 0);
xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(conn, infoCookie, NULL);
// Paint around center of monitor
double origin_x = crtc->x + (crtc->width / 2.0 - image_width / 2.0);
double origin_y = crtc->y + (crtc->height / 2.0 - image_height / 2.0);
cairo_set_source_surface(xcb_ctx, img, origin_x, origin_y);
cairo_paint(xcb_ctx); cairo_paint(xcb_ctx);
break;
free(crtc);
free(output);
}
} else if (tile) {
/* create a pattern and fill a rectangle as big as the screen */
cairo_pattern_t *pattern;
pattern = cairo_pattern_create_for_surface(img);
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);
} else {
cairo_set_source_surface(xcb_ctx, img, 0, 0);
cairo_paint(xcb_ctx);
} }
} }

View File

@ -38,8 +38,17 @@ typedef struct {
double bar_x, bar_y, bar_width; double bar_x, bar_y, bar_width;
} DrawData; } DrawData;
typedef enum {
NONE,
TILE,
CENTER,
FILL,
SCALE,
MAX,
} background_type_t;
void render_lock(uint32_t* resolution, xcb_drawable_t drawable); void render_lock(uint32_t* resolution, xcb_drawable_t drawable);
void draw_image(uint32_t* resolution, cairo_t* xcb_ctx); void draw_image(uint32_t* resolution, cairo_surface_t* img, cairo_t* xcb_ctx);
void init_colors_once(void); void init_colors_once(void);
void redraw_screen(void); void redraw_screen(void);
void clear_indicator(void); void clear_indicator(void);