aboutsummaryrefslogtreecommitdiffstats
path: root/swaybg
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-03-27 15:25:25 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-03-28 14:25:19 -0400
commit632bb948b7ffbb08a6e965dabf88347afd0a1fa8 (patch)
treecbd9d4e4e3a7c605d2b0a5e3e66ce35554a74c4b /swaybg
parentAdd client protocols and swaybg skeleton (diff)
downloadsway-632bb948b7ffbb08a6e965dabf88347afd0a1fa8.tar.gz
sway-632bb948b7ffbb08a6e965dabf88347afd0a1fa8.tar.zst
sway-632bb948b7ffbb08a6e965dabf88347afd0a1fa8.zip
Add solid-color rendering to swaybg
Diffstat (limited to 'swaybg')
-rw-r--r--swaybg/main.c187
-rw-r--r--swaybg/meson.build18
2 files changed, 203 insertions, 2 deletions
diff --git a/swaybg/main.c b/swaybg/main.c
index 94e98228..4473869b 100644
--- a/swaybg/main.c
+++ b/swaybg/main.c
@@ -6,6 +6,10 @@
6#include <time.h> 6#include <time.h>
7#include <wayland-client.h> 7#include <wayland-client.h>
8#include <wlr/util/log.h> 8#include <wlr/util/log.h>
9#include "buffer_pool.h"
10#include "cairo.h"
11#include "util.h"
12#include "wlr-layer-shell-unstable-v1-client-protocol.h"
9 13
10enum scaling_mode { 14enum scaling_mode {
11 SCALING_MODE_STRETCH, 15 SCALING_MODE_STRETCH,
@@ -13,6 +17,31 @@ enum scaling_mode {
13 SCALING_MODE_FIT, 17 SCALING_MODE_FIT,
14 SCALING_MODE_CENTER, 18 SCALING_MODE_CENTER,
15 SCALING_MODE_TILE, 19 SCALING_MODE_TILE,
20 SCALING_MODE_SOLID_COLOR,
21};
22
23struct swaybg_args {
24 int output_idx;
25 const char *path;
26 enum scaling_mode mode;
27};
28
29struct swaybg_state {
30 const struct swaybg_args *args;
31
32 struct wl_display *display;
33 struct wl_compositor *compositor;
34 struct zwlr_layer_shell_v1 *layer_shell;
35 struct wl_shm *shm;
36
37 struct wl_output *output;
38 struct wl_surface *surface;
39 struct zwlr_layer_surface_v1 *layer_surface;
40
41 bool run_display;
42 uint32_t width, height;
43 struct pool_buffer buffers[2];
44 struct pool_buffer *current_buffer;
16}; 45};
17 46
18bool is_valid_color(const char *color) { 47bool is_valid_color(const char *color) {
@@ -33,7 +62,165 @@ bool is_valid_color(const char *color) {
33 return true; 62 return true;
34} 63}
35 64
65static void render_frame(struct swaybg_state *state) {
66 if (!state->run_display) {
67 return;
68 }
69
70 state->current_buffer = get_next_buffer(state->shm,
71 state->buffers, state->width, state->height);
72 cairo_t *cairo = state->current_buffer->cairo;
73
74 switch (state->args->mode) {
75 case SCALING_MODE_SOLID_COLOR:
76 cairo_set_source_u32(cairo, parse_color(state->args->path));
77 cairo_paint(cairo);
78 break;
79 default:
80 exit(1);
81 break;
82 }
83
84 wl_surface_attach(state->surface, state->current_buffer->buffer, 0, 0);
85 wl_surface_damage(state->surface, 0, 0, state->width, state->height);
86 wl_surface_commit(state->surface);
87}
88
89static void layer_surface_configure(void *data,
90 struct zwlr_layer_surface_v1 *surface,
91 uint32_t serial, uint32_t width, uint32_t height) {
92 struct swaybg_state *state = data;
93 state->width = width;
94 state->height = height;
95 render_frame(state);
96 zwlr_layer_surface_v1_ack_configure(surface, serial);
97}
98
99static void layer_surface_closed(void *data,
100 struct zwlr_layer_surface_v1 *surface) {
101 struct swaybg_state *state = data;
102 zwlr_layer_surface_v1_destroy(state->layer_surface);
103 wl_surface_destroy(state->surface);
104 state->run_display = false;
105}
106
107struct zwlr_layer_surface_v1_listener layer_surface_listener = {
108 .configure = layer_surface_configure,
109 .closed = layer_surface_closed,
110};
111
112static void handle_global(void *data, struct wl_registry *registry,
113 uint32_t name, const char *interface, uint32_t version) {
114 struct swaybg_state *state = data;
115 if (strcmp(interface, wl_compositor_interface.name) == 0) {
116 state->compositor = wl_registry_bind(registry, name,
117 &wl_compositor_interface, 1);
118 } else if (strcmp(interface, wl_shm_interface.name) == 0) {
119 state->shm = wl_registry_bind(registry, name,
120 &wl_shm_interface, 1);
121 } else if (strcmp(interface, wl_output_interface.name) == 0) {
122 static int output_idx = 0;
123 if (output_idx == state->args->output_idx) {
124 state->output = wl_registry_bind(registry, name,
125 &wl_output_interface, 1);
126 }
127 output_idx++;
128 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
129 state->layer_shell = wl_registry_bind(
130 registry, name, &zwlr_layer_shell_v1_interface, 1);
131 }
132}
133
134static void handle_global_remove(void *data, struct wl_registry *registry,
135 uint32_t name) {
136 // who cares
137}
138
139static const struct wl_registry_listener registry_listener = {
140 .global = handle_global,
141 .global_remove = handle_global_remove,
142};
143
36int main(int argc, const char **argv) { 144int main(int argc, const char **argv) {
145 struct swaybg_args args = {0};
146 struct swaybg_state state = {0};
147 state.args = &args;
37 wlr_log_init(L_DEBUG, NULL); 148 wlr_log_init(L_DEBUG, NULL);
149
150 if (argc != 4) {
151 wlr_log(L_ERROR, "Do not run this program manually. "
152 "See man 5 sway and look for output options.");
153 return 1;
154 }
155 args.output_idx = atoi(argv[1]);
156 args.path = argv[2];
157 args.mode = atoi(argv[3]);
158
159 args.mode = SCALING_MODE_STRETCH;
160 if (strcmp(argv[3], "stretch") == 0) {
161 args.mode = SCALING_MODE_STRETCH;
162 } else if (strcmp(argv[3], "fill") == 0) {
163 args.mode = SCALING_MODE_FILL;
164 } else if (strcmp(argv[3], "fit") == 0) {
165 args.mode = SCALING_MODE_FIT;
166 } else if (strcmp(argv[3], "center") == 0) {
167 args.mode = SCALING_MODE_CENTER;
168 } else if (strcmp(argv[3], "tile") == 0) {
169 args.mode = SCALING_MODE_TILE;
170 } else if (strcmp(argv[3], "solid_color") == 0) {
171 args.mode = SCALING_MODE_SOLID_COLOR;
172 } else {
173 wlr_log(L_ERROR, "Unsupported scaling mode: %s", argv[3]);
174 return 1;
175 }
176
177 state.display = wl_display_connect(NULL);
178 if (!state.display) {
179 wlr_log(L_ERROR, "Failed to create display\n");
180 return 1;
181 }
182
183 struct wl_registry *registry = wl_display_get_registry(state.display);
184 wl_registry_add_listener(registry, &registry_listener, &state);
185 wl_display_roundtrip(state.display);
186
187 if (!state.compositor) {
188 wlr_log(L_DEBUG, "wl-compositor not available");
189 return 1;
190 }
191 if (!state.layer_shell) {
192 wlr_log(L_ERROR, "layer-shell not available");
193 return 1;
194 }
195
196 state.surface = wl_compositor_create_surface(state.compositor);
197 if (!state.surface) {
198 wlr_log(L_ERROR, "failed to create wl_surface");
199 return 1;
200 }
201
202 state.layer_surface = zwlr_layer_shell_v1_get_layer_surface(
203 state.layer_shell, state.surface, state.output,
204 ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "wallpaper");
205 if (!state.layer_surface) {
206 wlr_log(L_ERROR, "failed to create zwlr_layer_surface");
207 return 1;
208 }
209 zwlr_layer_surface_v1_set_size(state.layer_surface, 0, 0);
210 zwlr_layer_surface_v1_set_anchor(state.layer_surface,
211 ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
212 ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
213 ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
214 ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
215 zwlr_layer_surface_v1_add_listener(state.layer_surface,
216 &layer_surface_listener, &state);
217 wl_surface_commit(state.surface);
218 wl_display_roundtrip(state.display);
219
220 state.run_display = true;
221 render_frame(&state);
222 while (wl_display_dispatch(state.display) != -1 && state.run_display) {
223 // This space intentionally left blank
224 }
38 return 0; 225 return 0;
39} 226}
diff --git a/swaybg/meson.build b/swaybg/meson.build
index 47315023..7f5d6bd1 100644
--- a/swaybg/meson.build
+++ b/swaybg/meson.build
@@ -1,8 +1,22 @@
1deps = [
2 cairo,
3 jsonc,
4 math,
5 pango,
6 pangocairo,
7 sway_protos,
8 wayland_client,
9]
10
11if gdk_pixbuf.found()
12 deps += [gdk_pixbuf]
13endif
14
1executable( 15executable(
2 'swaybg', 16 'swaybg',
3 'main.c', 17 'main.c',
4 include_directories: [sway_inc], 18 include_directories: [sway_inc],
5 dependencies: [wayland_client, sway_protos, jsonc, wlroots], 19 dependencies: deps,
6 link_with: [lib_sway_common], 20 link_with: [lib_sway_common, lib_sway_client],
7 install: true 21 install: true
8) 22)