From 3f21cd441b50bd4dfa754e60ad6d7733815ac349 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 3 Apr 2018 14:31:30 -0400 Subject: [PATCH] Add password buffer, refactor rendering/surfaces --- main.c | 79 +++++++++++++++++++++-------------------------------- meson.build | 2 ++ password.c | 57 ++++++++++++++++++++++++++++++++++++++ render.c | 21 ++++++++++++++ seat.c | 4 ++- 5 files changed, 114 insertions(+), 49 deletions(-) create mode 100644 password.c create mode 100644 render.c diff --git a/main.c b/main.c index 7602e47..c8fdc2f 100644 --- a/main.c +++ b/main.c @@ -32,39 +32,22 @@ static void daemonize() { } } -static void render_frame(struct swaylock_context *context) { - struct swaylock_state *state = context->state; - context->current_buffer = get_next_buffer(state->shm, - context->buffers, context->width, context->height); - cairo_t *cairo = context->current_buffer->cairo; - if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR) { - cairo_set_source_u32(cairo, state->args.color); - cairo_paint(cairo); - } else { - render_background_image(cairo, context->image, - state->args.mode, context->width, context->height); - } - wl_surface_attach(context->surface, context->current_buffer->buffer, 0, 0); - wl_surface_damage(context->surface, 0, 0, context->width, context->height); - wl_surface_commit(context->surface); -} - static void layer_surface_configure(void *data, - struct zwlr_layer_surface_v1 *surface, + struct zwlr_layer_surface_v1 *layer_surface, uint32_t serial, uint32_t width, uint32_t height) { - struct swaylock_context *context = data; - context->width = width; - context->height = height; - zwlr_layer_surface_v1_ack_configure(surface, serial); - render_frame(context); + struct swaylock_surface *surface = data; + surface->width = width; + surface->height = height; + zwlr_layer_surface_v1_ack_configure(layer_surface, serial); + render_frame(surface); } static void layer_surface_closed(void *data, - struct zwlr_layer_surface_v1 *surface) { - struct swaylock_context *context = data; - zwlr_layer_surface_v1_destroy(context->layer_surface); - wl_surface_destroy(context->surface); - context->state->run_display = false; + struct zwlr_layer_surface_v1 *layer_surface) { + struct swaylock_surface *surface = data; + zwlr_layer_surface_v1_destroy(surface->layer_surface); + wl_surface_destroy(surface->surface); + surface->state->run_display = false; } 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, state->layer_shell = wl_registry_bind( registry, name, &zwlr_layer_shell_v1_interface, 1); } else if (strcmp(interface, wl_output_interface.name) == 0) { - struct swaylock_context *context = - calloc(1, sizeof(struct swaylock_context)); - context->state = state; - context->output = wl_registry_bind(registry, name, + struct swaylock_surface *surface = + calloc(1, sizeof(struct swaylock_surface)); + surface->state = state; + surface->output = wl_registry_bind(registry, name, &wl_output_interface, 1); - wl_list_insert(&state->contexts, &context->link); + wl_list_insert(&state->surfaces, &surface->link); } } @@ -198,7 +181,7 @@ int main(int argc, char **argv) { } } - wl_list_init(&state.contexts); + wl_list_init(&state.surfaces); state.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); assert(state.display = wl_display_connect(NULL)); @@ -207,33 +190,33 @@ int main(int argc, char **argv) { wl_display_roundtrip(state.display); assert(state.compositor && state.layer_shell && state.shm); - if (wl_list_empty(&state.contexts)) { + if (wl_list_empty(&state.surfaces)) { wlr_log(L_DEBUG, "Exiting - no outputs to show on."); return 0; } - struct swaylock_context *context; - wl_list_for_each(context, &state.contexts, link) { - assert(context->surface = + struct swaylock_surface *surface; + wl_list_for_each(surface, &state.surfaces, link) { + assert(surface->surface = wl_compositor_create_surface(state.compositor)); - context->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - state.layer_shell, context->surface, context->output, + surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface( + state.layer_shell, surface->surface, surface->output, ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); - assert(context->layer_surface); + assert(surface->layer_surface); - zwlr_layer_surface_v1_set_size(context->layer_surface, 0, 0); - zwlr_layer_surface_v1_set_anchor(context->layer_surface, + zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0); + zwlr_layer_surface_v1_set_anchor(surface->layer_surface, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); - zwlr_layer_surface_v1_set_exclusive_zone(context->layer_surface, -1); + zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1); zwlr_layer_surface_v1_set_keyboard_interactivity( - context->layer_surface, true); - zwlr_layer_surface_v1_add_listener(context->layer_surface, - &layer_surface_listener, context); - wl_surface_commit(context->surface); + surface->layer_surface, true); + zwlr_layer_surface_v1_add_listener(surface->layer_surface, + &layer_surface_listener, surface); + wl_surface_commit(surface->surface); wl_display_roundtrip(state.display); } diff --git a/meson.build b/meson.build index 2a1f029..3cde47a 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,8 @@ executable( 'swaylock', [ 'main.c', + 'password.c', + 'render.c', 'seat.c' ], include_directories: [sway_inc], diff --git a/password.c b/password.c new file mode 100644 index 0000000..da67205 --- /dev/null +++ b/password.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include "swaylock/swaylock.h" +#include "swaylock/seat.h" +#include "unicode.h" + +static void backspace(struct swaylock_password *pw) { + if (pw->len != 0) { + pw->buffer[--pw->len] = 0; + } +} + +static void append_ch(struct swaylock_password *pw, uint32_t codepoint) { + if (!pw->buffer) { + pw->size = 8; + if (!(pw->buffer = malloc(pw->size))) { + // TODO: Display error + return; + } + pw->buffer[0] = 0; + } + size_t utf8_size = utf8_chsize(codepoint); + if (pw->len + utf8_size + 1 >= pw->size) { + size_t size = pw->size * 2; + char *buffer = realloc(pw->buffer, size); + if (!buffer) { + // TODO: Display error + return; + } + pw->size = size; + pw->buffer = buffer; + } + utf8_encode(&pw->buffer[pw->len], codepoint); + pw->buffer[pw->len + utf8_size] = 0; + pw->len += utf8_size; +} + +void swaylock_handle_key(struct swaylock_state *state, + xkb_keysym_t keysym, uint32_t codepoint) { + switch (keysym) { + case XKB_KEY_KP_Enter: /* fallthrough */ + case XKB_KEY_Return: + // TODO: Attempt password + break; + case XKB_KEY_BackSpace: + backspace(&state->password); + break; + default: + if (codepoint) { + append_ch(&state->password, codepoint); + } + break; + } +} diff --git a/render.c b/render.c new file mode 100644 index 0000000..8fc4728 --- /dev/null +++ b/render.c @@ -0,0 +1,21 @@ +#include +#include "cairo.h" +#include "background-image.h" +#include "swaylock/swaylock.h" + +void render_frame(struct swaylock_surface *surface) { + struct swaylock_state *state = surface->state; + surface->current_buffer = get_next_buffer(state->shm, + surface->buffers, surface->width, surface->height); + cairo_t *cairo = surface->current_buffer->cairo; + if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR) { + cairo_set_source_u32(cairo, state->args.color); + cairo_paint(cairo); + } else { + render_background_image(cairo, surface->image, + state->args.mode, surface->width, surface->height); + } + wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0); + wl_surface_damage(surface->surface, 0, 0, surface->width, surface->height); + wl_surface_commit(surface->surface); +} diff --git a/seat.c b/seat.c index 522200f..6c46bb4 100644 --- a/seat.c +++ b/seat.c @@ -73,7 +73,9 @@ static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? key + 8 : 0; uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); - wlr_log(L_DEBUG, "%c %d", codepoint, sym); + if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED) { + swaylock_handle_key(state, sym, codepoint); + } } static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,