static xcb_cursor_t cursor;
static xcb_key_symbols_t *symbols;
static pam_handle_t *pam_handle;
-static int input_position = 0;
+int input_position = 0;
/* Holds the password you enter (in UTF-8). */
static char password[512];
static bool modeswitch_active = false;
static bool dpms = false;
bool unlock_indicator = true;
static bool dont_fork = false;
-static struct ev_loop *main_loop;
+struct ev_loop *main_loop;
static struct ev_timer *clear_pam_wrong_timeout;
-static struct ev_timer *clear_indicator_timeout;
extern unlock_state_t unlock_state;
extern pam_state_t pam_state;
pam_state = STATE_PAM_IDLE;
unlock_state = STATE_STARTED;
redraw_screen();
-}
-
-/*
- * Hides the unlock indicator completely when there is no content in the
- * password buffer.
- *
- */
-static void clear_indicator(EV_P_ ev_timer *w, int revents) {
- if (input_position == 0) {
- DEBUG("Clear indicator\n");
- unlock_state = STATE_STARTED;
- } else unlock_state = STATE_KEY_PRESSED;
- redraw_screen();
-}
-/*
- * (Re-)starts the clear_indicator timeout. Called after pressing backspace or
- * after an unsuccessful authentication attempt.
- *
- */
-static void start_clear_indicator_timeout() {
- if (clear_indicator_timeout) {
- ev_timer_stop(main_loop, clear_indicator_timeout);
- ev_timer_set(clear_indicator_timeout, 1.0, 0.);
- ev_timer_start(main_loop, clear_indicator_timeout);
- } else {
- clear_indicator_timeout = calloc(sizeof(struct ev_timer), 1);
- ev_timer_init(clear_indicator_timeout, clear_indicator, 1.0, 0.);
- ev_timer_start(main_loop, clear_indicator_timeout);
- }
+ /* Now free this timeout. */
+ ev_timer_stop(main_loop, clear_pam_wrong_timeout);
+ free(clear_pam_wrong_timeout);
+ clear_pam_wrong_timeout = NULL;
}
static void input_done() {
if (clear_pam_wrong_timeout) {
ev_timer_stop(main_loop, clear_pam_wrong_timeout);
+ free(clear_pam_wrong_timeout);
clear_pam_wrong_timeout = NULL;
}
/* Clear this state after 2 seconds (unless the user enters another
* password during that time). */
ev_now_update(main_loop);
- clear_pam_wrong_timeout = calloc(sizeof(struct ev_timer), 1);
- ev_timer_init(clear_pam_wrong_timeout, clear_pam_wrong, 2.0, 0.);
- ev_timer_start(main_loop, clear_pam_wrong_timeout);
+ if ((clear_pam_wrong_timeout = calloc(sizeof(struct ev_timer), 1))) {
+ ev_timer_init(clear_pam_wrong_timeout, clear_pam_wrong, 2.0, 0.);
+ ev_timer_start(main_loop, clear_pam_wrong_timeout);
+ }
/* Cancel the clear_indicator_timeout, it would hide the unlock indicator
* too early. */
- if (clear_indicator_timeout) {
- ev_timer_stop(main_loop, clear_indicator_timeout);
- clear_indicator_timeout = NULL;
- }
+ stop_clear_indicator_timeout();
/* beep on authentication failure, if enabled */
if (beep) {
static void redraw_timeout(EV_P_ ev_timer *w, int revents) {
redraw_screen();
+
+ ev_timer_stop(main_loop, w);
+ free(w);
}
/*
unlock_state = STATE_KEY_PRESSED;
struct ev_timer *timeout = calloc(sizeof(struct ev_timer), 1);
- ev_timer_init(timeout, redraw_timeout, 0.25, 0.);
- ev_timer_start(main_loop, timeout);
-
- if (clear_indicator_timeout) {
- ev_timer_stop(main_loop, clear_indicator_timeout);
- clear_indicator_timeout = NULL;
+ if (timeout) {
+ ev_timer_init(timeout, redraw_timeout, 0.25, 0.);
+ ev_timer_start(main_loop, timeout);
}
+
+ stop_clear_indicator_timeout();
}
/*
/* Strip off the highest bit (set if the event is generated) */
int type = (event->response_type & 0x7F);
-
- if (type == XCB_KEY_PRESS) {
- handle_key_press((xcb_key_press_event_t*)event);
- continue;
- }
-
- if (type == XCB_KEY_RELEASE) {
- handle_key_release((xcb_key_release_event_t*)event);
-
- /* If this was the backspace or escape key we are back at an
- * empty input, so turn off the screen if DPMS is enabled */
- if (dpms && input_position == 0)
- dpms_turn_off_screen(conn);
-
- continue;
- }
-
- if (type == XCB_VISIBILITY_NOTIFY) {
- handle_visibility_notify((xcb_visibility_notify_event_t*)event);
- continue;
- }
-
- if (type == XCB_MAP_NOTIFY) {
- if (!dont_fork) {
- /* After the first MapNotify, we never fork again. We don’t
- * expect to get another MapNotify, but better be sure… */
- dont_fork = true;
-
- /* In the parent process, we exit */
- if (fork() != 0)
- exit(0);
- }
- continue;
- }
-
- if (type == XCB_MAPPING_NOTIFY) {
- handle_mapping_notify((xcb_mapping_notify_event_t*)event);
- continue;
+ switch (type) {
+ case XCB_KEY_PRESS:
+ handle_key_press((xcb_key_press_event_t*)event);
+ break;
+
+ case XCB_KEY_RELEASE:
+ handle_key_release((xcb_key_release_event_t*)event);
+
+ /* If this was the backspace or escape key we are back at an
+ * empty input, so turn off the screen if DPMS is enabled */
+ if (dpms && input_position == 0)
+ dpms_turn_off_screen(conn);
+
+ break;
+
+ case XCB_VISIBILITY_NOTIFY:
+ handle_visibility_notify((xcb_visibility_notify_event_t*)event);
+ break;
+
+ case XCB_MAP_NOTIFY:
+ if (!dont_fork) {
+ /* After the first MapNotify, we never fork again. We don’t
+ * expect to get another MapNotify, but better be sure… */
+ dont_fork = true;
+
+ /* In the parent process, we exit */
+ if (fork() != 0)
+ exit(0);
+ }
+ break;
+
+ case XCB_MAPPING_NOTIFY:
+ handle_mapping_notify((xcb_mapping_notify_event_t*)event);
+ break;
+
+ case XCB_CONFIGURE_NOTIFY:
+ handle_screen_resize();
+ break;
}
- if (type == XCB_CONFIGURE_NOTIFY) {
- handle_screen_resize();
- continue;
- }
-
- printf("WARNING: unhandled event of type %d\n", type);
-
free(event);
}
}
if (dpms) {
xcb_dpms_capable_cookie_t dpmsc = xcb_dpms_capable(conn);
xcb_dpms_capable_reply_t *dpmsr;
- if ((dpmsr = xcb_dpms_capable_reply(conn, dpmsc, NULL)) && !dpmsr->capable) {
- fprintf(stderr, "Disabling DPMS, X server not DPMS capable\n");
- dpms = false;
+ if ((dpmsr = xcb_dpms_capable_reply(conn, dpmsc, NULL))) {
+ if (!dpmsr->capable) {
+ fprintf(stderr, "Disabling DPMS, X server not DPMS capable\n");
+ dpms = false;
+ }
+ free(dpmsr);
}
}
#include <math.h>
#include <xcb/xcb.h>
#include <xcb/xcb_keysyms.h>
+#include <ev.h>
#ifndef NOLIBCAIRO
#include <cairo.h>
* Variables defined in i3lock.c.
******************************************************************************/
+/* The current position in the input buffer. Useful to determine if any
+ * characters of the password have already been entered or not. */
+int input_position;
+
+/* The ev main loop. */
+struct ev_loop *main_loop;
+
/* The lock window. */
extern xcb_window_t win;
* Local variables.
******************************************************************************/
+static struct ev_timer *clear_indicator_timeout;
+
/* Cache the screen’s visual, necessary for creating a Cairo context. */
static xcb_visualtype_t *vistype;
xcb_free_pixmap(conn, bg_pixmap);
xcb_flush(conn);
}
+
+/*
+ * Hides the unlock indicator completely when there is no content in the
+ * password buffer.
+ *
+ */
+static void clear_indicator(EV_P_ ev_timer *w, int revents) {
+ if (input_position == 0) {
+ unlock_state = STATE_STARTED;
+ } else unlock_state = STATE_KEY_PRESSED;
+ redraw_screen();
+
+ ev_timer_stop(main_loop, clear_indicator_timeout);
+ free(clear_indicator_timeout);
+ clear_indicator_timeout = NULL;
+}
+
+/*
+ * (Re-)starts the clear_indicator timeout. Called after pressing backspace or
+ * after an unsuccessful authentication attempt.
+ *
+ */
+void start_clear_indicator_timeout() {
+ if (clear_indicator_timeout) {
+ ev_timer_stop(main_loop, clear_indicator_timeout);
+ ev_timer_set(clear_indicator_timeout, 1.0, 0.);
+ ev_timer_start(main_loop, clear_indicator_timeout);
+ } else {
+ /* When there is no memory, we just don’t have a timeout. We cannot
+ * exit() here, since that would effectively unlock the screen. */
+ if (!(clear_indicator_timeout = calloc(sizeof(struct ev_timer), 1)))
+ return;
+ ev_timer_init(clear_indicator_timeout, clear_indicator, 1.0, 0.);
+ ev_timer_start(main_loop, clear_indicator_timeout);
+ }
+}
+
+/*
+ * Stops the clear_indicator timeout.
+ *
+ */
+void stop_clear_indicator_timeout() {
+ if (clear_indicator_timeout) {
+ ev_timer_stop(main_loop, clear_indicator_timeout);
+ free(clear_indicator_timeout);
+ clear_indicator_timeout = NULL;
+ }
+}