mirror of
https://github.com/Raymo111/i3lock-color.git
synced 2024-12-02 14:05:43 -05:00
commit
e29a2d606b
3 changed files with 101 additions and 66 deletions
51
i3lock.c
51
i3lock.c
|
@ -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;
|
||||||
|
@ -1358,6 +1357,7 @@ static cairo_surface_t* load_image(char* image_path, char* image_raw_format) {
|
||||||
img = cairo_image_surface_create_for_data(jpg_data,
|
img = cairo_image_surface_create_for_data(jpg_data,
|
||||||
CAIRO_FORMAT_ARGB32, jpg_info.width, jpg_info.height,
|
CAIRO_FORMAT_ARGB32, jpg_info.width, jpg_info.height,
|
||||||
jpg_info.stride);
|
jpg_info.stride);
|
||||||
|
free(jpg_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1435,6 +1435,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'},
|
||||||
|
{"max", 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'},
|
||||||
|
@ -1575,7 +1578,7 @@ int main(int argc, char *argv[]) {
|
||||||
if (getenv("WAYLAND_DISPLAY") != NULL)
|
if (getenv("WAYLAND_DISPLAY") != NULL)
|
||||||
errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead");
|
errx(EXIT_FAILURE, "i3lock is a program for X11 and does not work on Wayland. Try https://github.com/swaywm/swaylock instead");
|
||||||
|
|
||||||
char *optstring = "hvnbdc:p:ui:tCeI:frsS:kB:m";
|
char *optstring = "hvnbdc:p:ui:tCFLMeI:frsS:kB:m";
|
||||||
char *arg = NULL;
|
char *arg = NULL;
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
char padded[9] = "ffffffff"; \
|
char padded[9] = "ffffffff"; \
|
||||||
|
@ -1624,16 +1627,34 @@ 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: Only one background type can be used.");
|
||||||
}
|
}
|
||||||
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: Only one background type can be used.");
|
||||||
}
|
}
|
||||||
centered = true;
|
bg_type = CENTER;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
if(bg_type != NONE) {
|
||||||
|
errx(EXIT_FAILURE, "i3lock-color: Only one background type can be used.");
|
||||||
|
}
|
||||||
|
bg_type = FILL;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
if(bg_type != NONE) {
|
||||||
|
errx(EXIT_FAILURE, "i3lock-color: Only one background type can be used.");
|
||||||
|
}
|
||||||
|
bg_type = SCALE;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
if(bg_type != NONE) {
|
||||||
|
errx(EXIT_FAILURE, "i3lock-color: Only one background type can be used.");
|
||||||
|
}
|
||||||
|
bg_type = MAX;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (!strcmp(optarg, "win")) {
|
if (!strcmp(optarg, "win")) {
|
||||||
|
@ -2349,20 +2370,22 @@ 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;
|
||||||
|
bg_type = NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_window_t stolen_focus = find_focused_window(conn, screen->root);
|
xcb_window_t stolen_focus = find_focused_window(conn, screen->root);
|
||||||
|
|
|
@ -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,64 @@ 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:
|
||||||
|
for (int i = 0; i < xr_screens; i++) {
|
||||||
|
cairo_save(xcb_ctx);
|
||||||
|
|
||||||
xcb_timestamp_t timestamp = reply->config_timestamp;
|
// Scale image according to bg_type and aspect ratios
|
||||||
int len = xcb_randr_get_screen_resources_current_outputs_length(reply);
|
double scale_x = 1, scale_y = 1;
|
||||||
xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(reply);
|
if (bg_type == SCALE) {
|
||||||
|
scale_x = xr_resolutions[i].width / image_width;
|
||||||
|
scale_y = xr_resolutions[i].height / image_height;
|
||||||
|
} else {
|
||||||
|
double aspect_diff = (double) xr_resolutions[i].height / xr_resolutions[i].width - image_height / image_width;
|
||||||
|
if((bg_type == MAX && aspect_diff > 0) || (bg_type == FILL && aspect_diff < 0)) {
|
||||||
|
scale_x = scale_y = xr_resolutions[i].width / image_width;
|
||||||
|
} else if ((bg_type == MAX && aspect_diff < 0) || (bg_type == FILL && aspect_diff > 0)) {
|
||||||
|
scale_x = scale_y = xr_resolutions[i].height / image_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For every output
|
if (scale_x != 0 || scale_y != 0) {
|
||||||
for (int i = 0; i < len; i++) {
|
cairo_scale(xcb_ctx, scale_x, scale_y);
|
||||||
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);
|
|
||||||
if (output == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (output->crtc == XCB_NONE || output->connection == XCB_RANDR_CONNECTION_DISCONNECTED)
|
// Place image in the middle
|
||||||
continue;
|
double origin_x = (xr_resolutions[i].x + xr_resolutions[i].width / 2) / scale_x - image_width / 2;
|
||||||
|
double origin_y = (xr_resolutions[i].y + xr_resolutions[i].height / 2) / scale_y - image_height / 2;
|
||||||
|
|
||||||
xcb_randr_get_crtc_info_cookie_t infoCookie = xcb_randr_get_crtc_info(conn, output->crtc,
|
cairo_set_source_surface(xcb_ctx, img, origin_x, origin_y);
|
||||||
timestamp);
|
cairo_paint(xcb_ctx);
|
||||||
xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(conn, infoCookie, NULL);
|
|
||||||
|
|
||||||
// Paint around center of monitor
|
cairo_restore(xcb_ctx);
|
||||||
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);
|
break;
|
||||||
|
|
||||||
cairo_set_source_surface(xcb_ctx, img, origin_x, origin_y);
|
case 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, root_resolution[0], root_resolution[1]);
|
||||||
|
cairo_fill(xcb_ctx);
|
||||||
|
cairo_pattern_destroy(pattern);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
cairo_set_source_surface(xcb_ctx, img, 0, 0);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue