diff options
Diffstat (limited to 'swaylock/main.c')
-rw-r--r-- | swaylock/main.c | 177 |
1 files changed, 92 insertions, 85 deletions
diff --git a/swaylock/main.c b/swaylock/main.c index 9530b6dc..d58fc868 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -115,6 +115,76 @@ void notify_key(enum wl_keyboard_key_state state, xkb_keysym_t sym, uint32_t cod | |||
115 | } | 115 | } |
116 | } | 116 | } |
117 | 117 | ||
118 | void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) { | ||
119 | double width = cairo_image_surface_get_width(image); | ||
120 | double height = cairo_image_surface_get_height(image); | ||
121 | |||
122 | switch (scaling_mode) { | ||
123 | case SCALING_MODE_STRETCH: | ||
124 | cairo_scale(window->cairo, | ||
125 | (double) window->width / width, | ||
126 | (double) window->height / height); | ||
127 | cairo_set_source_surface(window->cairo, image, 0, 0); | ||
128 | break; | ||
129 | case SCALING_MODE_FILL: | ||
130 | { | ||
131 | double window_ratio = (double) window->width / window->height; | ||
132 | double bg_ratio = width / height; | ||
133 | |||
134 | if (window_ratio > bg_ratio) { | ||
135 | double scale = (double) window->width / width; | ||
136 | cairo_scale(window->cairo, scale, scale); | ||
137 | cairo_set_source_surface(window->cairo, image, | ||
138 | 0, | ||
139 | (double) window->height/2 / scale - height/2); | ||
140 | } else { | ||
141 | double scale = (double) window->height / height; | ||
142 | cairo_scale(window->cairo, scale, scale); | ||
143 | cairo_set_source_surface(window->cairo, image, | ||
144 | (double) window->width/2 / scale - width/2, | ||
145 | 0); | ||
146 | } | ||
147 | break; | ||
148 | } | ||
149 | case SCALING_MODE_FIT: | ||
150 | { | ||
151 | double window_ratio = (double) window->width / window->height; | ||
152 | double bg_ratio = width / height; | ||
153 | |||
154 | if (window_ratio > bg_ratio) { | ||
155 | double scale = (double) window->height / height; | ||
156 | cairo_scale(window->cairo, scale, scale); | ||
157 | cairo_set_source_surface(window->cairo, image, | ||
158 | (double) window->width/2 / scale - width/2, | ||
159 | 0); | ||
160 | } else { | ||
161 | double scale = (double) window->width / width; | ||
162 | cairo_scale(window->cairo, scale, scale); | ||
163 | cairo_set_source_surface(window->cairo, image, | ||
164 | 0, | ||
165 | (double) window->height/2 / scale - height/2); | ||
166 | } | ||
167 | break; | ||
168 | } | ||
169 | case SCALING_MODE_CENTER: | ||
170 | cairo_set_source_surface(window->cairo, image, | ||
171 | (double) window->width/2 - width/2, | ||
172 | (double) window->height/2 - height/2); | ||
173 | break; | ||
174 | case SCALING_MODE_TILE: | ||
175 | { | ||
176 | cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image); | ||
177 | cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); | ||
178 | cairo_set_source(window->cairo, pattern); | ||
179 | break; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | cairo_paint(window->cairo); | ||
184 | |||
185 | window_render(window); | ||
186 | } | ||
187 | |||
118 | int main(int argc, char **argv) { | 188 | int main(int argc, char **argv) { |
119 | char *image_path = NULL; | 189 | char *image_path = NULL; |
120 | char *scaling_mode_str = "fit"; | 190 | char *scaling_mode_str = "fit"; |
@@ -176,6 +246,21 @@ int main(int argc, char **argv) { | |||
176 | exit(EXIT_FAILURE); | 246 | exit(EXIT_FAILURE); |
177 | } | 247 | } |
178 | 248 | ||
249 | enum scaling_mode scaling_mode = SCALING_MODE_STRETCH; | ||
250 | if (strcmp(scaling_mode_str, "stretch") == 0) { | ||
251 | scaling_mode = SCALING_MODE_STRETCH; | ||
252 | } else if (strcmp(scaling_mode_str, "fill") == 0) { | ||
253 | scaling_mode = SCALING_MODE_FILL; | ||
254 | } else if (strcmp(scaling_mode_str, "fit") == 0) { | ||
255 | scaling_mode = SCALING_MODE_FIT; | ||
256 | } else if (strcmp(scaling_mode_str, "center") == 0) { | ||
257 | scaling_mode = SCALING_MODE_CENTER; | ||
258 | } else if (strcmp(scaling_mode_str, "tile") == 0) { | ||
259 | scaling_mode = SCALING_MODE_TILE; | ||
260 | } else { | ||
261 | sway_abort("Unsupported scaling mode: %s", scaling_mode_str); | ||
262 | } | ||
263 | |||
179 | password = malloc(1024); // TODO: Let this grow | 264 | password = malloc(1024); // TODO: Let this grow |
180 | password[0] = '\0'; | 265 | password[0] = '\0'; |
181 | surfaces = create_list(); | 266 | surfaces = create_list(); |
@@ -197,13 +282,14 @@ int main(int argc, char **argv) { | |||
197 | 282 | ||
198 | registry->input->notify = notify_key; | 283 | registry->input->notify = notify_key; |
199 | 284 | ||
285 | cairo_surface_t *image = NULL; | ||
200 | #ifdef WITH_GDK_PIXBUF | 286 | #ifdef WITH_GDK_PIXBUF |
201 | GError *err = NULL; | 287 | GError *err = NULL; |
202 | GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(image_path, &err); | 288 | GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(image_path, &err); |
203 | if (!pixbuf) { | 289 | if (!pixbuf) { |
204 | sway_abort("Failed to load background image."); | 290 | sway_abort("Failed to load background image."); |
205 | } | 291 | } |
206 | cairo_surface_t *image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf); | 292 | image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf); |
207 | g_object_unref(pixbuf); | 293 | g_object_unref(pixbuf); |
208 | #else | 294 | #else |
209 | cairo_surface_t *image = cairo_image_surface_create_from_png(argv[1]); | 295 | cairo_surface_t *image = cairo_image_surface_create_from_png(argv[1]); |
@@ -211,93 +297,14 @@ int main(int argc, char **argv) { | |||
211 | if (!image) { | 297 | if (!image) { |
212 | sway_abort("Failed to read background image."); | 298 | sway_abort("Failed to read background image."); |
213 | } | 299 | } |
214 | double width = cairo_image_surface_get_width(image); | ||
215 | double height = cairo_image_surface_get_height(image); | ||
216 | |||
217 | enum scaling_mode scaling_mode = SCALING_MODE_STRETCH; | ||
218 | if (strcmp(scaling_mode_str, "stretch") == 0) { | ||
219 | scaling_mode = SCALING_MODE_STRETCH; | ||
220 | } else if (strcmp(scaling_mode_str, "fill") == 0) { | ||
221 | scaling_mode = SCALING_MODE_FILL; | ||
222 | } else if (strcmp(scaling_mode_str, "fit") == 0) { | ||
223 | scaling_mode = SCALING_MODE_FIT; | ||
224 | } else if (strcmp(scaling_mode_str, "center") == 0) { | ||
225 | scaling_mode = SCALING_MODE_CENTER; | ||
226 | } else if (strcmp(scaling_mode_str, "tile") == 0) { | ||
227 | scaling_mode = SCALING_MODE_TILE; | ||
228 | } else { | ||
229 | sway_abort("Unsupported scaling mode: %s", scaling_mode_str); | ||
230 | } | ||
231 | 300 | ||
232 | for (i = 0; i < surfaces->length; ++i) { | 301 | for (i = 0; i < surfaces->length; ++i) { |
233 | struct window *window = surfaces->items[i]; | 302 | struct window *window = surfaces->items[i]; |
234 | if (window_prerender(window) && window->cairo) { | 303 | if (!window_prerender(window) || !window->cairo) { |
235 | switch (scaling_mode) { | 304 | continue; |
236 | case SCALING_MODE_STRETCH: | 305 | } |
237 | cairo_scale(window->cairo, | 306 | if (image) { |
238 | (double) window->width / width, | 307 | render_image(window, image, scaling_mode); |
239 | (double) window->height / height); | ||
240 | cairo_set_source_surface(window->cairo, image, 0, 0); | ||
241 | break; | ||
242 | case SCALING_MODE_FILL: | ||
243 | { | ||
244 | double window_ratio = (double) window->width / window->height; | ||
245 | double bg_ratio = width / height; | ||
246 | |||
247 | if (window_ratio > bg_ratio) { | ||
248 | double scale = (double) window->width / width; | ||
249 | cairo_scale(window->cairo, scale, scale); | ||
250 | cairo_set_source_surface(window->cairo, image, | ||
251 | 0, | ||
252 | (double) window->height/2 / scale - height/2); | ||
253 | } else { | ||
254 | double scale = (double) window->height / height; | ||
255 | cairo_scale(window->cairo, scale, scale); | ||
256 | cairo_set_source_surface(window->cairo, image, | ||
257 | (double) window->width/2 / scale - width/2, | ||
258 | 0); | ||
259 | } | ||
260 | break; | ||
261 | } | ||
262 | case SCALING_MODE_FIT: | ||
263 | { | ||
264 | double window_ratio = (double) window->width / window->height; | ||
265 | double bg_ratio = width / height; | ||
266 | |||
267 | if (window_ratio > bg_ratio) { | ||
268 | double scale = (double) window->height / height; | ||
269 | cairo_scale(window->cairo, scale, scale); | ||
270 | cairo_set_source_surface(window->cairo, image, | ||
271 | (double) window->width/2 / scale - width/2, | ||
272 | 0); | ||
273 | } else { | ||
274 | double scale = (double) window->width / width; | ||
275 | cairo_scale(window->cairo, scale, scale); | ||
276 | cairo_set_source_surface(window->cairo, image, | ||
277 | 0, | ||
278 | (double) window->height/2 / scale - height/2); | ||
279 | } | ||
280 | break; | ||
281 | } | ||
282 | case SCALING_MODE_CENTER: | ||
283 | cairo_set_source_surface(window->cairo, image, | ||
284 | (double) window->width/2 - width/2, | ||
285 | (double) window->height/2 - height/2); | ||
286 | break; | ||
287 | case SCALING_MODE_TILE: | ||
288 | { | ||
289 | cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image); | ||
290 | cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); | ||
291 | cairo_set_source(window->cairo, pattern); | ||
292 | break; | ||
293 | } | ||
294 | default: | ||
295 | sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str); | ||
296 | } | ||
297 | |||
298 | cairo_paint(window->cairo); | ||
299 | |||
300 | window_render(window); | ||
301 | } | 308 | } |
302 | } | 309 | } |
303 | 310 | ||