From c9de62062672a44d0a3576af6049b12839bd330a Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Wed, 27 Jul 2016 20:46:00 +0200 Subject: [PATCH] add -s/--scaled option to scale the image on all available screens --- i3lock.1 | 5 +++++ i3lock.c | 13 ++++++++++++- unlock_indicator.c | 25 +++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/i3lock.1 b/i3lock.1 index 55af52d..a2a53bc 100644 --- a/i3lock.1 +++ b/i3lock.1 @@ -83,6 +83,11 @@ format: rrggbb (i.e. ff0000 is red). If an image is specified (via \-i) it will display the image tiled all over the screen (if it is a multi-monitor setup, the image is visible on all screens). +.TP +.B \-s, \-\-scaled +If an image is specified (via \-i) it will display the image scaled on each +available screen. + .TP .BI \-p\ win|default \fR,\ \fB\-\-pointer= win|default If you specify "default", diff --git a/i3lock.c b/i3lock.c index 380cab4..e51430a 100644 --- a/i3lock.c +++ b/i3lock.c @@ -76,6 +76,7 @@ static uint8_t xkb_base_error; cairo_surface_t *img = NULL; bool tile = false; +bool scaled = false; bool ignore_empty_password = false; bool skip_repeated_empty_password = false; @@ -780,6 +781,7 @@ int main(int argc, char *argv[]) { {"no-unlock-indicator", no_argument, NULL, 'u'}, {"image", required_argument, NULL, 'i'}, {"tiling", no_argument, NULL, 't'}, + {"scaled", no_argument, NULL, 's'}, {"ignore-empty-password", no_argument, NULL, 'e'}, {"inactivity-timeout", required_argument, NULL, 'I'}, {"show-failed-attempts", no_argument, NULL, 'f'}, @@ -790,7 +792,7 @@ int main(int argc, char *argv[]) { if ((username = pw->pw_name) == NULL) errx(EXIT_FAILURE, "pw->pw_name is NULL.\n"); - char *optstring = "hvnbdc:p:ui:teI:f"; + char *optstring = "hvnbdc:p:ui:teI:fs"; while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) { switch (o) { case 'v': @@ -828,6 +830,15 @@ int main(int argc, char *argv[]) { break; case 't': tile = true; + if (scaled) { + errx(EXIT_FAILURE, "the tile and scaled option can not be used at the same time\n"); + } + break; + case 's': + scaled = true; + if (tile) { + errx(EXIT_FAILURE, "the tile and scaled option can not be used at the same time\n"); + } break; case 'p': if (!strcmp(optarg, "win")) { diff --git a/unlock_indicator.c b/unlock_indicator.c index 3b94d17..c2a0231 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -53,6 +53,8 @@ extern cairo_surface_t *img; /* Whether the image should be tiled. */ extern bool tile; +/* Whether the image should be scaled per screen. */ +extern bool scaled; /* The background color to use (in hex). */ extern char color[7]; @@ -116,8 +118,27 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { if (img) { if (!tile) { - cairo_set_source_surface(xcb_ctx, img, 0, 0); - cairo_paint(xcb_ctx); + if (xr_screens > 0 && scaled) { + for (int screen = 0; screen < xr_screens; screen++) { + double w, h, scale_x, scale_y; + cairo_save(xcb_ctx); + w = cairo_image_surface_get_width(img); + h = cairo_image_surface_get_height(img); + scale_x = ((double)xr_resolutions[screen].width / w); + scale_y = ((double)xr_resolutions[screen].height / h); + cairo_scale(xcb_ctx, + scale_x, + scale_y); + cairo_set_source_surface(xcb_ctx, img, + xr_resolutions[screen].x / scale_x, + xr_resolutions[screen].y / scale_y); + cairo_paint(xcb_ctx); + cairo_restore(xcb_ctx); + } + } else { + cairo_set_source_surface(xcb_ctx, img, 0, 0); + cairo_paint(xcb_ctx); + } } else { /* create a pattern and fill a rectangle as big as the screen */ cairo_pattern_t *pattern;