aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build2
-rw-r--r--src/main.c49
-rw-r--r--src/x11_support.c40
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 <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
+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);