aboutsummaryrefslogtreecommitdiffstats
path: root/common/background-image.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-04-02 21:57:13 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-04-04 18:47:48 -0400
commita28730edee1896242012f80fd0e63e7966652e02 (patch)
treee85d2479ce1b77e23b3c3e34c1d9e0bf87ed30f0 /common/background-image.c
parentMerge pull request #1731 from acrisci/ipc-window-events (diff)
downloadsway-a28730edee1896242012f80fd0e63e7966652e02.tar.gz
sway-a28730edee1896242012f80fd0e63e7966652e02.tar.zst
sway-a28730edee1896242012f80fd0e63e7966652e02.zip
Move swaybg background rendering into common/
swaylock will use it too
Diffstat (limited to 'common/background-image.c')
-rw-r--r--common/background-image.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/common/background-image.c b/common/background-image.c
new file mode 100644
index 00000000..2988c2e2
--- /dev/null
+++ b/common/background-image.c
@@ -0,0 +1,100 @@
1#include <assert.h>
2#include <stdbool.h>
3#include <wlr/util/log.h>
4#include "background-image.h"
5#include "cairo.h"
6
7cairo_surface_t *load_background_image(const char *path) {
8 cairo_surface_t *image;
9#ifdef HAVE_GDK_PIXBUF
10 GError *err = NULL;
11 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err);
12 if (!pixbuf) {
13 wlr_log(L_ERROR, "Failed to load background image.");
14 return false;
15 }
16 image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
17 g_object_unref(pixbuf);
18#else
19 image = cairo_image_surface_create_from_png(path);
20#endif //HAVE_GDK_PIXBUF
21 if (!image) {
22 wlr_log(L_ERROR, "Failed to read background image.");
23 return NULL;
24 }
25 if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
26 wlr_log(L_ERROR, "Failed to read background image: %s."
27#ifndef HAVE_GDK_PIXBUF
28 "\nSway was compiled without gdk_pixbuf support, so only"
29 "\nPNG images can be loaded. This is the likely cause."
30#endif //HAVE_GDK_PIXBUF
31 , cairo_status_to_string(cairo_surface_status(image)));
32 return NULL;
33 }
34 return image;
35}
36
37void render_background_image(cairo_t *cairo, cairo_surface_t *image,
38 enum background_mode mode, int buffer_width, int buffer_height,
39 int buffer_scale) {
40 double width = cairo_image_surface_get_width(image);
41 double height = cairo_image_surface_get_height(image);
42
43 switch (mode) {
44 case BACKGROUND_MODE_STRETCH:
45 cairo_scale(cairo,
46 (double)buffer_width / width,
47 (double)buffer_height / height);
48 cairo_set_source_surface(cairo, image, 0, 0);
49 break;
50 case BACKGROUND_MODE_FILL: {
51 double window_ratio = (double)buffer_width / buffer_height;
52 double bg_ratio = width / height;
53
54 if (window_ratio > bg_ratio) {
55 double scale = (double)buffer_width / width;
56 cairo_scale(cairo, scale, scale);
57 cairo_set_source_surface(cairo, image,
58 0, (double)buffer_height / 2 / scale - height / 2);
59 } else {
60 double scale = (double)buffer_height / height;
61 cairo_scale(cairo, scale, scale);
62 cairo_set_source_surface(cairo, image,
63 (double)buffer_width / 2 / scale - width / 2, 0);
64 }
65 break;
66 }
67 case BACKGROUND_MODE_FIT: {
68 double window_ratio = (double)buffer_width / buffer_height;
69 double bg_ratio = width / height;
70
71 if (window_ratio > bg_ratio) {
72 double scale = (double)buffer_height / height;
73 cairo_scale(cairo, scale, scale);
74 cairo_set_source_surface(cairo, image,
75 (double)buffer_width / 2 / scale - width / 2, 0);
76 } else {
77 double scale = (double)buffer_width / width;
78 cairo_scale(cairo, scale, scale);
79 cairo_set_source_surface(cairo, image,
80 0, (double)buffer_height / 2 / scale - height / 2);
81 }
82 break;
83 }
84 case BACKGROUND_MODE_CENTER:
85 cairo_set_source_surface(cairo, image,
86 (double)buffer_width / 2 - width / 2,
87 (double)buffer_height / 2 - height / 2);
88 break;
89 case BACKGROUND_MODE_TILE: {
90 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
91 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
92 cairo_set_source(cairo, pattern);
93 break;
94 }
95 case BACKGROUND_MODE_SOLID_COLOR:
96 assert(0);
97 break;
98 }
99 cairo_paint(cairo);
100}