From 5087ea7538c32d953705f0352227648ecd8e33f0 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Sat, 19 Jan 2019 20:17:41 -0800 Subject: Changes to get it to work with xsecurelock Only thing left to do is to get it to read the screen dimensions, since apparently we don't get window changed events. --- meson.build | 2 +- src/main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/x11_support.c | 40 +++++++++++++++++++++++++++++----------- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index fab674f..2bbb9b3 100644 --- a/meson.build +++ b/meson.build @@ -29,7 +29,7 @@ resources = gnome.compile_resources( c_name: 'as' ) -executable('buzzlocker', +executable('auth_buzzlocker', sources: sources + resources, dependencies: dependencies, install: true diff --git a/src/main.c b/src/main.c index 5edb881..fc00437 100644 --- a/src/main.c +++ b/src/main.c @@ -8,12 +8,14 @@ #include "render.h" #include "x11_support.h" +#include #include #include #include #include #include +static const int kXSecureLockCharFD = 0; static const size_t kMaxPasswordLength = 128; static inline saver_state_t* saver_state(void *c) @@ -35,6 +37,40 @@ static void window_changed_size(saver_state_t *state, XConfigureEvent *event) cairo_xlib_surface_set_size(state->surface, event->width, event->height); } +static void handle_xsl_key_input(saver_state_t *state, const char c) +{ + char *password_buf = state->password_buffer; + size_t pw_len = strlen(password_buf); + switch (c) { + case '\b': // Backspace. + if (pw_len > 0) { + password_buf[pw_len - 1] = '\0'; + } + break; + case '\177': // Delete + break; + case '\001': // Ctrl-A. + // TODO: cursor movement + break; + case '\025': // Ctrl-U. + // TODO: clear line + break; + case 0: // Shouldn't happen. + case '\033': // Escape. + break; + case '\r': // Return. + case '\n': // Return. + accept_password(state); + break; + default: + if (pw_len + 1 < state->password_buffer_len) { + password_buf[pw_len] = c; + password_buf[pw_len + 1] = '\0'; + } + break; + } +} + static void handle_key_event(saver_state_t *state, XKeyEvent *event) { if (!state->input_allowed) return; @@ -65,6 +101,13 @@ static int poll_events(saver_state_t *state) XEvent e; const bool block_for_next_event = false; + // Via xsecurelock, take this route + char buf; + ssize_t read_res = read(kXSecureLockCharFD, &buf, 1); + if (read_res > 0) { + handle_xsl_key_input(state, buf); + } + // Temp: this should be handled by x11_support Display *display = cairo_xlib_surface_get_display(state->surface); for (;;) { @@ -208,6 +251,8 @@ static int runloop(cairo_surface_t *surface) state.input_allowed = false; state.password_prompt = ""; state.is_authenticated = false; + state.canvas_width = 800; + state.canvas_height = 600; auth_callbacks_t callbacks = { .info_handler = callback_show_info, @@ -257,6 +302,10 @@ int main(int argc, char **argv) exit(1); } + // Make it so reading from the xsecurelock file descriptor doesn't block + int flags = fcntl(kXSecureLockCharFD, F_GETFL, 0); + fcntl(kXSecureLockCharFD, F_SETFL, flags | O_NONBLOCK); + // Docs say this must be called whenever the size of the window changes cairo_xlib_surface_set_size(surface, default_width, default_height); diff --git a/src/x11_support.c b/src/x11_support.c index 87dd1ac..8ab05c1 100644 --- a/src/x11_support.c +++ b/src/x11_support.c @@ -12,6 +12,33 @@ static Window __window = { 0 }; static Display *__display = NULL; +static Window get_window_from_environment_or_make_one(Display *display, int width, int height) +{ + Window window; + + const char *env_window = getenv("XSCREENSAVER_WINDOW"); + if (env_window != NULL && env_window[0] != 0) { + char *endptr = NULL; + unsigned long long number = strtoull(env_window, &endptr, 0); + window = (Window)number; + } else { + // Presumably this is for debugging + Window root_window = DefaultRootWindow(__display); + window = XCreateSimpleWindow( + display, // display + root_window, // parent window + 0, 0, // x, y + width, // width + height, // height + 0, // border_width + 0, // border + 0 // background + ); + } + + return window; +} + cairo_surface_t* x11_helper_acquire_cairo_surface(int width, int height) { __display = XOpenDisplay(NULL); @@ -20,17 +47,8 @@ cairo_surface_t* x11_helper_acquire_cairo_surface(int width, int height) return NULL; } - Window root_window = DefaultRootWindow(__display); - __window = XCreateSimpleWindow( - __display, // display - root_window, // parent window - 0, 0, // x, y - width, // width - height, // height - 0, // border_width - 0, // border - 0 // background - ); + // Create (or get) window + __window = get_window_from_environment_or_make_one(__display, width, height); // Enable key events XSelectInput(__display, __window, ButtonPressMask | KeyPressMask | StructureNotifyMask); -- cgit v1.2.3