Added option to display the provided image centered on all monitors
This commit is contained in:
parent
b386a984e5
commit
8bb468697c
26
i3lock.c
26
i3lock.c
|
@ -229,6 +229,7 @@ int slideshow_interval = 10;
|
||||||
bool slideshow_random_selection = false;
|
bool slideshow_random_selection = false;
|
||||||
|
|
||||||
bool tile = false;
|
bool tile = false;
|
||||||
|
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;
|
||||||
|
@ -1379,6 +1380,7 @@ int main(int argc, char *argv[]) {
|
||||||
{"image", required_argument, NULL, 'i'},
|
{"image", required_argument, NULL, 'i'},
|
||||||
{"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'},
|
||||||
{"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'},
|
||||||
|
@ -1494,7 +1496,7 @@ int main(int argc, char *argv[]) {
|
||||||
if ((username = pw->pw_name) == NULL)
|
if ((username = pw->pw_name) == NULL)
|
||||||
errx(EXIT_FAILURE, "pw->pw_name is NULL.");
|
errx(EXIT_FAILURE, "pw->pw_name is NULL.");
|
||||||
|
|
||||||
char *optstring = "hvnbdc:p:ui:teI:frsS:kB:m";
|
char *optstring = "hvnbdc:p:ui:tCeI:frsS:kB:m";
|
||||||
char *arg = NULL;
|
char *arg = NULL;
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
|
|
||||||
|
@ -1534,8 +1536,17 @@ int main(int argc, char *argv[]) {
|
||||||
image_path = strdup(optarg);
|
image_path = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
|
if(centered) {
|
||||||
|
errx(EXIT_FAILURE, "i3lock-color: Options tiling and centered conflict.");
|
||||||
|
}
|
||||||
tile = true;
|
tile = true;
|
||||||
break;
|
break;
|
||||||
|
case 'C':
|
||||||
|
if(tile) {
|
||||||
|
errx(EXIT_FAILURE, "i3lock-color: Options tiling and centered conflict.");
|
||||||
|
}
|
||||||
|
centered = true;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (!strcmp(optarg, "win")) {
|
if (!strcmp(optarg, "win")) {
|
||||||
curs_choice = CURS_WIN;
|
curs_choice = CURS_WIN;
|
||||||
|
@ -2183,10 +2194,10 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
blur_image_surface(blur_img, blur_sigma);
|
blur_image_surface(blur_img, blur_sigma);
|
||||||
if (img) {
|
if (img) {
|
||||||
if (!tile) {
|
// Display image centered on all outputs.
|
||||||
cairo_set_source_surface(ctx, img, 0, 0);
|
if (centered) {
|
||||||
cairo_paint(ctx);
|
draw_on_all_outputs(ctx);
|
||||||
} else {
|
} else if (tile) {
|
||||||
/* create a pattern and fill a rectangle as big as the screen */
|
/* create a pattern and fill a rectangle as big as the screen */
|
||||||
cairo_pattern_t *pattern;
|
cairo_pattern_t *pattern;
|
||||||
pattern = cairo_pattern_create_for_surface(img);
|
pattern = cairo_pattern_create_for_surface(img);
|
||||||
|
@ -2195,9 +2206,10 @@ int main(int argc, char *argv[]) {
|
||||||
cairo_rectangle(ctx, 0, 0, last_resolution[0], last_resolution[1]);
|
cairo_rectangle(ctx, 0, 0, last_resolution[0], last_resolution[1]);
|
||||||
cairo_fill(ctx);
|
cairo_fill(ctx);
|
||||||
cairo_pattern_destroy(pattern);
|
cairo_pattern_destroy(pattern);
|
||||||
|
} else {
|
||||||
|
cairo_set_source_surface(ctx, img, 0, 0);
|
||||||
|
cairo_paint(ctx);
|
||||||
}
|
}
|
||||||
cairo_set_source_surface(ctx, img, 0, 0);
|
|
||||||
cairo_paint(ctx);
|
|
||||||
cairo_surface_destroy(img);
|
cairo_surface_destroy(img);
|
||||||
img = NULL;
|
img = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/randr.h>
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <cairo/cairo-xcb.h>
|
#include <cairo/cairo-xcb.h>
|
||||||
|
@ -68,7 +69,8 @@ extern bool slideshow_random_selection;
|
||||||
|
|
||||||
unsigned long lastCheck;
|
unsigned long lastCheck;
|
||||||
|
|
||||||
/* Whether the image should be tiled. */
|
/* Whether the image should be tiled or centered. */
|
||||||
|
extern bool centered;
|
||||||
extern bool tile;
|
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];
|
||||||
|
@ -671,9 +673,8 @@ static void draw_elements(cairo_t *const ctx, DrawData const *const draw_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draws global image with fill color onto a pixmap with the given
|
* Draws global image with fill color onto a provided drawable with the given
|
||||||
* resolution and returns it.
|
* resolution.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void draw_image(uint32_t *resolution, xcb_drawable_t drawable) {
|
void draw_image(uint32_t *resolution, xcb_drawable_t drawable) {
|
||||||
const double scaling_factor = get_dpi_value() / 96.0;
|
const double scaling_factor = get_dpi_value() / 96.0;
|
||||||
|
@ -719,10 +720,10 @@ void draw_image(uint32_t *resolution, xcb_drawable_t drawable) {
|
||||||
cairo_set_source_surface(xcb_ctx, blur_img, 0, 0);
|
cairo_set_source_surface(xcb_ctx, blur_img, 0, 0);
|
||||||
cairo_paint(xcb_ctx);
|
cairo_paint(xcb_ctx);
|
||||||
} else { // img can no longer be non-NULL if blur_img is not null
|
} else { // img can no longer be non-NULL if blur_img is not null
|
||||||
if (!tile) {
|
if (centered)
|
||||||
cairo_set_source_surface(xcb_ctx, img, 0, 0);
|
draw_on_all_outputs(xcb_ctx);
|
||||||
cairo_paint(xcb_ctx);
|
}
|
||||||
} else {
|
else if (tile) {
|
||||||
/* create a pattern and fill a rectangle as big as the screen */
|
/* create a pattern and fill a rectangle as big as the screen */
|
||||||
cairo_pattern_t *pattern;
|
cairo_pattern_t *pattern;
|
||||||
pattern = cairo_pattern_create_for_surface(img);
|
pattern = cairo_pattern_create_for_surface(img);
|
||||||
|
@ -731,6 +732,9 @@ void draw_image(uint32_t *resolution, xcb_drawable_t drawable) {
|
||||||
cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]);
|
cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]);
|
||||||
cairo_fill(xcb_ctx);
|
cairo_fill(xcb_ctx);
|
||||||
cairo_pattern_destroy(pattern);
|
cairo_pattern_destroy(pattern);
|
||||||
|
} else {
|
||||||
|
cairo_set_source_surface(xcb_ctx, img, 0, 0);
|
||||||
|
cairo_paint(xcb_ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1064,6 +1068,41 @@ void draw_image(uint32_t *resolution, xcb_drawable_t drawable) {
|
||||||
cairo_destroy(xcb_ctx);
|
cairo_destroy(xcb_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void draw_on_all_outputs(cairo_t* xcb_ctx) {
|
||||||
|
double image_width = cairo_image_surface_get_width(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(
|
||||||
|
conn, xcb_randr_get_screen_resources_current(conn, screen->root), NULL);
|
||||||
|
|
||||||
|
xcb_timestamp_t timestamp = reply->config_timestamp;
|
||||||
|
int len = xcb_randr_get_screen_resources_current_outputs_length(reply);
|
||||||
|
xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(reply);
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
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)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
xcb_randr_get_crtc_info_cookie_t infoCookie = xcb_randr_get_crtc_info(conn, output->crtc,
|
||||||
|
timestamp);
|
||||||
|
xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(conn, infoCookie, NULL);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
free(crtc);
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calls draw_image on a new pixmap and swaps that with the current pixmap
|
* Calls draw_image on a new pixmap and swaps that with the current pixmap
|
||||||
*
|
*
|
||||||
|
|
|
@ -39,6 +39,7 @@ typedef struct {
|
||||||
} DrawData;
|
} DrawData;
|
||||||
|
|
||||||
void draw_image(uint32_t* resolution, xcb_drawable_t drawable);
|
void draw_image(uint32_t* resolution, xcb_drawable_t drawable);
|
||||||
|
void draw_on_all_outputs(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 New Issue