aboutsummaryrefslogtreecommitdiffstats
path: root/swaybg
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 /swaybg
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 'swaybg')
-rw-r--r--swaybg/main.c113
1 files changed, 6 insertions, 107 deletions
diff --git a/swaybg/main.c b/swaybg/main.c
index c282a707..ffefcd08 100644
--- a/swaybg/main.c
+++ b/swaybg/main.c
@@ -7,20 +7,12 @@
7#include <time.h> 7#include <time.h>
8#include <wayland-client.h> 8#include <wayland-client.h>
9#include <wlr/util/log.h> 9#include <wlr/util/log.h>
10#include "background-image.h"
10#include "pool-buffer.h" 11#include "pool-buffer.h"
11#include "cairo.h" 12#include "cairo.h"
12#include "util.h" 13#include "util.h"
13#include "wlr-layer-shell-unstable-v1-client-protocol.h" 14#include "wlr-layer-shell-unstable-v1-client-protocol.h"
14 15
15enum background_mode {
16 BACKGROUND_MODE_STRETCH,
17 BACKGROUND_MODE_FILL,
18 BACKGROUND_MODE_FIT,
19 BACKGROUND_MODE_CENTER,
20 BACKGROUND_MODE_TILE,
21 BACKGROUND_MODE_SOLID_COLOR,
22};
23
24struct swaybg_args { 16struct swaybg_args {
25 int output_idx; 17 int output_idx;
26 const char *path; 18 const char *path;
@@ -71,85 +63,16 @@ bool is_valid_color(const char *color) {
71 return true; 63 return true;
72} 64}
73 65
74static void render_image(struct swaybg_state *state) {
75 cairo_t *cairo = state->current_buffer->cairo;
76 cairo_surface_t *image = state->context.image;
77 double width = cairo_image_surface_get_width(image);
78 double height = cairo_image_surface_get_height(image);
79 int buffer_width = state->width * state->scale;
80 int buffer_height = state->height * state->scale;
81
82 switch (state->args->mode) {
83 case BACKGROUND_MODE_STRETCH:
84 cairo_scale(cairo, (double)buffer_width / width,
85 (double)buffer_height / height);
86 cairo_set_source_surface(cairo, image, 0, 0);
87 break;
88 case BACKGROUND_MODE_FILL: {
89 double window_ratio = (double)buffer_width / buffer_height;
90 double bg_ratio = width / height;
91
92 if (window_ratio > bg_ratio) {
93 double scale = (double)buffer_width / width;
94 cairo_scale(cairo, scale, scale);
95 cairo_set_source_surface(cairo, image,
96 0, (double)buffer_height / 2 / scale - height / 2);
97 } else {
98 double scale = (double)buffer_height / height;
99 cairo_scale(cairo, scale, scale);
100 cairo_set_source_surface(cairo, image,
101 (double)buffer_width / 2 / scale - width / 2, 0);
102 }
103 break;
104 }
105 case BACKGROUND_MODE_FIT: {
106 double window_ratio = (double)buffer_width / buffer_height;
107 double bg_ratio = width / height;
108
109 if (window_ratio > bg_ratio) {
110 double scale = (double)buffer_height / height;
111 cairo_scale(cairo, scale, scale);
112 cairo_set_source_surface(cairo, image,
113 (double)buffer_width / 2 / scale - width / 2, 0);
114 } else {
115 double scale = (double)buffer_width / width;
116 cairo_scale(cairo, scale, scale);
117 cairo_set_source_surface(cairo, image,
118 0, (double)buffer_height / 2 / scale - height / 2);
119 }
120 break;
121 }
122 case BACKGROUND_MODE_CENTER:
123 cairo_set_source_surface(cairo, image,
124 (double)buffer_width / 2 - width / 2,
125 (double)buffer_height / 2 - height / 2);
126 break;
127 case BACKGROUND_MODE_TILE: {
128 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
129 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
130 cairo_set_source(cairo, pattern);
131 break;
132 }
133 case BACKGROUND_MODE_SOLID_COLOR:
134 assert(0);
135 break;
136 }
137 cairo_paint(cairo);
138}
139
140static void render_frame(struct swaybg_state *state) { 66static void render_frame(struct swaybg_state *state) {
141 state->current_buffer = get_next_buffer(state->shm, state->buffers, 67 state->current_buffer = get_next_buffer(state->shm, state->buffers,
142 state->width * state->scale, state->height * state->scale); 68 state->width * state->scale, state->height * state->scale);
143 cairo_t *cairo = state->current_buffer->cairo; 69 cairo_t *cairo = state->current_buffer->cairo;
144 70 if (state->args->mode == BACKGROUND_MODE_SOLID_COLOR) {
145 switch (state->args->mode) {
146 case BACKGROUND_MODE_SOLID_COLOR:
147 cairo_set_source_u32(cairo, state->context.color); 71 cairo_set_source_u32(cairo, state->context.color);
148 cairo_paint(cairo); 72 cairo_paint(cairo);
149 break; 73 } else {
150 default: 74 render_background_image(cairo, state->context.image,
151 render_image(state); 75 state->args->mode, state->width, state->height, state->scale);
152 break;
153 } 76 }
154 77
155 wl_surface_set_buffer_scale(state->surface, state->scale); 78 wl_surface_set_buffer_scale(state->surface, state->scale);
@@ -163,31 +86,7 @@ static bool prepare_context(struct swaybg_state *state) {
163 state->context.color = parse_color(state->args->path); 86 state->context.color = parse_color(state->args->path);
164 return is_valid_color(state->args->path); 87 return is_valid_color(state->args->path);
165 } 88 }
166#ifdef HAVE_GDK_PIXBUF 89 if (!(state->context.image = load_background_image(state->args->path))) {
167 GError *err = NULL;
168 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(state->args->path, &err);
169 if (!pixbuf) {
170 wlr_log(L_ERROR, "Failed to load background image.");
171 return false;
172 }
173 state->context.image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
174 g_object_unref(pixbuf);
175#else
176 state->context.image = cairo_image_surface_create_from_png(
177 state->args->path);
178#endif //HAVE_GDK_PIXBUF
179 if (!state->context.image) {
180 wlr_log(L_ERROR, "Failed to read background image.");
181 return false;
182 }
183 if (cairo_surface_status(state->context.image) != CAIRO_STATUS_SUCCESS) {
184 wlr_log(L_ERROR, "Failed to read background image: %s."
185#ifndef HAVE_GDK_PIXBUF
186 "\nSway was compiled without gdk_pixbuf support, so only"
187 "\nPNG images can be loaded. This is the likely cause."
188#endif //HAVE_GDK_PIXBUF
189 , cairo_status_to_string(
190 cairo_surface_status(state->context.image)));
191 return false; 90 return false;
192 } 91 }
193 return true; 92 return true;