Add password buffer, refactor rendering/surfaces

This commit is contained in:
Drew DeVault 2018-04-03 14:31:30 -04:00
parent aead06f43c
commit 3f21cd441b
5 changed files with 114 additions and 49 deletions

79
main.c
View File

@ -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, 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) { uint32_t serial, uint32_t width, uint32_t height) {
struct swaylock_context *context = data; struct swaylock_surface *surface = data;
context->width = width; surface->width = width;
context->height = height; surface->height = height;
zwlr_layer_surface_v1_ack_configure(surface, serial); zwlr_layer_surface_v1_ack_configure(layer_surface, serial);
render_frame(context); render_frame(surface);
} }
static void layer_surface_closed(void *data, static void layer_surface_closed(void *data,
struct zwlr_layer_surface_v1 *surface) { struct zwlr_layer_surface_v1 *layer_surface) {
struct swaylock_context *context = data; struct swaylock_surface *surface = data;
zwlr_layer_surface_v1_destroy(context->layer_surface); zwlr_layer_surface_v1_destroy(surface->layer_surface);
wl_surface_destroy(context->surface); wl_surface_destroy(surface->surface);
context->state->run_display = false; surface->state->run_display = false;
} }
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { 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( state->layer_shell = wl_registry_bind(
registry, name, &zwlr_layer_shell_v1_interface, 1); registry, name, &zwlr_layer_shell_v1_interface, 1);
} else if (strcmp(interface, wl_output_interface.name) == 0) { } else if (strcmp(interface, wl_output_interface.name) == 0) {
struct swaylock_context *context = struct swaylock_surface *surface =
calloc(1, sizeof(struct swaylock_context)); calloc(1, sizeof(struct swaylock_surface));
context->state = state; surface->state = state;
context->output = wl_registry_bind(registry, name, surface->output = wl_registry_bind(registry, name,
&wl_output_interface, 1); &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); state.xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
assert(state.display = wl_display_connect(NULL)); assert(state.display = wl_display_connect(NULL));
@ -207,33 +190,33 @@ int main(int argc, char **argv) {
wl_display_roundtrip(state.display); wl_display_roundtrip(state.display);
assert(state.compositor && state.layer_shell && state.shm); 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."); wlr_log(L_DEBUG, "Exiting - no outputs to show on.");
return 0; return 0;
} }
struct swaylock_context *context; struct swaylock_surface *surface;
wl_list_for_each(context, &state.contexts, link) { wl_list_for_each(surface, &state.surfaces, link) {
assert(context->surface = assert(surface->surface =
wl_compositor_create_surface(state.compositor)); wl_compositor_create_surface(state.compositor));
context->layer_surface = zwlr_layer_shell_v1_get_layer_surface( surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
state.layer_shell, context->surface, context->output, state.layer_shell, surface->surface, surface->output,
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen"); 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_size(surface->layer_surface, 0, 0);
zwlr_layer_surface_v1_set_anchor(context->layer_surface, zwlr_layer_surface_v1_set_anchor(surface->layer_surface,
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); 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( zwlr_layer_surface_v1_set_keyboard_interactivity(
context->layer_surface, true); surface->layer_surface, true);
zwlr_layer_surface_v1_add_listener(context->layer_surface, zwlr_layer_surface_v1_add_listener(surface->layer_surface,
&layer_surface_listener, context); &layer_surface_listener, surface);
wl_surface_commit(context->surface); wl_surface_commit(surface->surface);
wl_display_roundtrip(state.display); wl_display_roundtrip(state.display);
} }

View File

@ -1,6 +1,8 @@
executable( executable(
'swaylock', [ 'swaylock', [
'main.c', 'main.c',
'password.c',
'render.c',
'seat.c' 'seat.c'
], ],
include_directories: [sway_inc], include_directories: [sway_inc],

57
password.c Normal file
View File

@ -0,0 +1,57 @@
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <wlr/util/log.h>
#include <xkbcommon/xkbcommon.h>
#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;
}
}

21
render.c Normal file
View File

@ -0,0 +1,21 @@
#include <wayland-client.h>
#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);
}

4
seat.c
View File

@ -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 ? uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ?
key + 8 : 0; key + 8 : 0;
uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); 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, static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,