aboutsummaryrefslogtreecommitdiffstats
path: root/swaylock
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-04-03 14:31:30 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-04-04 18:47:48 -0400
commit066143adef7adc6e76e43e1990db2f75fe984b42 (patch)
treef9509c14f04399bf02d2cc31ff62869a07691543 /swaylock
parentLink swaylock to xkbcommon (diff)
downloadsway-066143adef7adc6e76e43e1990db2f75fe984b42.tar.gz
sway-066143adef7adc6e76e43e1990db2f75fe984b42.tar.zst
sway-066143adef7adc6e76e43e1990db2f75fe984b42.zip
Add password buffer, refactor rendering/surfaces
Diffstat (limited to 'swaylock')
-rw-r--r--swaylock/main.c79
-rw-r--r--swaylock/meson.build2
-rw-r--r--swaylock/password.c57
-rw-r--r--swaylock/render.c21
-rw-r--r--swaylock/seat.c4
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
35static 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
52static void layer_surface_configure(void *data, 35static 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
62static void layer_surface_closed(void *data, 45static 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
70static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { 53static 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 @@
1executable( 1executable(
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
10static void backspace(struct swaylock_password *pw) {
11 if (pw->len != 0) {
12 pw->buffer[--pw->len] = 0;
13 }
14}
15
16static 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
41void 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
6void 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
79static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, 81static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,