diff options
Diffstat (limited to 'swaylock')
-rw-r--r-- | swaylock/main.c | 79 | ||||
-rw-r--r-- | swaylock/meson.build | 2 | ||||
-rw-r--r-- | swaylock/password.c | 57 | ||||
-rw-r--r-- | swaylock/render.c | 21 | ||||
-rw-r--r-- | swaylock/seat.c | 4 |
5 files changed, 114 insertions, 49 deletions
diff --git a/swaylock/main.c b/swaylock/main.c index 7602e47e..c8fdc2f4 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -32,39 +32,22 @@ static void daemonize() { | |||
32 | } | 32 | } |
33 | } | 33 | } |
34 | 34 | ||
35 | static void render_frame(struct swaylock_context *context) { | ||
36 | struct swaylock_state *state = context->state; | ||
37 | context->current_buffer = get_next_buffer(state->shm, | ||
38 | context->buffers, context->width, context->height); | ||
39 | cairo_t *cairo = context->current_buffer->cairo; | ||
40 | if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR) { | ||
41 | cairo_set_source_u32(cairo, state->args.color); | ||
42 | cairo_paint(cairo); | ||
43 | } else { | ||
44 | render_background_image(cairo, context->image, | ||
45 | state->args.mode, context->width, context->height); | ||
46 | } | ||
47 | wl_surface_attach(context->surface, context->current_buffer->buffer, 0, 0); | ||
48 | wl_surface_damage(context->surface, 0, 0, context->width, context->height); | ||
49 | wl_surface_commit(context->surface); | ||
50 | } | ||
51 | |||
52 | static void layer_surface_configure(void *data, | 35 | static void layer_surface_configure(void *data, |
53 | struct zwlr_layer_surface_v1 *surface, | 36 | struct zwlr_layer_surface_v1 *layer_surface, |
54 | uint32_t serial, uint32_t width, uint32_t height) { | 37 | uint32_t serial, uint32_t width, uint32_t height) { |
55 | struct swaylock_context *context = data; | 38 | struct swaylock_surface *surface = data; |
56 | context->width = width; | 39 | surface->width = width; |
57 | context->height = height; | 40 | surface->height = height; |
58 | zwlr_layer_surface_v1_ack_configure(surface, serial); | 41 | zwlr_layer_surface_v1_ack_configure(layer_surface, serial); |
59 | render_frame(context); | 42 | render_frame(surface); |
60 | } | 43 | } |
61 | 44 | ||
62 | static void layer_surface_closed(void *data, | 45 | static void layer_surface_closed(void *data, |
63 | struct zwlr_layer_surface_v1 *surface) { | 46 | struct zwlr_layer_surface_v1 *layer_surface) { |
64 | struct swaylock_context *context = data; | 47 | struct swaylock_surface *surface = data; |
65 | zwlr_layer_surface_v1_destroy(context->layer_surface); | 48 | zwlr_layer_surface_v1_destroy(surface->layer_surface); |
66 | wl_surface_destroy(context->surface); | 49 | wl_surface_destroy(surface->surface); |
67 | context->state->run_display = false; | 50 | surface->state->run_display = false; |
68 | } | 51 | } |
69 | 52 | ||
70 | static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { | 53 | static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { |
@@ -89,12 +72,12 @@ static void handle_global(void *data, struct wl_registry *registry, | |||
89 | state->layer_shell = wl_registry_bind( | 72 | state->layer_shell = wl_registry_bind( |
90 | registry, name, &zwlr_layer_shell_v1_interface, 1); | 73 | registry, name, &zwlr_layer_shell_v1_interface, 1); |
91 | } else if (strcmp(interface, wl_output_interface.name) == 0) { | 74 | } else if (strcmp(interface, wl_output_interface.name) == 0) { |
92 | struct swaylock_context *context = | 75 | struct swaylock_surface *surface = |
93 | calloc(1, sizeof(struct swaylock_context)); | 76 | calloc(1, sizeof(struct swaylock_surface)); |
94 | context->state = state; | 77 | surface->state = state; |
95 | context->output = wl_registry_bind(registry, name, | 78 | surface->output = wl_registry_bind(registry, name, |
96 | &wl_output_interface, 1); | 79 | &wl_output_interface, 1); |
97 | wl_list_insert(&state->contexts, &context->link); | 80 | wl_list_insert(&state->surfaces, &surface->link); |
98 | } | 81 | } |
99 | } | 82 | } |
100 | 83 | ||
@@ -198,7 +181,7 @@ int main(int argc, char **argv) { | |||
198 | } | 181 | } |
199 | } | 182 | } |
200 | 183 | ||
201 | wl_list_init(&state.contexts); | 184 | wl_list_init(&state.surfaces); |
202 | state.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | 185 | state.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); |
203 | assert(state.display = wl_display_connect(NULL)); | 186 | assert(state.display = wl_display_connect(NULL)); |
204 | 187 | ||
@@ -207,33 +190,33 @@ int main(int argc, char **argv) { | |||
207 | wl_display_roundtrip(state.display); | 190 | wl_display_roundtrip(state.display); |
208 | assert(state.compositor && state.layer_shell && state.shm); | 191 | assert(state.compositor && state.layer_shell && state.shm); |
209 | 192 | ||
210 | if (wl_list_empty(&state.contexts)) { | 193 | if (wl_list_empty(&state.surfaces)) { |
211 | wlr_log(L_DEBUG, "Exiting - no outputs to show on."); | 194 | wlr_log(L_DEBUG, "Exiting - no outputs to show on."); |
212 | return 0; | 195 | return 0; |
213 | } | 196 | } |
214 | 197 | ||
215 | struct swaylock_context *context; | 198 | struct swaylock_surface *surface; |
216 | wl_list_for_each(context, &state.contexts, link) { | 199 | wl_list_for_each(surface, &state.surfaces, link) { |
217 | assert(context->surface = | 200 | assert(surface->surface = |
218 | wl_compositor_create_surface(state.compositor)); | 201 | wl_compositor_create_surface(state.compositor)); |
219 | 202 | ||
220 | context->layer_surface = zwlr_layer_shell_v1_get_layer_surface( | 203 | surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( |
221 | state.layer_shell, context->surface, context->output, | 204 | state.layer_shell, surface->surface, surface->output, |
222 | ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); | 205 | ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); |
223 | assert(context->layer_surface); | 206 | assert(surface->layer_surface); |
224 | 207 | ||
225 | zwlr_layer_surface_v1_set_size(context->layer_surface, 0, 0); | 208 | zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0); |
226 | zwlr_layer_surface_v1_set_anchor(context->layer_surface, | 209 | zwlr_layer_surface_v1_set_anchor(surface->layer_surface, |
227 | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | | 210 | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | |
228 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | | 211 | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | |
229 | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | | 212 | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | |
230 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); | 213 | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); |
231 | zwlr_layer_surface_v1_set_exclusive_zone(context->layer_surface, -1); | 214 | zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1); |
232 | zwlr_layer_surface_v1_set_keyboard_interactivity( | 215 | zwlr_layer_surface_v1_set_keyboard_interactivity( |
233 | context->layer_surface, true); | 216 | surface->layer_surface, true); |
234 | zwlr_layer_surface_v1_add_listener(context->layer_surface, | 217 | zwlr_layer_surface_v1_add_listener(surface->layer_surface, |
235 | &layer_surface_listener, context); | 218 | &layer_surface_listener, surface); |
236 | wl_surface_commit(context->surface); | 219 | wl_surface_commit(surface->surface); |
237 | wl_display_roundtrip(state.display); | 220 | wl_display_roundtrip(state.display); |
238 | } | 221 | } |
239 | 222 | ||
diff --git a/swaylock/meson.build b/swaylock/meson.build index 2a1f029a..3cde47a4 100644 --- a/swaylock/meson.build +++ b/swaylock/meson.build | |||
@@ -1,6 +1,8 @@ | |||
1 | executable( | 1 | executable( |
2 | 'swaylock', [ | 2 | 'swaylock', [ |
3 | 'main.c', | 3 | 'main.c', |
4 | 'password.c', | ||
5 | 'render.c', | ||
4 | 'seat.c' | 6 | 'seat.c' |
5 | ], | 7 | ], |
6 | include_directories: [sway_inc], | 8 | include_directories: [sway_inc], |
diff --git a/swaylock/password.c b/swaylock/password.c new file mode 100644 index 00000000..da67205d --- /dev/null +++ b/swaylock/password.c | |||
@@ -0,0 +1,57 @@ | |||
1 | #include <assert.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <unistd.h> | ||
4 | #include <wlr/util/log.h> | ||
5 | #include <xkbcommon/xkbcommon.h> | ||
6 | #include "swaylock/swaylock.h" | ||
7 | #include "swaylock/seat.h" | ||
8 | #include "unicode.h" | ||
9 | |||
10 | static void backspace(struct swaylock_password *pw) { | ||
11 | if (pw->len != 0) { | ||
12 | pw->buffer[--pw->len] = 0; | ||
13 | } | ||
14 | } | ||
15 | |||
16 | static void append_ch(struct swaylock_password *pw, uint32_t codepoint) { | ||
17 | if (!pw->buffer) { | ||
18 | pw->size = 8; | ||
19 | if (!(pw->buffer = malloc(pw->size))) { | ||
20 | // TODO: Display error | ||
21 | return; | ||
22 | } | ||
23 | pw->buffer[0] = 0; | ||
24 | } | ||
25 | size_t utf8_size = utf8_chsize(codepoint); | ||
26 | if (pw->len + utf8_size + 1 >= pw->size) { | ||
27 | size_t size = pw->size * 2; | ||
28 | char *buffer = realloc(pw->buffer, size); | ||
29 | if (!buffer) { | ||
30 | // TODO: Display error | ||
31 | return; | ||
32 | } | ||
33 | pw->size = size; | ||
34 | pw->buffer = buffer; | ||
35 | } | ||
36 | utf8_encode(&pw->buffer[pw->len], codepoint); | ||
37 | pw->buffer[pw->len + utf8_size] = 0; | ||
38 | pw->len += utf8_size; | ||
39 | } | ||
40 | |||
41 | void swaylock_handle_key(struct swaylock_state *state, | ||
42 | xkb_keysym_t keysym, uint32_t codepoint) { | ||
43 | switch (keysym) { | ||
44 | case XKB_KEY_KP_Enter: /* fallthrough */ | ||
45 | case XKB_KEY_Return: | ||
46 | // TODO: Attempt password | ||
47 | break; | ||
48 | case XKB_KEY_BackSpace: | ||
49 | backspace(&state->password); | ||
50 | break; | ||
51 | default: | ||
52 | if (codepoint) { | ||
53 | append_ch(&state->password, codepoint); | ||
54 | } | ||
55 | break; | ||
56 | } | ||
57 | } | ||
diff --git a/swaylock/render.c b/swaylock/render.c new file mode 100644 index 00000000..8fc47281 --- /dev/null +++ b/swaylock/render.c | |||
@@ -0,0 +1,21 @@ | |||
1 | #include <wayland-client.h> | ||
2 | #include "cairo.h" | ||
3 | #include "background-image.h" | ||
4 | #include "swaylock/swaylock.h" | ||
5 | |||
6 | void render_frame(struct swaylock_surface *surface) { | ||
7 | struct swaylock_state *state = surface->state; | ||
8 | surface->current_buffer = get_next_buffer(state->shm, | ||
9 | surface->buffers, surface->width, surface->height); | ||
10 | cairo_t *cairo = surface->current_buffer->cairo; | ||
11 | if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR) { | ||
12 | cairo_set_source_u32(cairo, state->args.color); | ||
13 | cairo_paint(cairo); | ||
14 | } else { | ||
15 | render_background_image(cairo, surface->image, | ||
16 | state->args.mode, surface->width, surface->height); | ||
17 | } | ||
18 | wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0); | ||
19 | wl_surface_damage(surface->surface, 0, 0, surface->width, surface->height); | ||
20 | wl_surface_commit(surface->surface); | ||
21 | } | ||
diff --git a/swaylock/seat.c b/swaylock/seat.c index 522200f2..6c46bb41 100644 --- a/swaylock/seat.c +++ b/swaylock/seat.c | |||
@@ -73,7 +73,9 @@ static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, | |||
73 | uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? | 73 | uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? |
74 | key + 8 : 0; | 74 | key + 8 : 0; |
75 | uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); | 75 | uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); |
76 | wlr_log(L_DEBUG, "%c %d", codepoint, sym); | 76 | if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED) { |
77 | swaylock_handle_key(state, sym, codepoint); | ||
78 | } | ||
77 | } | 79 | } |
78 | 80 | ||
79 | static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, | 81 | static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, |