summaryrefslogtreecommitdiffstats
path: root/swaylock
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-05-23 22:54:52 +0100
committerLibravatar emersion <contact@emersion.fr>2018-05-23 22:54:52 +0100
commitcd0fca2ebf81c252b3743c4474a5fdbcd3e2afad (patch)
tree595f1e80551b64de0d4e24f5721bae27acc195d9 /swaylock
parentFix output hotplugging (diff)
parentMerge pull request #2022 from RedSoxFan/ipc-get-marks (diff)
downloadsway-cd0fca2ebf81c252b3743c4474a5fdbcd3e2afad.tar.gz
sway-cd0fca2ebf81c252b3743c4474a5fdbcd3e2afad.tar.zst
sway-cd0fca2ebf81c252b3743c4474a5fdbcd3e2afad.zip
Merge branch 'master' into fix-swaylock-hotplugging
Diffstat (limited to 'swaylock')
-rw-r--r--swaylock/main.c158
-rw-r--r--swaylock/render.c2
2 files changed, 140 insertions, 20 deletions
diff --git a/swaylock/main.c b/swaylock/main.c
index 9da99f97..79c06285 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -13,6 +13,7 @@
13#include <time.h> 13#include <time.h>
14#include <unistd.h> 14#include <unistd.h>
15#include <wayland-client.h> 15#include <wayland-client.h>
16#include <wordexp.h>
16#include <wlr/util/log.h> 17#include <wlr/util/log.h>
17#include "swaylock/seat.h" 18#include "swaylock/seat.h"
18#include "swaylock/swaylock.h" 19#include "swaylock/swaylock.h"
@@ -20,9 +21,11 @@
20#include "pool-buffer.h" 21#include "pool-buffer.h"
21#include "cairo.h" 22#include "cairo.h"
22#include "log.h" 23#include "log.h"
24#include "stringop.h"
23#include "util.h" 25#include "util.h"
24#include "wlr-input-inhibitor-unstable-v1-client-protocol.h" 26#include "wlr-input-inhibitor-unstable-v1-client-protocol.h"
25#include "wlr-layer-shell-unstable-v1-client-protocol.h" 27#include "wlr-layer-shell-unstable-v1-client-protocol.h"
28#include "xdg-output-unstable-v1-client-protocol.h"
26 29
27void sway_terminate(int exit_code) { 30void sway_terminate(int exit_code) {
28 exit(exit_code); 31 exit(exit_code);
@@ -77,9 +80,14 @@ static void destroy_surface(struct swaylock_surface *surface) {
77 80
78static const struct zwlr_layer_surface_v1_listener layer_surface_listener; 81static const struct zwlr_layer_surface_v1_listener layer_surface_listener;
79 82
83static cairo_surface_t *select_image(struct swaylock_state *state,
84 struct swaylock_surface *surface);
85
80static void create_layer_surface(struct swaylock_surface *surface) { 86static void create_layer_surface(struct swaylock_surface *surface) {
81 struct swaylock_state *state = surface->state; 87 struct swaylock_state *state = surface->state;
82 88
89 surface->image = select_image(state, surface);
90
83 surface->surface = wl_compositor_create_surface(state->compositor); 91 surface->surface = wl_compositor_create_surface(state->compositor);
84 assert(surface->surface); 92 assert(surface->surface);
85 93
@@ -123,22 +131,23 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
123 .closed = layer_surface_closed, 131 .closed = layer_surface_closed,
124}; 132};
125 133
126static void output_geometry(void *data, struct wl_output *output, int32_t x, 134static void handle_wl_output_geometry(void *data, struct wl_output *output, int32_t x,
127 int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, 135 int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel,
128 const char *make, const char *model, int32_t transform) { 136 const char *make, const char *model, int32_t transform) {
129 // Who cares 137 // Who cares
130} 138}
131 139
132static void output_mode(void *data, struct wl_output *output, uint32_t flags, 140static void handle_wl_output_mode(void *data, struct wl_output *output, uint32_t flags,
133 int32_t width, int32_t height, int32_t refresh) { 141 int32_t width, int32_t height, int32_t refresh) {
134 // Who cares 142 // Who cares
135} 143}
136 144
137static void output_done(void *data, struct wl_output *output) { 145static void handle_wl_output_done(void *data, struct wl_output *output) {
138 // Who cares 146 // Who cares
139} 147}
140 148
141static void output_scale(void *data, struct wl_output *output, int32_t factor) { 149static void handle_wl_output_scale(void *data, struct wl_output *output,
150 int32_t factor) {
142 struct swaylock_surface *surface = data; 151 struct swaylock_surface *surface = data;
143 surface->scale = factor; 152 surface->scale = factor;
144 if (surface->state->run_display) { 153 if (surface->state->run_display) {
@@ -146,11 +155,46 @@ static void output_scale(void *data, struct wl_output *output, int32_t factor) {
146 } 155 }
147} 156}
148 157
149struct wl_output_listener output_listener = { 158struct wl_output_listener _wl_output_listener = {
150 .geometry = output_geometry, 159 .geometry = handle_wl_output_geometry,
151 .mode = output_mode, 160 .mode = handle_wl_output_mode,
152 .done = output_done, 161 .done = handle_wl_output_done,
153 .scale = output_scale, 162 .scale = handle_wl_output_scale,
163};
164
165static void handle_xdg_output_logical_size(void *data, struct zxdg_output_v1 *output,
166 int width, int height) {
167 // Who cares
168}
169
170static void handle_xdg_output_logical_position(void *data,
171 struct zxdg_output_v1 *output, int x, int y) {
172 // Who cares
173}
174
175static void handle_xdg_output_name(void *data, struct zxdg_output_v1 *output,
176 const char *name) {
177 wlr_log(L_DEBUG, "output name is %s", name);
178 struct swaylock_surface *surface = data;
179 surface->xdg_output = output;
180 surface->output_name = strdup(name);
181}
182
183static void handle_xdg_output_description(void *data, struct zxdg_output_v1 *output,
184 const char *description) {
185 // Who cares
186}
187
188static void handle_xdg_output_done(void *data, struct zxdg_output_v1 *output) {
189 // Who cares
190}
191
192struct zxdg_output_v1_listener _xdg_output_listener = {
193 .logical_position = handle_xdg_output_logical_position,
194 .logical_size = handle_xdg_output_logical_size,
195 .done = handle_xdg_output_done,
196 .name = handle_xdg_output_name,
197 .description = handle_xdg_output_description,
154}; 198};
155 199
156static void handle_global(void *data, struct wl_registry *registry, 200static void handle_global(void *data, struct wl_registry *registry,
@@ -172,6 +216,9 @@ static void handle_global(void *data, struct wl_registry *registry,
172 } else if (strcmp(interface, zwlr_input_inhibit_manager_v1_interface.name) == 0) { 216 } else if (strcmp(interface, zwlr_input_inhibit_manager_v1_interface.name) == 0) {
173 state->input_inhibit_manager = wl_registry_bind( 217 state->input_inhibit_manager = wl_registry_bind(
174 registry, name, &zwlr_input_inhibit_manager_v1_interface, 1); 218 registry, name, &zwlr_input_inhibit_manager_v1_interface, 1);
219 } else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) {
220 state->zxdg_output_manager = wl_registry_bind(
221 registry, name, &zxdg_output_manager_v1_interface, 2);
175 } else if (strcmp(interface, wl_output_interface.name) == 0) { 222 } else if (strcmp(interface, wl_output_interface.name) == 0) {
176 struct swaylock_surface *surface = 223 struct swaylock_surface *surface =
177 calloc(1, sizeof(struct swaylock_surface)); 224 calloc(1, sizeof(struct swaylock_surface));
@@ -180,7 +227,7 @@ static void handle_global(void *data, struct wl_registry *registry,
180 &wl_output_interface, 3); 227 &wl_output_interface, 3);
181 surface->output_global_name = name; 228 surface->output_global_name = name;
182 surface->image = state->background_image; 229 surface->image = state->background_image;
183 wl_output_add_listener(surface->output, &output_listener, surface); 230 wl_output_add_listener(surface->output, &_wl_output_listener, surface);
184 wl_list_insert(&state->surfaces, &surface->link); 231 wl_list_insert(&state->surfaces, &surface->link);
185 232
186 if (state->run_display) { 233 if (state->run_display) {
@@ -207,6 +254,70 @@ static const struct wl_registry_listener registry_listener = {
207 .global_remove = handle_global_remove, 254 .global_remove = handle_global_remove,
208}; 255};
209 256
257static cairo_surface_t *select_image(struct swaylock_state *state,
258 struct swaylock_surface *surface) {
259 struct swaylock_image *image;
260 cairo_surface_t *default_image = NULL;
261 wl_list_for_each(image, &state->images, link) {
262 if (lenient_strcmp(image->output_name, surface->output_name) == 0) {
263 return image->cairo_surface;
264 } else if (!image->output_name) {
265 default_image = image->cairo_surface;
266 }
267 }
268 return default_image;
269}
270
271static void load_image(char *arg, struct swaylock_state *state) {
272 // [<output>:]<path>
273 struct swaylock_image *image = calloc(1, sizeof(struct swaylock_image));
274 char *separator = strchr(arg, ':');
275 if (separator) {
276 *separator = '\0';
277 image->output_name = strdup(arg);
278 image->path = strdup(separator + 1);
279 } else {
280 image->output_name = NULL;
281 image->path = strdup(arg);
282 }
283
284 bool exists = false;
285 struct swaylock_image *iter_image;
286 wl_list_for_each(iter_image, &state->images, link) {
287 if (lenient_strcmp(iter_image->output_name, image->output_name) == 0) {
288 exists = true;
289 break;
290 }
291 }
292 if (exists) {
293 if (image->output_name) {
294 wlr_log(L_ERROR, "Multiple images defined for output %s",
295 image->output_name);
296 } else {
297 wlr_log(L_ERROR, "Multiple default images defined");
298 }
299 }
300
301 // Bash doesn't replace the ~ with $HOME if the output name is supplied
302 wordexp_t p;
303 if (wordexp(image->path, &p, 0) == 0) {
304 free(image->path);
305 image->path = strdup(p.we_wordv[0]);
306 wordfree(&p);
307 }
308
309 // Load the actual image
310 image->cairo_surface = load_background_image(image->path);
311 if (!image->cairo_surface) {
312 free(image);
313 return;
314 }
315 wl_list_insert(&state->images, &image->link);
316 state->args.mode = BACKGROUND_MODE_FILL;
317 wlr_log(L_DEBUG, "Loaded image %s for output %s",
318 image->path, image->output_name ? image->output_name : "*");
319}
320
210static struct swaylock_state state; 321static struct swaylock_state state;
211 322
212int main(int argc, char **argv) { 323int main(int argc, char **argv) {
@@ -233,14 +344,14 @@ int main(int argc, char **argv) {
233 " -v, --version Show the version number and quit.\n" 344 " -v, --version Show the version number and quit.\n"
234 " -i, --image [<output>:]<path> Display the given image.\n" 345 " -i, --image [<output>:]<path> Display the given image.\n"
235 " -u, --no-unlock-indicator Disable the unlock indicator.\n" 346 " -u, --no-unlock-indicator Disable the unlock indicator.\n"
236 " -f, --daemonize Detach from the controlling terminal.\n" 347 " -f, --daemonize Detach from the controlling terminal.\n";
237 " --socket <socket> Use the specified socket.\n";
238 348
239 state.args = (struct swaylock_args){ 349 state.args = (struct swaylock_args){
240 .mode = BACKGROUND_MODE_SOLID_COLOR, 350 .mode = BACKGROUND_MODE_SOLID_COLOR,
241 .color = 0xFFFFFFFF, 351 .color = 0xFFFFFFFF,
242 .show_indicator = true, 352 .show_indicator = true,
243 }; 353 };
354 wl_list_init(&state.images);
244 355
245 wlr_log_init(L_DEBUG, NULL); 356 wlr_log_init(L_DEBUG, NULL);
246 357
@@ -258,12 +369,7 @@ int main(int argc, char **argv) {
258 break; 369 break;
259 } 370 }
260 case 'i': 371 case 'i':
261 // TODO: Multiple background images (bleh) 372 load_image(optarg, &state);
262 state.background_image = load_background_image(optarg);
263 if (!state.background_image) {
264 return 1;
265 }
266 state.args.mode = BACKGROUND_MODE_FILL;
267 break; 373 break;
268 case 's': 374 case 's':
269 state.args.mode = parse_background_mode(optarg); 375 state.args.mode = parse_background_mode(optarg);
@@ -313,6 +419,7 @@ int main(int argc, char **argv) {
313 if (!state.input_inhibit_manager) { 419 if (!state.input_inhibit_manager) {
314 wlr_log(L_ERROR, "Compositor does not support the input inhibitor " 420 wlr_log(L_ERROR, "Compositor does not support the input inhibitor "
315 "protocol, refusing to run insecurely"); 421 "protocol, refusing to run insecurely");
422 return 1;
316 } 423 }
317 424
318 if (wl_list_empty(&state.surfaces)) { 425 if (wl_list_empty(&state.surfaces)) {
@@ -322,11 +429,24 @@ int main(int argc, char **argv) {
322 429
323 zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager); 430 zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager);
324 431
432 if (state.zxdg_output_manager) {
433 struct swaylock_surface *surface;
434 wl_list_for_each(surface, &state.surfaces, link) {
435 surface->xdg_output = zxdg_output_manager_v1_get_xdg_output(
436 state.zxdg_output_manager, surface->output);
437 zxdg_output_v1_add_listener(
438 surface->xdg_output, &_xdg_output_listener, surface);
439 }
440 wl_display_roundtrip(state.display);
441 } else {
442 wlr_log(L_INFO, "Compositor does not support zxdg output manager, "
443 "images assigned to named outputs will not work");
444 }
445
325 struct swaylock_surface *surface; 446 struct swaylock_surface *surface;
326 wl_list_for_each(surface, &state.surfaces, link) { 447 wl_list_for_each(surface, &state.surfaces, link) {
327 create_layer_surface(surface); 448 create_layer_surface(surface);
328 } 449 }
329 wl_display_roundtrip(state.display);
330 450
331 state.run_display = true; 451 state.run_display = true;
332 while (wl_display_dispatch(state.display) != -1 && state.run_display) { 452 while (wl_display_dispatch(state.display) != -1 && state.run_display) {
diff --git a/swaylock/render.c b/swaylock/render.c
index 7d9d25a5..cc40f4e9 100644
--- a/swaylock/render.c
+++ b/swaylock/render.c
@@ -23,7 +23,7 @@ void render_frame(struct swaylock_surface *surface) {
23 cairo_t *cairo = surface->current_buffer->cairo; 23 cairo_t *cairo = surface->current_buffer->cairo;
24 cairo_identity_matrix(cairo); 24 cairo_identity_matrix(cairo);
25 25
26 if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR) { 26 if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR || !surface->image) {
27 cairo_set_source_u32(cairo, state->args.color); 27 cairo_set_source_u32(cairo, state->args.color);
28 cairo_paint(cairo); 28 cairo_paint(cairo);
29 } else { 29 } else {