diff options
-rw-r--r-- | include/swaylock/swaylock.h | 16 | ||||
-rw-r--r-- | swaylock/main.c | 100 |
2 files changed, 77 insertions, 39 deletions
diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h index e161ada9..27db67cd 100644 --- a/include/swaylock/swaylock.h +++ b/include/swaylock/swaylock.h | |||
@@ -10,13 +10,13 @@ | |||
10 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | 10 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
11 | 11 | ||
12 | enum auth_state { | 12 | enum auth_state { |
13 | AUTH_STATE_IDLE, | 13 | AUTH_STATE_IDLE, |
14 | AUTH_STATE_CLEAR, | 14 | AUTH_STATE_CLEAR, |
15 | AUTH_STATE_INPUT, | 15 | AUTH_STATE_INPUT, |
16 | AUTH_STATE_INPUT_NOP, | 16 | AUTH_STATE_INPUT_NOP, |
17 | AUTH_STATE_BACKSPACE, | 17 | AUTH_STATE_BACKSPACE, |
18 | AUTH_STATE_VALIDATING, | 18 | AUTH_STATE_VALIDATING, |
19 | AUTH_STATE_INVALID, | 19 | AUTH_STATE_INVALID, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | struct swaylock_args { | 22 | struct swaylock_args { |
@@ -39,6 +39,7 @@ struct swaylock_state { | |||
39 | struct wl_list surfaces; | 39 | struct wl_list surfaces; |
40 | struct wl_list images; | 40 | struct wl_list images; |
41 | struct swaylock_args args; | 41 | struct swaylock_args args; |
42 | cairo_surface_t *background_image; | ||
42 | struct swaylock_password password; | 43 | struct swaylock_password password; |
43 | struct swaylock_xkb xkb; | 44 | struct swaylock_xkb xkb; |
44 | enum auth_state auth_state; | 45 | enum auth_state auth_state; |
@@ -50,6 +51,7 @@ struct swaylock_surface { | |||
50 | cairo_surface_t *image; | 51 | cairo_surface_t *image; |
51 | struct swaylock_state *state; | 52 | struct swaylock_state *state; |
52 | struct wl_output *output; | 53 | struct wl_output *output; |
54 | uint32_t output_global_name; | ||
53 | struct zxdg_output_v1 *xdg_output; | 55 | struct zxdg_output_v1 *xdg_output; |
54 | struct wl_surface *surface; | 56 | struct wl_surface *surface; |
55 | struct zwlr_layer_surface_v1 *layer_surface; | 57 | struct zwlr_layer_surface_v1 *layer_surface; |
diff --git a/swaylock/main.c b/swaylock/main.c index 11b5e8c8..79c06285 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -64,6 +64,52 @@ static void daemonize() { | |||
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | static void destroy_surface(struct swaylock_surface *surface) { | ||
68 | wl_list_remove(&surface->link); | ||
69 | if (surface->layer_surface != NULL) { | ||
70 | zwlr_layer_surface_v1_destroy(surface->layer_surface); | ||
71 | } | ||
72 | if (surface->surface != NULL) { | ||
73 | wl_surface_destroy(surface->surface); | ||
74 | } | ||
75 | destroy_buffer(&surface->buffers[0]); | ||
76 | destroy_buffer(&surface->buffers[1]); | ||
77 | wl_output_destroy(surface->output); | ||
78 | free(surface); | ||
79 | } | ||
80 | |||
81 | static const struct zwlr_layer_surface_v1_listener layer_surface_listener; | ||
82 | |||
83 | static cairo_surface_t *select_image(struct swaylock_state *state, | ||
84 | struct swaylock_surface *surface); | ||
85 | |||
86 | static void create_layer_surface(struct swaylock_surface *surface) { | ||
87 | struct swaylock_state *state = surface->state; | ||
88 | |||
89 | surface->image = select_image(state, surface); | ||
90 | |||
91 | surface->surface = wl_compositor_create_surface(state->compositor); | ||
92 | assert(surface->surface); | ||
93 | |||
94 | surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||
95 | state->layer_shell, surface->surface, surface->output, | ||
96 | ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); | ||
97 | assert(surface->layer_surface); | ||
98 | |||
99 | zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0); | ||
100 | zwlr_layer_surface_v1_set_anchor(surface->layer_surface, | ||
101 | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | | ||
102 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | | ||
103 | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | | ||
104 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); | ||
105 | zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1); | ||
106 | zwlr_layer_surface_v1_set_keyboard_interactivity( | ||
107 | surface->layer_surface, true); | ||
108 | zwlr_layer_surface_v1_add_listener(surface->layer_surface, | ||
109 | &layer_surface_listener, surface); | ||
110 | wl_surface_commit(surface->surface); | ||
111 | } | ||
112 | |||
67 | static void layer_surface_configure(void *data, | 113 | static void layer_surface_configure(void *data, |
68 | struct zwlr_layer_surface_v1 *layer_surface, | 114 | struct zwlr_layer_surface_v1 *layer_surface, |
69 | uint32_t serial, uint32_t width, uint32_t height) { | 115 | uint32_t serial, uint32_t width, uint32_t height) { |
@@ -77,9 +123,7 @@ static void layer_surface_configure(void *data, | |||
77 | static void layer_surface_closed(void *data, | 123 | static void layer_surface_closed(void *data, |
78 | struct zwlr_layer_surface_v1 *layer_surface) { | 124 | struct zwlr_layer_surface_v1 *layer_surface) { |
79 | struct swaylock_surface *surface = data; | 125 | struct swaylock_surface *surface = data; |
80 | zwlr_layer_surface_v1_destroy(surface->layer_surface); | 126 | destroy_surface(surface); |
81 | wl_surface_destroy(surface->surface); | ||
82 | surface->state->run_display = false; | ||
83 | } | 127 | } |
84 | 128 | ||
85 | static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { | 129 | static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { |
@@ -181,14 +225,28 @@ static void handle_global(void *data, struct wl_registry *registry, | |||
181 | surface->state = state; | 225 | surface->state = state; |
182 | surface->output = wl_registry_bind(registry, name, | 226 | surface->output = wl_registry_bind(registry, name, |
183 | &wl_output_interface, 3); | 227 | &wl_output_interface, 3); |
228 | surface->output_global_name = name; | ||
229 | surface->image = state->background_image; | ||
184 | wl_output_add_listener(surface->output, &_wl_output_listener, surface); | 230 | wl_output_add_listener(surface->output, &_wl_output_listener, surface); |
185 | wl_list_insert(&state->surfaces, &surface->link); | 231 | wl_list_insert(&state->surfaces, &surface->link); |
232 | |||
233 | if (state->run_display) { | ||
234 | create_layer_surface(surface); | ||
235 | wl_display_roundtrip(state->display); | ||
236 | } | ||
186 | } | 237 | } |
187 | } | 238 | } |
188 | 239 | ||
189 | static void handle_global_remove(void *data, struct wl_registry *registry, | 240 | static void handle_global_remove(void *data, struct wl_registry *registry, |
190 | uint32_t name) { | 241 | uint32_t name) { |
191 | // who cares | 242 | struct swaylock_state *state = data; |
243 | struct swaylock_surface *surface; | ||
244 | wl_list_for_each(surface, &state->surfaces, link) { | ||
245 | if (surface->output_global_name == name) { | ||
246 | destroy_surface(surface); | ||
247 | break; | ||
248 | } | ||
249 | } | ||
192 | } | 250 | } |
193 | 251 | ||
194 | static const struct wl_registry_listener registry_listener = { | 252 | static const struct wl_registry_listener registry_listener = { |
@@ -276,7 +334,7 @@ int main(int argc, char **argv) { | |||
276 | {0, 0, 0, 0} | 334 | {0, 0, 0, 0} |
277 | }; | 335 | }; |
278 | 336 | ||
279 | const char *usage = | 337 | const char usage[] = |
280 | "Usage: swaylock [options...]\n" | 338 | "Usage: swaylock [options...]\n" |
281 | "\n" | 339 | "\n" |
282 | " -h, --help Show help message and quit.\n" | 340 | " -h, --help Show help message and quit.\n" |
@@ -288,13 +346,13 @@ int main(int argc, char **argv) { | |||
288 | " -u, --no-unlock-indicator Disable the unlock indicator.\n" | 346 | " -u, --no-unlock-indicator Disable the unlock indicator.\n" |
289 | " -f, --daemonize Detach from the controlling terminal.\n"; | 347 | " -f, --daemonize Detach from the controlling terminal.\n"; |
290 | 348 | ||
291 | struct swaylock_args args = { | 349 | state.args = (struct swaylock_args){ |
292 | .mode = BACKGROUND_MODE_SOLID_COLOR, | 350 | .mode = BACKGROUND_MODE_SOLID_COLOR, |
293 | .color = 0xFFFFFFFF, | 351 | .color = 0xFFFFFFFF, |
294 | .show_indicator = true, | 352 | .show_indicator = true, |
295 | }; | 353 | }; |
296 | state.args = args; | ||
297 | wl_list_init(&state.images); | 354 | wl_list_init(&state.images); |
355 | |||
298 | wlr_log_init(L_DEBUG, NULL); | 356 | wlr_log_init(L_DEBUG, NULL); |
299 | 357 | ||
300 | int c; | 358 | int c; |
@@ -369,6 +427,8 @@ int main(int argc, char **argv) { | |||
369 | return 0; | 427 | return 0; |
370 | } | 428 | } |
371 | 429 | ||
430 | zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager); | ||
431 | |||
372 | if (state.zxdg_output_manager) { | 432 | if (state.zxdg_output_manager) { |
373 | struct swaylock_surface *surface; | 433 | struct swaylock_surface *surface; |
374 | wl_list_for_each(surface, &state.surfaces, link) { | 434 | wl_list_for_each(surface, &state.surfaces, link) { |
@@ -385,33 +445,9 @@ int main(int argc, char **argv) { | |||
385 | 445 | ||
386 | struct swaylock_surface *surface; | 446 | struct swaylock_surface *surface; |
387 | wl_list_for_each(surface, &state.surfaces, link) { | 447 | wl_list_for_each(surface, &state.surfaces, link) { |
388 | surface->image = select_image(&state, surface); | 448 | create_layer_surface(surface); |
389 | |||
390 | surface->surface = wl_compositor_create_surface(state.compositor); | ||
391 | assert(surface->surface); | ||
392 | |||
393 | surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | ||
394 | state.layer_shell, surface->surface, surface->output, | ||
395 | ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); | ||
396 | assert(surface->layer_surface); | ||
397 | |||
398 | zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0); | ||
399 | zwlr_layer_surface_v1_set_anchor(surface->layer_surface, | ||
400 | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | | ||
401 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | | ||
402 | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | | ||
403 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); | ||
404 | zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1); | ||
405 | zwlr_layer_surface_v1_set_keyboard_interactivity( | ||
406 | surface->layer_surface, true); | ||
407 | zwlr_layer_surface_v1_add_listener(surface->layer_surface, | ||
408 | &layer_surface_listener, surface); | ||
409 | wl_surface_commit(surface->surface); | ||
410 | wl_display_roundtrip(state.display); | ||
411 | } | 449 | } |
412 | 450 | ||
413 | zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager); | ||
414 | |||
415 | state.run_display = true; | 451 | state.run_display = true; |
416 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { | 452 | while (wl_display_dispatch(state.display) != -1 && state.run_display) { |
417 | // This space intentionally left blank | 453 | // This space intentionally left blank |