Hello community, here is the log from the commit of package i3lock for openSUSE:Factory checked in at 2017-06-28 10:36:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/i3lock (Old) and /work/SRC/openSUSE:Factory/.i3lock.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "i3lock" Wed Jun 28 10:36:24 2017 rev:10 rq:505642 version:2.9 Changes: -------- --- /work/SRC/openSUSE:Factory/i3lock/i3lock.changes 2017-01-10 10:44:06.894000680 +0100 +++ /work/SRC/openSUSE:Factory/.i3lock.new/i3lock.changes 2017-06-28 10:36:25.022268150 +0200 @@ -1,0 +2,23 @@ +Sun Jun 11 07:09:22 UTC 2017 - mimi...@gmail.com + +- drop i3lock-2.5-use-unix2_chkpwd.diff +- use default pam config - drop i3lock.pam + +------------------------------------------------------------------- +Sat Jun 10 13:34:49 UTC 2017 - mimi...@gmail.com + +- update to 2.9 +- refresh i3lock-2.5-use-unix2_chkpwd.diff +* Removed obsolete inactivity timeout +* Set font face +* Automatically unlock (without having to press <Enter>) one attempt which was + entered while authenticating +* Stop leaking the image_path dup +* Displaying locking message when grabbing the pointer/keyboard +* Display error message when locking failed +* Add Enter on C-m +* Change input slices to be exactly pi/3 in size instead of slightly more +* Fix covering of composited notifications using the XComposite extension +* Remove last traces of DPMS + +------------------------------------------------------------------- Old: ---- i3lock-2.5-use-unix2_chkpwd.diff i3lock-2.8.tar.bz2 i3lock.pam New: ---- i3lock-2.9.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ i3lock.spec ++++++ --- /var/tmp/diff_new_pack.xzKrOE/_old 2017-06-28 10:36:25.582188936 +0200 +++ /var/tmp/diff_new_pack.xzKrOE/_new 2017-06-28 10:36:25.586188370 +0200 @@ -1,7 +1,7 @@ # # spec file for package i3lock # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2014 B1 Systems GmbH, Vohburg, Germany. # Copyright (c) 2012 Pascal Bleser <pascal.ble...@opensuse.org> # @@ -19,42 +19,32 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ - Name: i3lock -Version: 2.8 +Version: 2.9 Release: 0 Summary: Screen Locker for the i3 Window Manager License: BSD-3-Clause Group: System/GUI/Other +Url: http://i3wm.org/i3lock/ Source: http://i3wm.org/i3lock/i3lock-%{version}.tar.bz2 -Source1: i3lock.pam # borrowed from gnome-icon-theme Source2: i3lock-icon.png Source3: xlock.sh -# PATCH-FEATURE-OPENSUSE i3lock-2.5-use-unix2_chkpwd.diff -- seife+...@b1-systems.com -Patch1: i3lock-2.5-use-unix2_chkpwd.diff -Url: http://i3wm.org/i3lock/ -BuildRoot: %{_tmppath}/%{name}-%{version}-build -BuildRequires: cairo-devel BuildRequires: gcc -BuildRequires: glib2-devel BuildRequires: glibc-devel -BuildRequires: libev-devel -%if 0%{?suse_version} > 1310 -# /usr/lib64/libEGL.so.1 now requires libudev.so.1, might be a packaging error BuildRequires: libudev1 -%endif BuildRequires: make BuildRequires: pam-devel +BuildRequires: pam-modules BuildRequires: pkgconfig BuildRequires: pkgconfig(cairo) +BuildRequires: pkgconfig(libev) BuildRequires: pkgconfig(xcb-atom) -BuildRequires: pkgconfig(xkbcommon-x11) -Requires: pam-modules -BuildRequires: pam-modules BuildRequires: pkgconfig(xcb-image) -BuildRequires: pkgconfig(xcb-keysyms) BuildRequires: pkgconfig(xkbcommon) >= 0.5.0 +BuildRequires: pkgconfig(xkbcommon-x11) +Requires: pam-modules +BuildRoot: %{_tmppath}/%{name}-%{version}-build %description i3lock is a simple screen locker like slock. After starting it, you will see a @@ -69,36 +59,29 @@ Conflicts: xlockmore %description xlock-compat -This package provides a script /usr/bin/xlock which calls i3lock to lock your screen. +This package provides a script %{_bindir}/xlock which calls i3lock to lock your screen. This is handy for hard-coded screen-saver invocations e.g. in XFCE4, so you can use i3lock instead of xlock with them. %prep %setup -q -%patch1 -p1 %build export CFLAGS="%{optflags}" make %{?_smp_mflags} \ - USE_UNIX2_CHKPWD=1 \ PREFIX="%{_prefix}" \ SYSCONFDIR="%{_sysconfdir}" %install export CFLAGS="%{optflags}" make \ - USE_UNIX2_CHKPWD=1 \ PREFIX="%{_prefix}" \ SYSCONFDIR="%{_sysconfdir}" \ - DESTDIR="%{buildroot}" \ + DESTDIR=%{buildroot} \ install -rm "%{buildroot}%{_sysconfdir}/pam.d/i3lock" -install -m0644 "%{SOURCE1}" "%{buildroot}%{_sysconfdir}/pam.d/%{name}" - install -D -m0644 i3lock.1 "%{buildroot}%{_mandir}/man1/i3lock.1" - -install -D -m0644 %{SOURCE2} %{buildroot}/usr/share/i3lock-xlock-compat/i3lock-icon.png +install -D -m0644 %{SOURCE2} %{buildroot}%{_datadir}/i3lock-xlock-compat/i3lock-icon.png install -m0755 %{SOURCE3} %{buildroot}/%{_bindir}/xlock %files xlock-compat @@ -111,6 +94,6 @@ %doc CHANGELOG LICENSE README.md %config(noreplace) %{_sysconfdir}/pam.d/%{name} %{_bindir}/i3lock -%doc %{_mandir}/man1/i3lock.1* +%{_mandir}/man1/i3lock.1* %changelog ++++++ i3lock-2.8.tar.bz2 -> i3lock-2.9.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/CHANGELOG new/i3lock-2.9/CHANGELOG --- old/i3lock-2.8/CHANGELOG 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/CHANGELOG 2017-05-26 09:51:55.000000000 +0200 @@ -1,3 +1,21 @@ +2017-05-26 i3lock 2.9 + + • i3lock.1: use signal names without SIG prefix + • Removed obsolete inactivity timeout + • Added version files for release tarball. + • Set font face + • Automatically unlock (without having to press <Enter>) one attempt which was + entered while authenticating + • Stop leaking the image_path dup + • Displaying locking message when grabbing the pointer/keyboard + • Display error message when locking failed + • Add Enter on C-m + • Change input slices to be exactly pi/3 in size instead of slightly more + • Fix covering of composited notifications using the XComposite extension + • Remove last traces of DPMS + • Use bsd_auth(3) instead of PAM on OpenBSD + • Restore intended behaviour and don't use mlock(2) on OpenBSD. + 2016-06-04 i3lock 2.8 • Remove DPMS support in favor of a wrapper script and xset(1). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/Makefile new/i3lock-2.9/Makefile --- old/i3lock-2.8/Makefile 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/Makefile 2017-05-26 09:51:55.000000000 +0200 @@ -1,3 +1,6 @@ +TOPDIR=$(shell pwd) +UNAME=$(shell uname) + INSTALL=install PREFIX=/usr SYSCONFDIR=/etc @@ -12,18 +15,28 @@ CFLAGS += -pipe CFLAGS += -Wall CPPFLAGS += -D_GNU_SOURCE -CFLAGS += $(shell $(PKG_CONFIG) --cflags cairo xcb-dpms xcb-xinerama xcb-atom xcb-image xcb-xkb xkbcommon xkbcommon-x11) -LIBS += $(shell $(PKG_CONFIG) --libs cairo xcb-dpms xcb-xinerama xcb-atom xcb-image xcb-xkb xkbcommon xkbcommon-x11) -LIBS += -lpam +CFLAGS += $(shell $(PKG_CONFIG) --cflags cairo xcb-composite xcb-xinerama xcb-atom xcb-image xcb-xkb xkbcommon xkbcommon-x11) +LIBS += $(shell $(PKG_CONFIG) --libs cairo xcb-composite xcb-xinerama xcb-atom xcb-image xcb-xkb xkbcommon xkbcommon-x11) LIBS += -lev LIBS += -lm +# OpenBSD lacks PAM, use bsd_auth(3) instead. +ifneq ($(UNAME),OpenBSD) + LIBS += -lpam +endif + FILES:=$(wildcard *.c) FILES:=$(FILES:.c=.o) -VERSION:=2.8 -GIT_VERSION:="2.8 (2016-06-04)" -CPPFLAGS += -DVERSION=\"${GIT_VERSION}\" +ifeq ($(wildcard .git),) + # not in git repository + VERSION := $(shell [ -f $(TOPDIR)/I3LOCK_VERSION ] && cat $(TOPDIR)/I3LOCK_VERSION | cut -d '-' -f 1) + I3LOCK_VERSION := '$(shell [ -f $(TOPDIR)/I3LOCK_VERSION ] && cat $(TOPDIR)/I3LOCK_VERSION)' +else + VERSION:=$(shell git describe --tags --abbrev=0) + I3LOCK_VERSION:="$(shell git describe --tags --always) ($(shell git log --pretty=format:%cd --date=short -n1))" +endif +CPPFLAGS += -DVERSION=\"${I3LOCK_VERSION}\" .PHONY: install clean uninstall @@ -49,6 +62,6 @@ [ ! -e i3lock-${VERSION}.tar.bz2 ] || rm i3lock-${VERSION}.tar.bz2 mkdir i3lock-${VERSION} cp *.c *.h i3lock.1 i3lock.pam Makefile LICENSE README.md CHANGELOG i3lock-${VERSION} - sed -e 's/^GIT_VERSION:=\(.*\)/GIT_VERSION:=$(shell /bin/echo '${GIT_VERSION}' | sed 's/\\/\\\\/g')/g;s/^VERSION:=\(.*\)/VERSION:=${VERSION}/g' Makefile > i3lock-${VERSION}/Makefile + sed -e 's/^I3LOCK_VERSION:=\(.*\)/I3LOCK_VERSION:=$(shell /bin/echo '${I3LOCK_VERSION}' | sed 's/\\/\\\\/g')/g;s/^VERSION:=\(.*\)/VERSION:=${VERSION}/g' Makefile > i3lock-${VERSION}/Makefile tar cfj i3lock-${VERSION}.tar.bz2 i3lock-${VERSION} rm -rf i3lock-${VERSION} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/README.md new/i3lock-2.9/README.md --- old/i3lock-2.8/README.md 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/README.md 2017-05-26 09:51:55.000000000 +0200 @@ -16,6 +16,7 @@ - You can specify whether i3lock should bell upon a wrong password. - i3lock uses PAM and therefore is compatible with LDAP etc. + On OpenBSD i3lock uses the bsd_auth(3) framework. Requirements ------------ @@ -24,6 +25,7 @@ - libxcb-util - libpam-dev - libcairo-dev +- libxcb-composite0 - libxcb-xinerama - libev - libx11-dev @@ -36,6 +38,9 @@ Simply invoke the 'i3lock' command. To get out of it, enter your password and press enter. +On OpenBSD the `i3lock` binary needs to be setgid `auth` to call the +authentication helpers, e.g. `/usr/libexec/auth/login_passwd`. + Upstream -------- Please submit pull requests to https://github.com/i3/i3lock diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/i3lock.1 new/i3lock-2.9/i3lock.1 --- old/i3lock-2.8/i3lock.1 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/i3lock.1 2017-05-26 09:51:55.000000000 +0200 @@ -27,8 +27,6 @@ .IR pointer\|] .RB [\|\-u\|] .RB [\|\-e\|] -.RB [\|\-I -.IR timeout\|] .RB [\|\-f\|] .SH DESCRIPTION @@ -65,13 +63,6 @@ like when opening your laptop in a boring lecture. .TP -.BI \-I\ seconds \fR,\ \fB\-\-inactivity-timeout= seconds -Specifies the number of seconds i3lock will wait for another password before -turning off the monitors, in case you entered a wrong password or canceled by -pressing Escape. Only makes sense together with \-d. If omitted, the default is -30 seconds. - -.TP .B \-u, \-\-no-unlock-indicator Disable the unlock indicator. i3lock will by default show an unlock indicator after pressing keys. This will give feedback for every keypress and it will @@ -134,12 +125,14 @@ \& revert() { \& xset dpms 0 0 0 \& } -\& trap revert SIGHUP SIGINT SIGTERM +\& trap revert HUP INT TERM \& xset +dpms dpms 5 5 5 \& i3lock -n \& revert .Ve +The \-I (-\-inactivity-timeout=seconds) was removed because it only makes sense with DPMS. + .SH SEE ALSO .IR xautolock(1) \- use i3lock as your screen saver diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/i3lock.c new/i3lock-2.9/i3lock.c --- old/i3lock-2.8/i3lock.c 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/i3lock.c 2017-05-26 09:51:55.000000000 +0200 @@ -18,7 +18,11 @@ #include <xcb/xkb.h> #include <err.h> #include <assert.h> +#ifdef __OpenBSD__ +#include <bsd_auth.h> +#else #include <security/pam_appl.h> +#endif #include <getopt.h> #include <string.h> #include <ev.h> @@ -28,6 +32,9 @@ #include <xkbcommon/xkbcommon-x11.h> #include <cairo.h> #include <cairo/cairo-xcb.h> +#ifdef __OpenBSD__ +#include <strings.h> /* explicit_bzero(3) */ +#endif #include "i3lock.h" #include "xcb.h" @@ -43,13 +50,15 @@ timer_obj = stop_timer(timer_obj) typedef void (*ev_callback_t)(EV_P_ ev_timer *w, int revents); +static void input_done(void); char color[7] = "ffffff"; -int inactivity_timeout = 30; uint32_t last_resolution[2]; xcb_window_t win; static xcb_cursor_t cursor; +#ifndef __OpenBSD__ static pam_handle_t *pam_handle; +#endif int input_position = 0; /* Holds the password you enter (in UTF-8). */ static char password[512]; @@ -59,13 +68,14 @@ char *modifier_string = NULL; static bool dont_fork = false; struct ev_loop *main_loop; -static struct ev_timer *clear_pam_wrong_timeout; +static struct ev_timer *clear_auth_wrong_timeout; static struct ev_timer *clear_indicator_timeout; static struct ev_timer *discard_passwd_timeout; extern unlock_state_t unlock_state; -extern pam_state_t pam_state; +extern auth_state_t auth_state; int failed_attempts = 0; bool show_failed_attempts = false; +bool retry_verification = false; static struct xkb_state *xkb_state; static struct xkb_context *xkb_context; @@ -157,6 +167,11 @@ * */ static void clear_password_memory(void) { +#ifdef __OpenBSD__ + /* Use explicit_bzero(3) which was explicitly designed not to be + * optimized out by the compiler. */ + explicit_bzero(password, strlen(password)); +#else /* A volatile pointer to the password buffer to prevent the compiler from * optimizing this out. */ volatile char *vpassword = password; @@ -166,6 +181,7 @@ * compiler from optimizing the calls away, since the value of 'beep' * is not known at compile-time. */ vpassword[c] = c + (int)beep; +#endif } ev_timer *start_timer(ev_timer *timer_obj, ev_tstamp timeout, ev_callback_t callback) { @@ -194,13 +210,24 @@ } /* - * Resets pam_state to STATE_PAM_IDLE 2 seconds after an unsuccessful + * Neccessary calls after ending input via enter or others + * + */ +static void finish_input(void) { + password[input_position] = '\0'; + unlock_state = STATE_KEY_PRESSED; + redraw_screen(); + input_done(); +} + +/* + * Resets auth_state to STATE_AUTH_IDLE 2 seconds after an unsuccessful * authentication event. * */ -static void clear_pam_wrong(EV_P_ ev_timer *w, int revents) { - DEBUG("clearing pam wrong\n"); - pam_state = STATE_PAM_IDLE; +static void clear_auth_wrong(EV_P_ ev_timer *w, int revents) { + DEBUG("clearing auth wrong\n"); + auth_state = STATE_AUTH_IDLE; redraw_screen(); /* Clear modifier string. */ @@ -210,7 +237,13 @@ } /* Now free this timeout. */ - STOP_TIMER(clear_pam_wrong_timeout); + STOP_TIMER(clear_auth_wrong_timeout); + + /* retry with input done during auth verification */ + if (retry_verification) { + retry_verification = false; + finish_input(); + } } static void clear_indicator_cb(EV_P_ ev_timer *w, int revents) { @@ -230,11 +263,24 @@ } static void input_done(void) { - STOP_TIMER(clear_pam_wrong_timeout); - pam_state = STATE_PAM_VERIFY; + STOP_TIMER(clear_auth_wrong_timeout); + auth_state = STATE_AUTH_VERIFY; unlock_state = STATE_STARTED; redraw_screen(); +#ifdef __OpenBSD__ + struct passwd *pw; + + if (!(pw = getpwuid(getuid()))) + errx(1, "unknown uid %u.", getuid()); + + if (auth_userokay(pw->pw_name, NULL, NULL, password) != 0) { + DEBUG("successfully authenticated\n"); + clear_password_memory(); + + exit(0); + } +#else if (pam_authenticate(pam_handle, 0) == PAM_SUCCESS) { DEBUG("successfully authenticated\n"); clear_password_memory(); @@ -248,12 +294,13 @@ exit(0); } +#endif if (debug_mode) fprintf(stderr, "Authentication failure\n"); /* Get state of Caps and Num lock modifiers, to be displayed in - * STATE_PAM_WRONG state */ + * STATE_AUTH_WRONG state */ xkb_mod_index_t idx, num_mods; const char *mod_name; @@ -287,7 +334,7 @@ } } - pam_state = STATE_PAM_WRONG; + auth_state = STATE_AUTH_WRONG; failed_attempts += 1; clear_input(); if (unlock_indicator) @@ -296,7 +343,7 @@ /* Clear this state after 2 seconds (unless the user enters another * password during that time). */ ev_now_update(main_loop); - START_TIMER(clear_pam_wrong_timeout, TSTAMP_N_SECS(2), clear_pam_wrong); + START_TIMER(clear_auth_wrong_timeout, TSTAMP_N_SECS(2), clear_auth_wrong); /* Cancel the clear_indicator_timeout, it would hide the unlock indicator * too early. */ @@ -368,23 +415,23 @@ switch (ksym) { case XKB_KEY_j: + case XKB_KEY_m: case XKB_KEY_Return: case XKB_KEY_KP_Enter: case XKB_KEY_XF86ScreenSaver: - if (ksym == XKB_KEY_j && !ctrl) + if ((ksym == XKB_KEY_j || ksym == XKB_KEY_m) && !ctrl) break; - if (pam_state == STATE_PAM_WRONG) + if (auth_state == STATE_AUTH_WRONG) { + retry_verification = true; return; + } if (skip_without_validation()) { clear_input(); return; } - password[input_position] = '\0'; - unlock_state = STATE_KEY_PRESSED; - redraw_screen(); - input_done(); + finish_input(); skip_repeated_empty_password = true; return; default: @@ -579,6 +626,7 @@ redraw_screen(); } +#ifndef __OpenBSD__ /* * Callback function for PAM. We only react on password request callbacks. * @@ -609,6 +657,7 @@ return 0; } +#endif /* * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb. @@ -707,7 +756,7 @@ /* * This function is called from a fork()ed child and will raise the i3lock * window when the window is obscured, even when the main i3lock process is - * blocked due to PAM. + * blocked due to the authentication backend. * */ static void raise_loop(xcb_window_t window) { @@ -764,8 +813,10 @@ struct passwd *pw; char *username; char *image_path = NULL; +#ifndef __OpenBSD__ int ret; struct pam_conv conv = {conv_callback, NULL}; +#endif int curs_choice = CURS_NONE; int o; int optind = 0; @@ -806,10 +857,7 @@ fprintf(stderr, "DPMS support has been removed from i3lock. Please see the manpage i3lock(1).\n"); break; case 'I': { - int time = 0; - if (sscanf(optarg, "%d", &time) != 1 || time < 0) - errx(EXIT_FAILURE, "invalid timeout, it must be a positive integer\n"); - inactivity_timeout = time; + fprintf(stderr, "Inactivity timeout only makes sense with DPMS, which was removed. Please see the manpage i3lock(1).\n"); break; } case 'c': { @@ -862,16 +910,20 @@ * the unlock indicator upon keypresses. */ srand(time(NULL)); +#ifndef __OpenBSD__ /* Initialize PAM */ if ((ret = pam_start("i3lock", username, &conv, &pam_handle)) != PAM_SUCCESS) errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret)); if ((ret = pam_set_item(pam_handle, PAM_TTY, getenv("DISPLAY"))) != PAM_SUCCESS) errx(EXIT_FAILURE, "PAM: %s", pam_strerror(pam_handle, ret)); +#endif -/* Using mlock() as non-super-user seems only possible in Linux. Users of other - * operating systems should use encrypted swap/no swap (or remove the ifdef and - * run i3lock as super-user). */ +/* Using mlock() as non-super-user seems only possible in Linux. + * Users of other operating systems should use encrypted swap/no swap + * (or remove the ifdef and run i3lock as super-user). + * Alas, swap is encrypted by default on OpenBSD so swapping out + * is not necessarily an issue. */ #if defined(__linux__) /* Lock the area where we store the password in memory, we don’t want it to * be swapped to disk. Since Linux 2.6.9, this does not require any @@ -957,15 +1009,22 @@ image_path, cairo_status_to_string(cairo_surface_status(img))); img = NULL; } + free(image_path); } /* Pixmap on which the image is rendered to (if any) */ xcb_pixmap_t bg_pixmap = draw_image(last_resolution); - /* open the fullscreen window, already with the correct pixmap in place */ + /* Open the fullscreen window, already with the correct pixmap in place */ win = open_fullscreen_window(conn, screen, color, bg_pixmap); xcb_free_pixmap(conn, bg_pixmap); + cursor = create_cursor(conn, screen, win, curs_choice); + + /* Display the "locking…" message while trying to grab the pointer/keyboard. */ + auth_state = STATE_AUTH_LOCK; + grab_pointer_and_keyboard(conn, screen, cursor); + pid_t pid = fork(); /* The pid == -1 case is intentionally ignored here: * While the child process is useful for preventing other windows from @@ -978,9 +1037,6 @@ exit(EXIT_SUCCESS); } - cursor = create_cursor(conn, screen, win, curs_choice); - - grab_pointer_and_keyboard(conn, screen, cursor); /* Load the keymap again to sync the current modifier state. Since we first * loaded the keymap, there might have been changes, but starting from now, * we should get all key presses/releases due to having grabbed the @@ -992,6 +1048,10 @@ if (main_loop == NULL) errx(EXIT_FAILURE, "Could not initialize libev. Bad LIBEV_FLAGS?\n"); + /* Explicitly call the screen redraw in case "locking…" message was displayed */ + auth_state = STATE_AUTH_IDLE; + redraw_screen(); + struct ev_io *xcb_watcher = calloc(sizeof(struct ev_io), 1); struct ev_check *xcb_check = calloc(sizeof(struct ev_check), 1); struct ev_prepare *xcb_prepare = calloc(sizeof(struct ev_prepare), 1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/unlock_indicator.c new/i3lock-2.9/unlock_indicator.c --- old/i3lock-2.8/unlock_indicator.c 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/unlock_indicator.c 2017-05-26 09:51:55.000000000 +0200 @@ -78,7 +78,7 @@ /* Maintain the current unlock/PAM state to draw the appropriate unlock * indicator. */ unlock_state_t unlock_state; -pam_state_t pam_state; +auth_state_t auth_state; /* * Returns the scaling factor of the current screen. E.g., on a 227 DPI MacBook @@ -141,7 +141,7 @@ } if (unlock_indicator && - (unlock_state >= STATE_KEY_PRESSED || pam_state > STATE_PAM_IDLE)) { + (unlock_state >= STATE_KEY_PRESSED || auth_state > STATE_AUTH_IDLE)) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 10.0); @@ -154,11 +154,13 @@ /* Use the appropriate color for the different PAM states * (currently verifying, wrong password, or default) */ - switch (pam_state) { - case STATE_PAM_VERIFY: + switch (auth_state) { + case STATE_AUTH_VERIFY: + case STATE_AUTH_LOCK: cairo_set_source_rgba(ctx, 0, 114.0 / 255, 255.0 / 255, 0.75); break; - case STATE_PAM_WRONG: + case STATE_AUTH_WRONG: + case STATE_I3LOCK_LOCK_FAILED: cairo_set_source_rgba(ctx, 250.0 / 255, 0, 0, 0.75); break; default: @@ -167,14 +169,16 @@ } cairo_fill_preserve(ctx); - switch (pam_state) { - case STATE_PAM_VERIFY: + switch (auth_state) { + case STATE_AUTH_VERIFY: + case STATE_AUTH_LOCK: cairo_set_source_rgb(ctx, 51.0 / 255, 0, 250.0 / 255); break; - case STATE_PAM_WRONG: + case STATE_AUTH_WRONG: + case STATE_I3LOCK_LOCK_FAILED: cairo_set_source_rgb(ctx, 125.0 / 255, 51.0 / 255, 0); break; - case STATE_PAM_IDLE: + case STATE_AUTH_IDLE: cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0); break; } @@ -199,14 +203,21 @@ char buf[4]; cairo_set_source_rgb(ctx, 0, 0, 0); + cairo_select_font_face(ctx, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(ctx, 28.0); - switch (pam_state) { - case STATE_PAM_VERIFY: + switch (auth_state) { + case STATE_AUTH_VERIFY: text = "verifying…"; break; - case STATE_PAM_WRONG: + case STATE_AUTH_LOCK: + text = "locking…"; + break; + case STATE_AUTH_WRONG: text = "wrong!"; break; + case STATE_I3LOCK_LOCK_FAILED: + text = "lock failed!"; + break; default: if (show_failed_attempts && failed_attempts > 0) { if (failed_attempts > 999) { @@ -234,7 +245,7 @@ cairo_close_path(ctx); } - if (pam_state == STATE_PAM_WRONG && (modifier_string != NULL)) { + if (auth_state == STATE_AUTH_WRONG && (modifier_string != NULL)) { cairo_text_extents_t extents; double x, y; @@ -285,8 +296,8 @@ BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, - highlight_start + (M_PI / 3.0) /* start */, - (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); + (highlight_start + (M_PI / 3.0)) - (M_PI / 128.0) /* start */, + highlight_start + (M_PI / 3.0) /* end */); cairo_stroke(ctx); } } @@ -323,7 +334,7 @@ * */ void redraw_screen(void) { - DEBUG("redraw_screen(unlock_state = %d, pam_state = %d)\n", unlock_state, pam_state); + DEBUG("redraw_screen(unlock_state = %d, auth_state = %d)\n", unlock_state, auth_state); xcb_pixmap_t bg_pixmap = draw_image(last_resolution); xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){bg_pixmap}); /* XXX: Possible optimization: Only update the area in the middle of the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/unlock_indicator.h new/i3lock-2.9/unlock_indicator.h --- old/i3lock-2.8/unlock_indicator.h 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/unlock_indicator.h 2017-05-26 09:51:55.000000000 +0200 @@ -11,10 +11,12 @@ } unlock_state_t; typedef enum { - STATE_PAM_IDLE = 0, /* no PAM interaction at the moment */ - STATE_PAM_VERIFY = 1, /* currently verifying the password via PAM */ - STATE_PAM_WRONG = 2 /* the password was wrong */ -} pam_state_t; + STATE_AUTH_IDLE = 0, /* no authenticator interaction at the moment */ + STATE_AUTH_VERIFY = 1, /* currently verifying the password via authenticator */ + STATE_AUTH_LOCK = 2, /* currently locking the screen */ + STATE_AUTH_WRONG = 3, /* the password was wrong */ + STATE_I3LOCK_LOCK_FAILED = 4 /* i3lock failed to load */ +} auth_state_t; xcb_pixmap_t draw_image(uint32_t* resolution); void redraw_screen(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/xcb.c new/i3lock-2.9/xcb.c --- old/i3lock-2.8/xcb.c 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/xcb.c 2017-05-26 09:51:55.000000000 +0200 @@ -11,6 +11,7 @@ #include <xcb/xcb_image.h> #include <xcb/xcb_atom.h> #include <xcb/xcb_aux.h> +#include <xcb/composite.h> #include <stdio.h> #include <stdlib.h> #include <stdbool.h> @@ -18,8 +19,12 @@ #include <unistd.h> #include <assert.h> #include <err.h> +#include <time.h> #include "cursors.h" +#include "unlock_indicator.h" + +extern auth_state_t auth_state; xcb_connection_t *conn; xcb_screen_t *screen; @@ -102,6 +107,29 @@ uint32_t mask = 0; uint32_t values[3]; xcb_window_t win = xcb_generate_id(conn); + xcb_window_t parent_win = scr->root; + + /* Check whether the composite extension is available */ + const xcb_query_extension_reply_t *extension_query = NULL; + xcb_generic_error_t *error = NULL; + xcb_composite_get_overlay_window_cookie_t cookie; + xcb_composite_get_overlay_window_reply_t *composite_reply = NULL; + + extension_query = xcb_get_extension_data(conn, &xcb_composite_id); + if (extension_query && extension_query->present) { + /* When composition is used, we need to use the composite overlay + * window instead of the normal root window to be able to cover + * composited windows */ + cookie = xcb_composite_get_overlay_window(conn, scr->root); + composite_reply = xcb_composite_get_overlay_window_reply(conn, cookie, &error); + + if (!error && composite_reply) { + parent_win = composite_reply->overlay_win; + } + + free(composite_reply); + free(error); + } if (pixmap == XCB_NONE) { mask |= XCB_CW_BACK_PIXEL; @@ -123,8 +151,8 @@ xcb_create_window(conn, XCB_COPY_FROM_PARENT, - win, /* the window id */ - scr->root, /* parent == root */ + win, /* the window id */ + parent_win, 0, 0, scr->width_in_pixels, scr->height_in_pixels, /* dimensions */ @@ -158,7 +186,7 @@ } /* - * Repeatedly tries to grab pointer and keyboard (up to 1000 times). + * Repeatedly tries to grab pointer and keyboard (up to 10000 times). * */ void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor) { @@ -170,6 +198,10 @@ int tries = 10000; + /* Using few variables to trigger a redraw_screen() if too many tries */ + bool redrawn = false; + time_t start = clock(); + while (tries-- > 0) { pcookie = xcb_grab_pointer( conn, @@ -190,6 +222,14 @@ /* Make this quite a bit slower */ usleep(50); + + /* Measure elapsed time and trigger a screen redraw if elapsed > 250000 */ + if (!redrawn && + (tries % 100) == 0 && + (clock() - start) > 250000) { + redraw_screen(); + redrawn = true; + } } while (tries-- > 0) { @@ -209,10 +249,24 @@ /* Make this quite a bit slower */ usleep(50); + + /* Measure elapsed time and trigger a screen redraw if elapsed > 250000 */ + if (!redrawn && + (tries % 100) == 0 && + (clock() - start) > 250000) { + redraw_screen(); + redrawn = true; + } } - if (tries <= 0) + /* After trying for 10000 times, i3lock will display an error message + * for 2 sec prior to terminate. */ + if (tries <= 0) { + auth_state = STATE_I3LOCK_LOCK_FAILED; + redraw_screen(); + sleep(1); errx(EXIT_FAILURE, "Cannot grab pointer/keyboard"); + } } xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/i3lock-2.8/xcb.h new/i3lock-2.9/xcb.h --- old/i3lock-2.8/xcb.h 2016-06-04 19:27:15.000000000 +0200 +++ new/i3lock-2.9/xcb.h 2017-05-26 09:51:55.000000000 +0200 @@ -2,7 +2,6 @@ #define _XCB_H #include <xcb/xcb.h> -#include <xcb/dpms.h> extern xcb_connection_t *conn; extern xcb_screen_t *screen; @@ -11,7 +10,6 @@ xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, u_int32_t *resolution, char *color); xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, char *color, xcb_pixmap_t pixmap); void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor); -void dpms_set_mode(xcb_connection_t *conn, xcb_dpms_dpms_mode_t mode); xcb_cursor_t create_cursor(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win, int choice); #endif