aboutsummaryrefslogtreecommitdiffstats
path: root/swaybg
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-27 13:35:34 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-28 14:25:19 -0400
commiteccf0b25987b2b194031edf3415e9f09a7ad7119 (patch)
tree1392beed8f4745a36047d8194f3ac9eb20117f44 /swaybg
parentMerge pull request #1641 from swaywm/transformed-events (diff)
downloadsway-eccf0b25987b2b194031edf3415e9f09a7ad7119.tar.gz
sway-eccf0b25987b2b194031edf3415e9f09a7ad7119.tar.zst
sway-eccf0b25987b2b194031edf3415e9f09a7ad7119.zip
Add client protocols and swaybg skeleton
Diffstat (limited to 'swaybg')
-rw-r--r--swaybg/main.c189
-rw-r--r--swaybg/meson.build8
2 files changed, 15 insertions, 182 deletions
diff --git a/swaybg/main.c b/swaybg/main.c
index 2fdd4220..94e98228 100644
--- a/swaybg/main.c
+++ b/swaybg/main.c
@@ -1,20 +1,11 @@
1#include "wayland-desktop-shell-client-protocol.h" 1#include <ctype.h>
2#include <stdbool.h> 2#include <stdbool.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <ctype.h>
6#include <wayland-client.h>
7#include <time.h>
8#include <string.h> 5#include <string.h>
9#include "client/window.h" 6#include <time.h>
10#include "client/registry.h" 7#include <wayland-client.h>
11#include "client/cairo.h" 8#include <wlr/util/log.h>
12#include "log.h"
13#include "list.h"
14#include "util.h"
15
16list_t *surfaces;
17struct registry *registry;
18 9
19enum scaling_mode { 10enum scaling_mode {
20 SCALING_MODE_STRETCH, 11 SCALING_MODE_STRETCH,
@@ -24,21 +15,11 @@ enum scaling_mode {
24 SCALING_MODE_TILE, 15 SCALING_MODE_TILE,
25}; 16};
26 17
27void sway_terminate(int exit_code) {
28 int i;
29 for (i = 0; i < surfaces->length; ++i) {
30 struct window *window = surfaces->items[i];
31 window_teardown(window);
32 }
33 list_free(surfaces);
34 registry_teardown(registry);
35 exit(exit_code);
36}
37
38bool is_valid_color(const char *color) { 18bool is_valid_color(const char *color) {
39 int len = strlen(color); 19 int len = strlen(color);
40 if (len != 7 || color[0] != '#') { 20 if (len != 7 || color[0] != '#') {
41 sway_log(L_ERROR, "%s is not a valid color for swaybg. Color should be specified as #rrggbb (no alpha).", color); 21 wlr_log(L_ERROR, "%s is not a valid color for swaybg. "
22 "Color should be specified as #rrggbb (no alpha).", color);
42 return false; 23 return false;
43 } 24 }
44 25
@@ -53,162 +34,6 @@ bool is_valid_color(const char *color) {
53} 34}
54 35
55int main(int argc, const char **argv) { 36int main(int argc, const char **argv) {
56 init_log(L_INFO); 37 wlr_log_init(L_DEBUG, NULL);
57 surfaces = create_list();
58 registry = registry_poll();
59
60 if (argc != 4) {
61 sway_abort("Do not run this program manually. See man 5 sway and look for output options.");
62 }
63
64 if (!registry->desktop_shell) {
65 sway_abort("swaybg requires the compositor to support the desktop-shell extension.");
66 }
67
68 int desired_output = atoi(argv[1]);
69 sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length);
70 int i;
71 struct output_state *output = registry->outputs->items[desired_output];
72 struct window *window = window_setup(registry,
73 output->width, output->height, output->scale, false);
74 if (!window) {
75 sway_abort("Failed to create surfaces.");
76 }
77 desktop_shell_set_background(registry->desktop_shell, output->output, window->surface);
78 window_make_shell(window);
79 list_add(surfaces, window);
80
81 if (strcmp(argv[3], "solid_color") == 0 && is_valid_color(argv[2])) {
82 cairo_set_source_u32(window->cairo, parse_color(argv[2]));
83 cairo_paint(window->cairo);
84 window_render(window);
85 } else {
86#ifdef WITH_GDK_PIXBUF
87 GError *err = NULL;
88 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(argv[2], &err);
89 if (!pixbuf) {
90 sway_abort("Failed to load background image.");
91 }
92 cairo_surface_t *image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
93 g_object_unref(pixbuf);
94#else
95 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[2]);
96#endif //WITH_GDK_PIXBUF
97 if (!image) {
98 sway_abort("Failed to read background image.");
99 }
100 if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
101 sway_abort("Failed to read background image: %s."
102#ifndef WITH_GDK_PIXBUF
103 "\nSway was compiled without gdk_pixbuf support, so only"
104 "\nPNG images can be loaded. This is the likely cause."
105#endif //WITH_GDK_PIXBUF
106 , cairo_status_to_string(cairo_surface_status(image)));
107 }
108 double width = cairo_image_surface_get_width(image);
109 double height = cairo_image_surface_get_height(image);
110
111 const char *scaling_mode_str = argv[3];
112 enum scaling_mode scaling_mode = SCALING_MODE_STRETCH;
113 if (strcmp(scaling_mode_str, "stretch") == 0) {
114 scaling_mode = SCALING_MODE_STRETCH;
115 } else if (strcmp(scaling_mode_str, "fill") == 0) {
116 scaling_mode = SCALING_MODE_FILL;
117 } else if (strcmp(scaling_mode_str, "fit") == 0) {
118 scaling_mode = SCALING_MODE_FIT;
119 } else if (strcmp(scaling_mode_str, "center") == 0) {
120 scaling_mode = SCALING_MODE_CENTER;
121 } else if (strcmp(scaling_mode_str, "tile") == 0) {
122 scaling_mode = SCALING_MODE_TILE;
123 } else {
124 sway_abort("Unsupported scaling mode: %s", scaling_mode_str);
125 }
126
127 int wwidth = window->width * window->scale;
128 int wheight = window->height * window->scale;
129
130 for (i = 0; i < surfaces->length; ++i) {
131 struct window *window = surfaces->items[i];
132 if (window_prerender(window) && window->cairo) {
133 switch (scaling_mode) {
134 case SCALING_MODE_STRETCH:
135 cairo_scale(window->cairo,
136 (double) wwidth / width,
137 (double) wheight / height);
138 cairo_set_source_surface(window->cairo, image, 0, 0);
139 break;
140 case SCALING_MODE_FILL:
141 {
142 double window_ratio = (double) wwidth / wheight;
143 double bg_ratio = width / height;
144
145 if (window_ratio > bg_ratio) {
146 double scale = (double) wwidth / width;
147 cairo_scale(window->cairo, scale, scale);
148 cairo_set_source_surface(window->cairo, image,
149 0,
150 (double) wheight/2 / scale - height/2);
151 } else {
152 double scale = (double) wheight / height;
153 cairo_scale(window->cairo, scale, scale);
154 cairo_set_source_surface(window->cairo, image,
155 (double) wwidth/2 / scale - width/2,
156 0);
157 }
158 break;
159 }
160 case SCALING_MODE_FIT:
161 {
162 double window_ratio = (double) wwidth / wheight;
163 double bg_ratio = width / height;
164
165 if (window_ratio > bg_ratio) {
166 double scale = (double) wheight / height;
167 cairo_scale(window->cairo, scale, scale);
168 cairo_set_source_surface(window->cairo, image,
169 (double) wwidth/2 / scale - width/2,
170 0);
171 } else {
172 double scale = (double) wwidth / width;
173 cairo_scale(window->cairo, scale, scale);
174 cairo_set_source_surface(window->cairo, image,
175 0,
176 (double) wheight/2 / scale - height/2);
177 }
178 break;
179 }
180 case SCALING_MODE_CENTER:
181 cairo_set_source_surface(window->cairo, image,
182 (double) wwidth/2 - width/2,
183 (double) wheight/2 - height/2);
184 break;
185 case SCALING_MODE_TILE:
186 {
187 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
188 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
189 cairo_set_source(window->cairo, pattern);
190 break;
191 }
192 default:
193 sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str);
194 }
195
196 cairo_paint(window->cairo);
197
198 window_render(window);
199 }
200 }
201
202 cairo_surface_destroy(image);
203 }
204
205 while (wl_display_dispatch(registry->display) != -1);
206
207 for (i = 0; i < surfaces->length; ++i) {
208 struct window *window = surfaces->items[i];
209 window_teardown(window);
210 }
211 list_free(surfaces);
212 registry_teardown(registry);
213 return 0; 38 return 0;
214} 39}
diff --git a/swaybg/meson.build b/swaybg/meson.build
new file mode 100644
index 00000000..47315023
--- /dev/null
+++ b/swaybg/meson.build
@@ -0,0 +1,8 @@
1executable(
2 'swaybg',
3 'main.c',
4 include_directories: [sway_inc],
5 dependencies: [wayland_client, sway_protos, jsonc, wlroots],
6 link_with: [lib_sway_common],
7 install: true
8)