Hello community,

here is the log from the commit of package i3lock for openSUSE:Factory checked 
in at 2016-04-30 23:31:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/i3lock (Old)
 and      /work/SRC/openSUSE:Factory/.i3lock.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "i3lock"

Changes:
--------
--- /work/SRC/openSUSE:Factory/i3lock/i3lock.changes    2015-05-15 
07:43:30.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.i3lock.new/i3lock.changes       2016-04-30 
23:31:16.000000000 +0200
@@ -1,0 +2,18 @@
+Tue Apr 26 12:25:06 UTC 2016 - mimi...@gmail.com
+
+- update to 2.7
+- refresh i3lock-2.5-use-unix2_chkpwd.diff 
+* Die when the X11 connection breaks during runtime
+* Implement logging the number of failed attempts
+* Ignore password validation is pam is in wrong state
+* Get current user with getpwuid() instead of using $ENV{USER}
+* Add support for Compose and dead-keys with libxkbcommon.
+   Requires libxkbcommon ≥ 0.5.0
+* Format the source using clang-format.
+* Refresh pam credentials on successful authentication (for Kerberos and the
+   like)
+* List pressed modifiers on failed authentication
+* Only redraw the screen if the unlock indicator is actually used
+* Make pkg-config configurable for cross-compilation
+
+-------------------------------------------------------------------

Old:
----
  i3lock-2.6.tar.bz2

New:
----
  i3lock-2.7.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ i3lock.spec ++++++
--- /var/tmp/diff_new_pack.0YQZ2A/_old  2016-04-30 23:31:17.000000000 +0200
+++ /var/tmp/diff_new_pack.0YQZ2A/_new  2016-04-30 23:31:17.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package i3lock
 #
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
 # Copyright (c) 2014 B1 Systems GmbH, Vohburg, Germany.
 # Copyright (c) 2012 Pascal Bleser <pascal.ble...@opensuse.org>
 #
@@ -21,7 +21,7 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 
 Name:           i3lock
-Version:        2.6
+Version:        2.7
 Release:        0
 Summary:        Screen Locker for the i3 Window Manager
 License:        BSD-3-Clause
@@ -54,7 +54,7 @@
 BuildRequires:  pam-modules
 BuildRequires:  pkgconfig(xcb-image)
 BuildRequires:  pkgconfig(xcb-keysyms)
-BuildRequires:  pkgconfig(xkbcommon)
+BuildRequires:  pkgconfig(xkbcommon) >= 0.5.0
 
 %description
 i3lock is a simple screen locker like slock. After starting it, you will see a
@@ -62,7 +62,7 @@
 screen by entering your password.
 
 %package xlock-compat
-Summary:        xlock-compatibility script which calls i3lock
+Summary:        Xlock-compatibility script which calls i3lock
 Group:          System/GUI/Other
 Requires:       ImageMagick
 Requires:       xdpyinfo
@@ -108,7 +108,7 @@
 
 %files
 %defattr(-,root,root)
-%doc CHANGELOG LICENSE README
+%doc CHANGELOG LICENSE README.md
 %config(noreplace) %{_sysconfdir}/pam.d/%{name}
 %{_bindir}/i3lock
 %doc %{_mandir}/man1/i3lock.1*

++++++ i3lock-2.5-use-unix2_chkpwd.diff ++++++
--- /var/tmp/diff_new_pack.0YQZ2A/_old  2016-04-30 23:31:17.000000000 +0200
+++ /var/tmp/diff_new_pack.0YQZ2A/_new  2016-04-30 23:31:17.000000000 +0200
@@ -3,14 +3,14 @@
 
     add the option to use unix2_chkpwd instead of needing setgid shadow
 
-diff --git a/Makefile b/Makefile
-index 2633bef..27a471b 100644
---- a/Makefile
-+++ b/Makefile
-@@ -13,7 +13,11 @@
+Index: i3lock-2.7/Makefile
+===================================================================
+--- i3lock-2.7.orig/Makefile
++++ i3lock-2.7/Makefile
+@@ -14,7 +14,11 @@ 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)
+ 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)
 +ifeq ($(USE_UNIX2_CHKPWD),1)
 +CFLAGS += -DUSE_UNIX2_CHKPWD=1
 +else
@@ -19,11 +19,11 @@
  LIBS += -lev
  LIBS += -lm
  
-diff --git a/i3lock.c b/i3lock.c
-index 5a87999..70842c6 100644
---- a/i3lock.c
-+++ b/i3lock.c
-@@ -17,7 +17,9 @@
+Index: i3lock-2.7/i3lock.c
+===================================================================
+--- i3lock-2.7.orig/i3lock.c
++++ i3lock-2.7/i3lock.c
+@@ -19,7 +19,9 @@
  #include <xcb/dpms.h>
  #include <err.h>
  #include <assert.h>
@@ -33,7 +33,7 @@
  #include <getopt.h>
  #include <string.h>
  #include <ev.h>
-@@ -28,6 +30,13 @@
+@@ -30,6 +32,13 @@
  #include <cairo.h>
  #include <cairo/cairo-xcb.h>
  
@@ -47,7 +47,7 @@
  #include "i3lock.h"
  #include "xcb.h"
  #include "cursors.h"
-@@ -40,7 +49,9 @@ char color[7] = "ffffff";
+@@ -51,7 +60,9 @@ int inactivity_timeout = 30;
  uint32_t last_resolution[2];
  xcb_window_t win;
  static xcb_cursor_t cursor;
@@ -57,7 +57,7 @@
  int input_position = 0;
  /* Holds the password you enter (in UTF-8). */
  static char password[512];
-@@ -226,6 +228,62 @@
+@@ -266,6 +277,62 @@ static void input_done(void) {
      pam_state = STATE_PAM_VERIFY;
      redraw_screen();
  
@@ -120,8 +120,8 @@
      if (pam_authenticate(pam_handle, 0) == PAM_SUCCESS) {
          DEBUG("successfully authenticated\n");
          clear_password_memory();
-@@ -234,7 +292,7 @@
-         turn_monitors_on();
+@@ -282,7 +349,7 @@ static void input_done(void) {
+ 
          exit(0);
      }
 -
@@ -129,7 +129,7 @@
      if (debug_mode)
          fprintf(stderr, "Authentication failure\n");
  
-@@ -398,6 +466,7 @@ void handle_screen_resize(void) {
+@@ -591,6 +658,7 @@ void handle_screen_resize(void) {
      redraw_screen();
  }
  
@@ -137,7 +137,7 @@
  /*
   * Callback function for PAM. We only react on password request callbacks.
   *
-@@ -429,6 +498,7 @@ static int conv_callback(int num_msg, const struct 
pam_message **msg,
+@@ -621,6 +689,7 @@ static int conv_callback(int num_msg, co
  
      return 0;
  }
@@ -145,8 +145,8 @@
  
  /*
   * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb.
-@@ -516,8 +586,10 @@ static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
- int main(int argc, char *argv[]) {
+@@ -768,8 +837,10 @@ int main(int argc, char *argv[]) {
+     struct passwd *pw;
      char *username;
      char *image_path = NULL;
 +#ifndef USE_UNIX2_CHKPWD
@@ -156,7 +156,7 @@
      int curs_choice = CURS_NONE;
      int o;
      int optind = 0;
-@@ -597,10 +669,12 @@ int main(int argc, char *argv[]) {
+@@ -866,10 +937,12 @@ int main(int argc, char *argv[]) {
       * the unlock indicator upon keypresses. */
      srand(time(NULL));
  

++++++ i3lock-2.6.tar.bz2 -> i3lock-2.7.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/CHANGELOG new/i3lock-2.7/CHANGELOG
--- old/i3lock-2.6/CHANGELOG    2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/CHANGELOG    2015-05-20 09:17:06.000000000 +0200
@@ -1,3 +1,19 @@
+2015-05-20 i3lock 2.7
+
+ • Die when the X11 connection breaks during runtime (Thanks Eduan)
+ • Implement logging the number of failed attempts (Thanks koebi)
+ • Ignore password validation is pam is in wrong state (Thanks Neodyblue)
+ • Get current user with getpwuid() instead of using $ENV{USER} (Thanks Martin)
+ • Add support for Compose and dead-keys with libxkbcommon.
+   Requires libxkbcommon ≥ 0.5.0 (Thanks Daniel)
+ • Format the source using clang-format.
+ • Refresh pam credentials on successful authentication (for Kerberos and the
+   like) (Thanks James)
+ • List pressed modifiers on failed authentication (Thanks Deiz, Alexandre)
+ • Only redraw the screen if the unlock indicator is actually used
+   (Thanks Ingo)
+ • Make pkg-config configurable for cross-compilation (Thanks Nikolay)
+
 2014-07-18 i3lock 2.6
 
  • NEW DEPENDENCY: use libxkbcommon-x11 instead of libX11
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/Makefile new/i3lock-2.7/Makefile
--- old/i3lock-2.6/Makefile     2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/Makefile     2015-05-20 09:17:06.000000000 +0200
@@ -1,18 +1,19 @@
 INSTALL=install
 PREFIX=/usr
 SYSCONFDIR=/etc
+PKG_CONFIG=pkg-config
 
 # Check if pkg-config is installed, we need it for building CFLAGS/LIBS
-ifeq ($(shell which pkg-config 2>/dev/null 1>/dev/null || echo 1),1)
-$(error "pkg-config was not found")
+ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null 1>/dev/null || echo 1),1)
+$(error "$(PKG_CONFIG) was not found")
 endif
 
 CFLAGS += -std=c99
 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)
+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
 LIBS += -lev
 LIBS += -lm
@@ -20,8 +21,8 @@
 FILES:=$(wildcard *.c)
 FILES:=$(FILES:.c=.o)
 
-VERSION:=2.6
-GIT_VERSION:="2.6 (2014-07-18)"
+VERSION:=2.7
+GIT_VERSION:="2.7 (2015-05-20)"
 CPPFLAGS += -DVERSION=\"${GIT_VERSION}\"
 
 .PHONY: install clean uninstall
@@ -47,7 +48,7 @@
        [ ! -d i3lock-${VERSION} ] || rm -rf i3lock-${VERSION}
        [ ! -e i3lock-${VERSION}.tar.bz2 ] || rm i3lock-${VERSION}.tar.bz2
        mkdir i3lock-${VERSION}
-       cp *.c *.h i3lock.1 i3lock.pam Makefile LICENSE README CHANGELOG 
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
        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.6/README new/i3lock-2.7/README
--- old/i3lock-2.6/README       2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/README       1970-01-01 01:00:00.000000000 +0100
@@ -1,42 +0,0 @@
-i3lock - improved screen locker
-===============================
-i3lock is a simple screen locker like slock. After starting it, you will
-see a white screen (you can configure the color/an image). You can return
-to your screen by entering your password.
-
-Many little improvements have been made to i3lock over time:
-
-- i3lock forks, so you can combine it with an alias to suspend to RAM
-  (run "i3lock && echo mem > /sys/power/state" to get a locked screen
-   after waking up your computer from suspend to RAM)
-
-- You can specify either a background color or a PNG image which will be
-  displayed while your screen is locked.
-
-- You can specify whether i3lock should bell upon a wrong password.
-
-- i3lock uses PAM and therefore is compatible with LDAP etc.
-
-Requirements
-------------
-- pkg-config
-- libxcb
-- libxcb-util
-- libpam-dev
-- libcairo-dev
-- libxcb-xinerama
-- libev
-- libx11-dev
-- libx11-xcb-dev
-- libxkbfile-dev
-- libxkbcommon >= 0.4.0
-- libxkbcommon-x11 >= 0.4.0
-
-Running i3lock
--------------
-Simply invoke the 'i3lock' command. To get out of it, enter your password and
-press enter.
-
-Upstream
---------
-Please submit patches to http://cr.i3wm.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/README.md new/i3lock-2.7/README.md
--- old/i3lock-2.6/README.md    1970-01-01 01:00:00.000000000 +0100
+++ new/i3lock-2.7/README.md    2015-05-20 09:17:06.000000000 +0200
@@ -0,0 +1,42 @@
+i3lock - improved screen locker
+===============================
+i3lock is a simple screen locker like slock. After starting it, you will
+see a white screen (you can configure the color/an image). You can return
+to your screen by entering your password.
+
+Many little improvements have been made to i3lock over time:
+
+- i3lock forks, so you can combine it with an alias to suspend to RAM
+  (run "i3lock && echo mem > /sys/power/state" to get a locked screen
+   after waking up your computer from suspend to RAM)
+
+- You can specify either a background color or a PNG image which will be
+  displayed while your screen is locked.
+
+- You can specify whether i3lock should bell upon a wrong password.
+
+- i3lock uses PAM and therefore is compatible with LDAP etc.
+
+Requirements
+------------
+- pkg-config
+- libxcb
+- libxcb-util
+- libpam-dev
+- libcairo-dev
+- libxcb-xinerama
+- libev
+- libx11-dev
+- libx11-xcb-dev
+- libxkbfile-dev
+- libxkbcommon >= 0.5.0
+- libxkbcommon-x11 >= 0.5.0
+
+Running i3lock
+-------------
+Simply invoke the 'i3lock' command. To get out of it, enter your password and
+press enter.
+
+Upstream
+--------
+Please submit pull requests to https://github.com/i3/i3lock
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/cursors.h new/i3lock-2.7/cursors.h
--- old/i3lock-2.6/cursors.h    2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/cursors.h    2015-05-20 09:17:06.000000000 +0200
@@ -1,8 +1,8 @@
 #ifndef _CURSORS_H
 #define _CURSORS_H
 
-#define CURS_NONE    0
-#define CURS_WIN     1
+#define CURS_NONE 0
+#define CURS_WIN 1
 #define CURS_DEFAULT 2
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/i3lock.1 new/i3lock-2.7/i3lock.1
--- old/i3lock-2.6/i3lock.1     2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/i3lock.1     2015-05-20 09:17:06.000000000 +0200
@@ -29,6 +29,7 @@
 .RB [\|\-u\|]
 .RB [\|\-e\|]
 .RB [\|\-I\|]
+.RB [\|\-f\|]
 
 .SH DESCRIPTION
 .B i3lock
@@ -115,6 +116,15 @@
 put a laptop to sleep and bounce on resume or if you happen to wake up
 your computer with the enter key.
 
+.TP
+.B \-f, \-\-show-failed-attempts
+Show the number of failed attempts, if any.
+
+.TP
+.B \-\-debug
+Enables debug logging.
+Note, that this will log the password used for authentication to stdout.
+
 .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.6/i3lock.c new/i3lock-2.7/i3lock.c
--- old/i3lock-2.6/i3lock.c     2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/i3lock.c     2015-05-20 09:17:06.000000000 +0200
@@ -1,13 +1,15 @@
 /*
  * vim:ts=4:sw=4:expandtab
  *
- * © 2010-2013 Michael Stapelberg
+ * © 2010 Michael Stapelberg
  *
  * See LICENSE for licensing information
  *
  */
 #include <stdio.h>
 #include <stdlib.h>
+#include <pwd.h>
+#include <sys/types.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdbool.h>
@@ -23,6 +25,7 @@
 #include <ev.h>
 #include <sys/mman.h>
 #include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-compose.h>
 #include <xkbcommon/xkbcommon-x11.h>
 #include <cairo.h>
 #include <cairo/cairo-xcb.h>
@@ -56,6 +59,7 @@
 bool debug_mode = false;
 static bool dpms = false;
 bool unlock_indicator = true;
+char *modifier_string = NULL;
 static bool dont_fork = false;
 struct ev_loop *main_loop;
 static struct ev_timer *clear_pam_wrong_timeout;
@@ -64,10 +68,14 @@
 static struct ev_timer *discard_passwd_timeout;
 extern unlock_state_t unlock_state;
 extern pam_state_t pam_state;
+int failed_attempts = 0;
+bool show_failed_attempts = false;
 
 static struct xkb_state *xkb_state;
 static struct xkb_context *xkb_context;
 static struct xkb_keymap *xkb_keymap;
+static struct xkb_compose_table *xkb_compose_table;
+static struct xkb_compose_state *xkb_compose_state;
 static uint8_t xkb_base_event;
 static uint8_t xkb_base_error;
 
@@ -77,7 +85,7 @@
 bool skip_repeated_empty_password = false;
 
 /* isutf, u8_dec © 2005 Jeff Bezanson, public domain */
-#define isutf(c) (((c) & 0xC0) != 0x80)
+#define isutf(c) (((c)&0xC0) != 0x80)
 
 /*
  * Decrements i to point to the previous unicode glyph
@@ -134,6 +142,30 @@
 }
 
 /*
+ * Loads the XKB compose table from the given locale.
+ *
+ */
+static bool load_compose_table(const char *locale) {
+    xkb_compose_table_unref(xkb_compose_table);
+
+    if ((xkb_compose_table = xkb_compose_table_new_from_locale(xkb_context, 
locale, 0)) == NULL) {
+        fprintf(stderr, "[i3lock] xkb_compose_table_new_from_locale failed\n");
+        return false;
+    }
+
+    struct xkb_compose_state *new_compose_state = 
xkb_compose_state_new(xkb_compose_table, 0);
+    if (new_compose_state == NULL) {
+        fprintf(stderr, "[i3lock] xkb_compose_state_new failed\n");
+        return false;
+    }
+
+    xkb_compose_state_unref(xkb_compose_state);
+    xkb_compose_state = new_compose_state;
+
+    return true;
+}
+
+/*
  * Clears the memory which stored the password to be a bit safer against
  * cold-boot attacks.
  *
@@ -150,7 +182,7 @@
         vpassword[c] = c + (int)beep;
 }
 
-ev_timer* start_timer(ev_timer *timer_obj, ev_tstamp timeout, ev_callback_t 
callback) {
+ev_timer *start_timer(ev_timer *timer_obj, ev_tstamp timeout, ev_callback_t 
callback) {
     if (timer_obj) {
         ev_timer_stop(main_loop, timer_obj);
         ev_timer_set(timer_obj, timeout, 0.);
@@ -167,7 +199,7 @@
     return timer_obj;
 }
 
-ev_timer* stop_timer(ev_timer *timer_obj) {
+ev_timer *stop_timer(ev_timer *timer_obj) {
     if (timer_obj) {
         ev_timer_stop(main_loop, timer_obj);
         free(timer_obj);
@@ -186,6 +218,12 @@
     unlock_state = STATE_STARTED;
     redraw_screen();
 
+    /* Clear modifier string. */
+    if (modifier_string != NULL) {
+        free(modifier_string);
+        modifier_string = NULL;
+    }
+
     /* Now free this timeout. */
     STOP_TIMER(clear_pam_wrong_timeout);
 }
@@ -202,10 +240,12 @@
 
     /* Hide the unlock indicator after a bit if the password buffer is
      * empty. */
-    START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
-    unlock_state = STATE_BACKSPACE_ACTIVE;
-    redraw_screen();
-    unlock_state = STATE_KEY_PRESSED;
+    if (unlock_indicator) {
+        START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
+        unlock_state = STATE_BACKSPACE_ACTIVE;
+        redraw_screen();
+        unlock_state = STATE_KEY_PRESSED;
+    }
 }
 
 static void turn_off_monitors_cb(EV_P_ ev_timer *w, int revents) {
@@ -232,15 +272,60 @@
         /* Turn the screen on, as it may have been turned off
          * on release of the 'enter' key. */
         turn_monitors_on();
+
+        /* PAM credentials should be refreshed, this will for example update 
any kerberos tickets.
+         * Related to credentials pam_end() needs to be called to cleanup any 
temporary
+         * credentials like kerberos /tmp/krb5cc_pam_* files which may of been 
left behind if the
+         * refresh of the credentials failed. */
+        pam_setcred(pam_handle, PAM_REFRESH_CRED);
+        pam_end(pam_handle, PAM_SUCCESS);
+
         exit(0);
     }
 
     if (debug_mode)
         fprintf(stderr, "Authentication failure\n");
 
+    /* Get state of Caps and Num lock modifiers, to be displayed in
+     * STATE_PAM_WRONG state */
+    xkb_mod_index_t idx, num_mods;
+    const char *mod_name;
+
+    num_mods = xkb_keymap_num_mods(xkb_keymap);
+
+    for (idx = 0; idx < num_mods; idx++) {
+        if (!xkb_state_mod_index_is_active(xkb_state, idx, 
XKB_STATE_MODS_EFFECTIVE))
+            continue;
+
+        mod_name = xkb_keymap_mod_get_name(xkb_keymap, idx);
+        if (mod_name == NULL)
+            continue;
+
+        /* Replace certain xkb names with nicer, human-readable ones. */
+        if (strcmp(mod_name, XKB_MOD_NAME_CAPS) == 0)
+            mod_name = "Caps Lock";
+        else if (strcmp(mod_name, XKB_MOD_NAME_ALT) == 0)
+            mod_name = "Alt";
+        else if (strcmp(mod_name, XKB_MOD_NAME_NUM) == 0)
+            mod_name = "Num Lock";
+        else if (strcmp(mod_name, XKB_MOD_NAME_LOGO) == 0)
+            mod_name = "Win";
+
+        char *tmp;
+        if (modifier_string == NULL) {
+            if (asprintf(&tmp, "%s", mod_name) != -1)
+                modifier_string = tmp;
+        } else if (asprintf(&tmp, "%s, %s", modifier_string, mod_name) != -1) {
+            free(modifier_string);
+            modifier_string = tmp;
+        }
+    }
+
     pam_state = STATE_PAM_WRONG;
+    failed_attempts += 1;
     clear_input();
-    redraw_screen();
+    if (unlock_indicator)
+        redraw_screen();
 
     /* Clear this state after 2 seconds (unless the user enters another
      * password during that time). */
@@ -284,60 +369,86 @@
     char buffer[128];
     int n;
     bool ctrl;
+    bool composed = false;
 
     ksym = xkb_state_key_get_one_sym(xkb_state, event->detail);
-    ctrl = xkb_state_mod_name_is_active(xkb_state, "Control", 
XKB_STATE_MODS_DEPRESSED);
+    ctrl = xkb_state_mod_name_is_active(xkb_state, XKB_MOD_NAME_CTRL, 
XKB_STATE_MODS_DEPRESSED);
 
     /* The buffer will be null-terminated, so n >= 2 for 1 actual character. */
     memset(buffer, '\0', sizeof(buffer));
-    n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));
 
-    switch (ksym) {
-    case XKB_KEY_Return:
-    case XKB_KEY_KP_Enter:
-    case XKB_KEY_XF86ScreenSaver:
-        if (skip_without_validation()) {
-            clear_input();
-            return;
+    if (xkb_compose_state && xkb_compose_state_feed(xkb_compose_state, ksym) 
== XKB_COMPOSE_FEED_ACCEPTED) {
+        switch (xkb_compose_state_get_status(xkb_compose_state)) {
+            case XKB_COMPOSE_NOTHING:
+                break;
+            case XKB_COMPOSE_COMPOSING:
+                return;
+            case XKB_COMPOSE_COMPOSED:
+                /* xkb_compose_state_get_utf8 doesn't include the terminating 
byte in the return value
+             * as xkb_keysym_to_utf8 does. Adding one makes the variable n 
consistent. */
+                n = xkb_compose_state_get_utf8(xkb_compose_state, buffer, 
sizeof(buffer)) + 1;
+                ksym = xkb_compose_state_get_one_sym(xkb_compose_state);
+                composed = true;
+                break;
+            case XKB_COMPOSE_CANCELLED:
+                xkb_compose_state_reset(xkb_compose_state);
+                return;
         }
-        password[input_position] = '\0';
-        unlock_state = STATE_KEY_PRESSED;
-        redraw_screen();
-        input_done();
-        skip_repeated_empty_password = true;
-        return;
-    default:
-        skip_repeated_empty_password = false;
+    }
+
+    if (!composed) {
+        n = xkb_keysym_to_utf8(ksym, buffer, sizeof(buffer));
     }
 
     switch (ksym) {
-    case XKB_KEY_u:
-        if (ctrl) {
-            DEBUG("C-u pressed\n");
-            clear_input();
+        case XKB_KEY_Return:
+        case XKB_KEY_KP_Enter:
+        case XKB_KEY_XF86ScreenSaver:
+            if (pam_state == STATE_PAM_WRONG)
+                return;
+
+            if (skip_without_validation()) {
+                clear_input();
+                return;
+            }
+            password[input_position] = '\0';
+            unlock_state = STATE_KEY_PRESSED;
+            redraw_screen();
+            input_done();
+            skip_repeated_empty_password = true;
             return;
-        }
-        break;
+        default:
+            skip_repeated_empty_password = false;
+    }
 
-    case XKB_KEY_Escape:
-        clear_input();
-        return;
+    switch (ksym) {
+        case XKB_KEY_u:
+            if (ctrl) {
+                DEBUG("C-u pressed\n");
+                clear_input();
+                return;
+            }
+            break;
 
-    case XKB_KEY_BackSpace:
-        if (input_position == 0)
+        case XKB_KEY_Escape:
+            clear_input();
             return;
 
-        /* decrement input_position to point to the previous glyph */
-        u8_dec(password, &input_position);
-        password[input_position] = '\0';
+        case XKB_KEY_BackSpace:
+            if (input_position == 0)
+                return;
+
+            /* decrement input_position to point to the previous glyph */
+            u8_dec(password, &input_position);
+            password[input_position] = '\0';
 
-        /* Hide the unlock indicator after a bit if the password buffer is
+            /* Hide the unlock indicator after a bit if the password buffer is
          * empty. */
-        START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
-        unlock_state = STATE_BACKSPACE_ACTIVE;
-        redraw_screen();
-        unlock_state = STATE_KEY_PRESSED;
-        return;
+            START_TIMER(clear_indicator_timeout, 1.0, clear_indicator_cb);
+            unlock_state = STATE_BACKSPACE_ACTIVE;
+            redraw_screen();
+            unlock_state = STATE_KEY_PRESSED;
+            return;
     }
 
     if ((input_position + 8) >= sizeof(password))
@@ -358,17 +469,20 @@
         return;
 
     /* store it in the password array as UTF-8 */
-    memcpy(password+input_position, buffer, n-1);
-    input_position += n-1;
+    memcpy(password + input_position, buffer, n - 1);
+    input_position += n - 1;
     DEBUG("current password = %.*s\n", input_position, password);
 
-    unlock_state = STATE_KEY_ACTIVE;
-    redraw_screen();
-    unlock_state = STATE_KEY_PRESSED;
+    if (unlock_indicator) {
+        unlock_state = STATE_KEY_ACTIVE;
+        redraw_screen();
+        unlock_state = STATE_KEY_PRESSED;
+
+        struct ev_timer *timeout = NULL;
+        START_TIMER(timeout, TSTAMP_N_SECS(0.25), redraw_timeout);
+        STOP_TIMER(clear_indicator_timeout);
+    }
 
-    struct ev_timer *timeout = NULL;
-    START_TIMER(timeout, TSTAMP_N_SECS(0.25), redraw_timeout);
-    STOP_TIMER(clear_indicator_timeout);
     START_TIMER(discard_passwd_timeout, TSTAMP_N_MINS(3), discard_passwd_cb);
 }
 
@@ -382,9 +496,9 @@
  *
  */
 static void handle_visibility_notify(xcb_connection_t *conn,
-    xcb_visibility_notify_event_t *event) {
+                                     xcb_visibility_notify_event_t *event) {
     if (event->state != XCB_VISIBILITY_UNOBSCURED) {
-        uint32_t values[] = { XCB_STACK_MODE_ABOVE };
+        uint32_t values[] = {XCB_STACK_MODE_ABOVE};
         xcb_configure_window(conn, event->window, 
XCB_CONFIG_WINDOW_STACK_MODE, values);
         xcb_flush(conn);
     }
@@ -409,7 +523,7 @@
         xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify;
         xcb_xkb_map_notify_event_t map_notify;
         xcb_xkb_state_notify_event_t state_notify;
-    } *event = (union xkb_event*)gevent;
+    } *event = (union xkb_event *)gevent;
 
     DEBUG("process_xkb_event for device %d\n", event->any.deviceID);
 
@@ -482,8 +596,7 @@
  *
  */
 static int conv_callback(int num_msg, const struct pam_message **msg,
-                         struct pam_response **resp, void *appdata_ptr)
-{
+                         struct pam_response **resp, void *appdata_ptr) {
     if (num_msg == 0)
         return 1;
 
@@ -534,9 +647,12 @@
 static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
     xcb_generic_event_t *event;
 
+    if (xcb_connection_has_error(conn))
+        errx(EXIT_FAILURE, "X11 connection broke, did your server 
terminate?\n");
+
     while ((event = xcb_poll_for_event(conn)) != NULL) {
         if (event->response_type == 0) {
-            xcb_generic_error_t *error = (xcb_generic_error_t*)event;
+            xcb_generic_error_t *error = (xcb_generic_error_t *)event;
             if (debug_mode)
                 fprintf(stderr, "X11 Error received! sequence 0x%x, error_code 
= %d\n",
                         error->sequence, error->error_code);
@@ -549,7 +665,7 @@
 
         switch (type) {
             case XCB_KEY_PRESS:
-                handle_key_press((xcb_key_press_event_t*)event);
+                handle_key_press((xcb_key_press_event_t *)event);
                 break;
 
             case XCB_KEY_RELEASE:
@@ -562,7 +678,7 @@
                 break;
 
             case XCB_VISIBILITY_NOTIFY:
-                handle_visibility_notify(conn, 
(xcb_visibility_notify_event_t*)event);
+                handle_visibility_notify(conn, (xcb_visibility_notify_event_t 
*)event);
                 break;
 
             case XCB_MAP_NOTIFY:
@@ -609,18 +725,17 @@
 
     /* We need to know about the window being obscured or getting destroyed. */
     xcb_change_window_attributes(conn, window, XCB_CW_EVENT_MASK,
-        (uint32_t[]){
-            XCB_EVENT_MASK_VISIBILITY_CHANGE |
-            XCB_EVENT_MASK_STRUCTURE_NOTIFY
-        });
+                                 (uint32_t[]){
+                                     XCB_EVENT_MASK_VISIBILITY_CHANGE |
+                                     XCB_EVENT_MASK_STRUCTURE_NOTIFY});
     xcb_flush(conn);
 
     DEBUG("Watching window 0x%08x\n", window);
     while ((event = xcb_wait_for_event(conn)) != NULL) {
         if (event->response_type == 0) {
-            xcb_generic_error_t *error = (xcb_generic_error_t*)event;
+            xcb_generic_error_t *error = (xcb_generic_error_t *)event;
             DEBUG("X11 Error received! sequence 0x%x, error_code = %d\n",
-                 error->sequence, error->error_code);
+                  error->sequence, error->error_code);
             free(event);
             continue;
         }
@@ -629,16 +744,16 @@
         DEBUG("Read event of type %d\n", type);
         switch (type) {
             case XCB_VISIBILITY_NOTIFY:
-                handle_visibility_notify(conn, 
(xcb_visibility_notify_event_t*)event);
+                handle_visibility_notify(conn, (xcb_visibility_notify_event_t 
*)event);
                 break;
             case XCB_UNMAP_NOTIFY:
-                DEBUG("UnmapNotify for 0x%08x\n", 
(((xcb_unmap_notify_event_t*)event)->window));
-                if (((xcb_unmap_notify_event_t*)event)->window == window)
+                DEBUG("UnmapNotify for 0x%08x\n", (((xcb_unmap_notify_event_t 
*)event)->window));
+                if (((xcb_unmap_notify_event_t *)event)->window == window)
                     exit(EXIT_SUCCESS);
                 break;
             case XCB_DESTROY_NOTIFY:
-                DEBUG("DestroyNotify for 0x%08x\n", 
(((xcb_destroy_notify_event_t*)event)->window));
-                if (((xcb_destroy_notify_event_t*)event)->window == window)
+                DEBUG("DestroyNotify for 0x%08x\n", 
(((xcb_destroy_notify_event_t *)event)->window));
+                if (((xcb_destroy_notify_event_t *)event)->window == window)
                     exit(EXIT_SUCCESS);
                 break;
             default:
@@ -650,6 +765,7 @@
 }
 
 int main(int argc, char *argv[]) {
+    struct passwd *pw;
     char *username;
     char *image_path = NULL;
     int ret;
@@ -663,7 +779,7 @@
         {"beep", no_argument, NULL, 'b'},
         {"dpms", no_argument, NULL, 'd'},
         {"color", required_argument, NULL, 'c'},
-        {"pointer", required_argument, NULL , 'p'},
+        {"pointer", required_argument, NULL, 'p'},
         {"debug", no_argument, NULL, 0},
         {"help", no_argument, NULL, 'h'},
         {"no-unlock-indicator", no_argument, NULL, 'u'},
@@ -671,74 +787,78 @@
         {"tiling", no_argument, NULL, 't'},
         {"ignore-empty-password", no_argument, NULL, 'e'},
         {"inactivity-timeout", required_argument, NULL, 'I'},
-        {NULL, no_argument, NULL, 0}
-    };
+        {"show-failed-attempts", no_argument, NULL, 'f'},
+        {NULL, no_argument, NULL, 0}};
 
-    if ((username = getenv("USER")) == NULL)
-        errx(EXIT_FAILURE, "USER environment variable not set, please set 
it.\n");
+    if ((pw = getpwuid(getuid())) == NULL)
+        err(EXIT_FAILURE, "getpwuid() failed");
+    if ((username = pw->pw_name) == NULL)
+        errx(EXIT_FAILURE, "pw->pw_name is NULL.\n");
 
-    char *optstring = "hvnbdc:p:ui:teI:";
+    char *optstring = "hvnbdc:p:ui:teI:f";
     while ((o = getopt_long(argc, argv, optstring, longopts, &optind)) != -1) {
         switch (o) {
-        case 'v':
-            errx(EXIT_SUCCESS, "version " VERSION " © 2010-2012 Michael 
Stapelberg");
-        case 'n':
-            dont_fork = true;
-            break;
-        case 'b':
-            beep = true;
-            break;
-        case 'd':
-            dpms = true;
-            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;
-            break;
-        }
-        case 'c': {
-            char *arg = optarg;
+            case 'v':
+                errx(EXIT_SUCCESS, "version " VERSION " © 2010 Michael 
Stapelberg");
+            case 'n':
+                dont_fork = true;
+                break;
+            case 'b':
+                beep = true;
+                break;
+            case 'd':
+                dpms = true;
+                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;
+                break;
+            }
+            case 'c': {
+                char *arg = optarg;
 
-            /* Skip # if present */
-            if (arg[0] == '#')
-                arg++;
+                /* Skip # if present */
+                if (arg[0] == '#')
+                    arg++;
 
-            if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", color) != 1)
-                errx(EXIT_FAILURE, "color is invalid, it must be given in 
3-byte hexadecimal format: rrggbb\n");
+                if (strlen(arg) != 6 || sscanf(arg, "%06[0-9a-fA-F]", color) 
!= 1)
+                    errx(EXIT_FAILURE, "color is invalid, it must be given in 
3-byte hexadecimal format: rrggbb\n");
 
-            break;
-        }
-        case 'u':
-            unlock_indicator = false;
-            break;
-        case 'i':
-            image_path = strdup(optarg);
-            break;
-        case 't':
-            tile = true;
-            break;
-        case 'p':
-            if (!strcmp(optarg, "win")) {
-                curs_choice = CURS_WIN;
-            } else if (!strcmp(optarg, "default")) {
-                curs_choice = CURS_DEFAULT;
-            } else {
-                errx(EXIT_FAILURE, "i3lock: Invalid pointer type given. 
Expected one of \"win\" or \"default\".\n");
+                break;
             }
-            break;
-        case 'e':
-            ignore_empty_password = true;
-            break;
-        case 0:
-            if (strcmp(longopts[optind].name, "debug") == 0)
-                debug_mode = true;
-            break;
-        default:
-            errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] 
[-u] [-p win|default]"
-            " [-i image.png] [-t] [-e] [-I]"
-            );
+            case 'u':
+                unlock_indicator = false;
+                break;
+            case 'i':
+                image_path = strdup(optarg);
+                break;
+            case 't':
+                tile = true;
+                break;
+            case 'p':
+                if (!strcmp(optarg, "win")) {
+                    curs_choice = CURS_WIN;
+                } else if (!strcmp(optarg, "default")) {
+                    curs_choice = CURS_DEFAULT;
+                } else {
+                    errx(EXIT_FAILURE, "i3lock: Invalid pointer type given. 
Expected one of \"win\" or \"default\".\n");
+                }
+                break;
+            case 'e':
+                ignore_empty_password = true;
+                break;
+            case 0:
+                if (strcmp(longopts[optind].name, "debug") == 0)
+                    debug_mode = true;
+                break;
+            case 'f':
+                show_failed_attempts = true;
+                break;
+            default:
+                errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c 
color] [-u] [-p win|default]"
+                                   " [-i image.png] [-t] [-e] [-I] [-f]");
         }
     }
 
@@ -769,13 +889,13 @@
         errx(EXIT_FAILURE, "Could not connect to X11, maybe you need to set 
DISPLAY?");
 
     if (xkb_x11_setup_xkb_extension(conn,
-            XKB_X11_MIN_MAJOR_XKB_VERSION,
-            XKB_X11_MIN_MINOR_XKB_VERSION,
-            0,
-            NULL,
-            NULL,
-            &xkb_base_event,
-            &xkb_base_error) != 1)
+                                    XKB_X11_MIN_MAJOR_XKB_VERSION,
+                                    XKB_X11_MIN_MINOR_XKB_VERSION,
+                                    0,
+                                    NULL,
+                                    NULL,
+                                    &xkb_base_event,
+                                    &xkb_base_error) != 1)
         errx(EXIT_FAILURE, "Could not setup XKB extension.");
 
     static const xcb_xkb_map_part_t required_map_parts =
@@ -806,6 +926,19 @@
     if (!load_keymap())
         errx(EXIT_FAILURE, "Could not load keymap");
 
+    const char *locale = getenv("LC_ALL");
+    if (!locale)
+        locale = getenv("LC_CTYPE");
+    if (!locale)
+        locale = getenv("LANG");
+    if (!locale) {
+        if (debug_mode)
+            fprintf(stderr, "Can't detect your locale, fallback to C\n");
+        locale = "C";
+    }
+
+    load_compose_table(locale);
+
     xinerama_init();
     xinerama_query_screens();
 
@@ -829,7 +962,7 @@
     last_resolution[1] = screen->height_in_pixels;
 
     xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK,
-            (uint32_t[]){ XCB_EVENT_MASK_STRUCTURE_NOTIFY });
+                                 
(uint32_t[]){XCB_EVENT_MASK_STRUCTURE_NOTIFY});
 
     if (image_path) {
         /* Create a pixmap to render on, fill it with the background color */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/i3lock.h new/i3lock-2.7/i3lock.h
--- old/i3lock-2.6/i3lock.h     2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/i3lock.h     2015-05-20 09:17:06.000000000 +0200
@@ -5,9 +5,10 @@
  * This is important because xautolock (for example) closes stdout/stderr by
  * default, so just printing something to stdout will lead to the data ending
  * up on the X11 socket (!). */
-#define DEBUG(fmt, ...) do { \
-    if (debug_mode) \
-        printf("[i3lock-debug] " fmt, ##__VA_ARGS__); \
-} while (0)
+#define DEBUG(fmt, ...)                                   \
+    do {                                                  \
+        if (debug_mode)                                   \
+            printf("[i3lock-debug] " fmt, ##__VA_ARGS__); \
+    } while (0)
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/unlock_indicator.c 
new/i3lock-2.7/unlock_indicator.c
--- old/i3lock-2.6/unlock_indicator.c   2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/unlock_indicator.c   2015-05-20 09:17:06.000000000 +0200
@@ -1,7 +1,7 @@
 /*
  * vim:ts=4:sw=4:expandtab
  *
- * © 2010-2014 Michael Stapelberg
+ * © 2010 Michael Stapelberg
  *
  * See LICENSE for licensing information
  *
@@ -9,6 +9,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <math.h>
 #include <xcb/xcb.h>
 #include <ev.h>
@@ -44,6 +45,9 @@
 /* Whether the unlock indicator is enabled (defaults to true). */
 extern bool unlock_indicator;
 
+/* List of pressed modifiers, or NULL if none are pressed. */
+extern char *modifier_string;
+
 /* A Cairo surface containing the specified image (-i), if any. */
 extern cairo_surface_t *img;
 
@@ -52,6 +56,11 @@
 /* The background color to use (in hex). */
 extern char color[7];
 
+/* Whether the failed attempts should be displayed. */
+extern bool show_failed_attempts;
+/* Number of failed unlock attempts. */
+extern int failed_attempts;
+
 
/*******************************************************************************
  * Variables defined in xcb.c.
  
******************************************************************************/
@@ -146,10 +155,10 @@
          * (currently verifying, wrong password, or default) */
         switch (pam_state) {
             case STATE_PAM_VERIFY:
-                cairo_set_source_rgba(ctx, 0, 114.0/255, 255.0/255, 0.75);
+                cairo_set_source_rgba(ctx, 0, 114.0 / 255, 255.0 / 255, 0.75);
                 break;
             case STATE_PAM_WRONG:
-                cairo_set_source_rgba(ctx, 250.0/255, 0, 0, 0.75);
+                cairo_set_source_rgba(ctx, 250.0 / 255, 0, 0, 0.75);
                 break;
             default:
                 cairo_set_source_rgba(ctx, 0, 0, 0, 0.75);
@@ -159,13 +168,13 @@
 
         switch (pam_state) {
             case STATE_PAM_VERIFY:
-                cairo_set_source_rgb(ctx, 51.0/255, 0, 250.0/255);
+                cairo_set_source_rgb(ctx, 51.0 / 255, 0, 250.0 / 255);
                 break;
             case STATE_PAM_WRONG:
-                cairo_set_source_rgb(ctx, 125.0/255, 51.0/255, 0);
+                cairo_set_source_rgb(ctx, 125.0 / 255, 51.0 / 255, 0);
                 break;
             case STATE_PAM_IDLE:
-                cairo_set_source_rgb(ctx, 51.0/255, 125.0/255, 0);
+                cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0);
                 break;
         }
         cairo_stroke(ctx);
@@ -185,6 +194,11 @@
 
         /* Display a (centered) text of the current PAM state. */
         char *text = NULL;
+        /* We don't want to show more than a 3-digit number. */
+        char buf[4];
+
+        cairo_set_source_rgb(ctx, 0, 0, 0);
+        cairo_set_font_size(ctx, 28.0);
         switch (pam_state) {
             case STATE_PAM_VERIFY:
                 text = "verifying…";
@@ -193,6 +207,16 @@
                 text = "wrong!";
                 break;
             default:
+                if (show_failed_attempts && failed_attempts > 0) {
+                    if (failed_attempts > 999) {
+                        text = "> 999";
+                    } else {
+                        snprintf(buf, sizeof(buf), "%d", failed_attempts);
+                        text = buf;
+                    }
+                    cairo_set_source_rgb(ctx, 1, 0, 0);
+                    cairo_set_font_size(ctx, 32.0);
+                }
                 break;
         }
 
@@ -200,9 +224,6 @@
             cairo_text_extents_t extents;
             double x, y;
 
-            cairo_set_source_rgb(ctx, 0, 0, 0);
-            cairo_set_font_size(ctx, 28.0);
-
             cairo_text_extents(ctx, text, &extents);
             x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing);
             y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing);
@@ -212,6 +233,21 @@
             cairo_close_path(ctx);
         }
 
+        if (pam_state == STATE_PAM_WRONG && (modifier_string != NULL)) {
+            cairo_text_extents_t extents;
+            double x, y;
+
+            cairo_set_font_size(ctx, 14.0);
+
+            cairo_text_extents(ctx, modifier_string, &extents);
+            x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing);
+            y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 
28.0;
+
+            cairo_move_to(ctx, x, y);
+            cairo_show_text(ctx, modifier_string);
+            cairo_close_path(ctx);
+        }
+
         /* After the user pressed any valid key or the backspace key, we
          * highlight a random part of the unlock indicator to confirm this
          * keypress. */
@@ -227,10 +263,10 @@
                       highlight_start + (M_PI / 3.0));
             if (unlock_state == STATE_KEY_ACTIVE) {
                 /* For normal keys, we use a lighter green. */
-                cairo_set_source_rgb(ctx, 51.0/255, 219.0/255, 0);
+                cairo_set_source_rgb(ctx, 51.0 / 255, 219.0 / 255, 0);
             } else {
                 /* For backspace, we use red. */
-                cairo_set_source_rgb(ctx, 219.0/255, 51.0/255, 0);
+                cairo_set_source_rgb(ctx, 219.0 / 255, 51.0 / 255, 0);
             }
             cairo_stroke(ctx);
 
@@ -287,7 +323,7 @@
  */
 void redraw_screen(void) {
     xcb_pixmap_t bg_pixmap = draw_image(last_resolution);
-    xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){ 
bg_pixmap });
+    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
      * screen instead of the whole screen. */
     xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]);
@@ -303,6 +339,7 @@
 void clear_indicator(void) {
     if (input_position == 0) {
         unlock_state = STATE_STARTED;
-    } else unlock_state = STATE_KEY_PRESSED;
+    } else
+        unlock_state = STATE_KEY_PRESSED;
     redraw_screen();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/unlock_indicator.h 
new/i3lock-2.7/unlock_indicator.h
--- old/i3lock-2.6/unlock_indicator.h   2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/unlock_indicator.h   2015-05-20 09:17:06.000000000 +0200
@@ -2,18 +2,18 @@
 #define _UNLOCK_INDICATOR_H
 
 typedef enum {
-    STATE_STARTED = 0,          /* default state */
-    STATE_KEY_PRESSED = 1,      /* key was pressed, show unlock indicator */
-    STATE_KEY_ACTIVE = 2,       /* a key was pressed recently, highlight part
+    STATE_STARTED = 0,         /* default state */
+    STATE_KEY_PRESSED = 1,     /* key was pressed, show unlock indicator */
+    STATE_KEY_ACTIVE = 2,      /* a key was pressed recently, highlight part
                                    of the unlock indicator. */
-    STATE_BACKSPACE_ACTIVE = 3  /* backspace was pressed recently, highlight
+    STATE_BACKSPACE_ACTIVE = 3 /* backspace was pressed recently, highlight
                                    part of the unlock indicator in red. */
 } 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 */
+    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;
 
 xcb_pixmap_t draw_image(uint32_t* resolution);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/xcb.c new/i3lock-2.7/xcb.c
--- old/i3lock-2.6/xcb.c        2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/xcb.c        2015-05-20 09:17:06.000000000 +0200
@@ -1,7 +1,7 @@
 /*
  * vim:ts=4:sw=4:expandtab
  *
- * © 2010-2012 Michael Stapelberg
+ * © 2010 Michael Stapelberg
  *
  * xcb.c: contains all functions which use XCB to talk to X11. Mostly wrappers
  *        around the rather complicated/ugly parts of the XCB API.
@@ -28,25 +28,25 @@
 #define curs_invisible_height 8
 
 static unsigned char curs_invisible_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
 #define curs_windows_width 11
 #define curs_windows_height 19
 
 static unsigned char curs_windows_bits[] = {
- 0xfe, 0x07, 0xfc, 0x07, 0xfa, 0x07, 0xf6, 0x07, 0xee, 0x07, 0xde, 0x07,
- 0xbe, 0x07, 0x7e, 0x07, 0xfe, 0x06, 0xfe, 0x05, 0x3e, 0x00, 0xb6, 0x07,
- 0x6a, 0x07, 0x6c, 0x07, 0xde, 0x06, 0xdf, 0x06, 0xbf, 0x05, 0xbf, 0x05,
- 0x7f, 0x06 };
+    0xfe, 0x07, 0xfc, 0x07, 0xfa, 0x07, 0xf6, 0x07, 0xee, 0x07, 0xde, 0x07,
+    0xbe, 0x07, 0x7e, 0x07, 0xfe, 0x06, 0xfe, 0x05, 0x3e, 0x00, 0xb6, 0x07,
+    0x6a, 0x07, 0x6c, 0x07, 0xde, 0x06, 0xdf, 0x06, 0xbf, 0x05, 0xbf, 0x05,
+    0x7f, 0x06};
 
 #define mask_windows_width 11
 #define mask_windows_height 19
 
 static unsigned char mask_windows_bits[] = {
- 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00,
- 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x07, 0x7f, 0x00,
- 0xf7, 0x00, 0xf3, 0x00, 0xe1, 0x01, 0xe0, 0x01, 0xc0, 0x03, 0xc0, 0x03,
- 0x80, 0x01 };
+    0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00,
+    0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x07, 0x7f, 0x00,
+    0xf7, 0x00, 0xf3, 0x00, 0xe1, 0x01, 0xe0, 0x01, 0xc0, 0x03, 0xc0, 0x03,
+    0x80, 0x01};
 
 static uint32_t get_colorpixel(char *hex) {
     char strgroups[3][3] = {{hex[0], hex[1], '\0'},
@@ -67,7 +67,6 @@
     for (depth_iter = xcb_screen_allowed_depths_iterator(screen);
          depth_iter.rem;
          xcb_depth_next(&depth_iter)) {
-
         for (visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
              visual_iter.rem;
              xcb_visualtype_next(&visual_iter)) {
@@ -82,7 +81,7 @@
     return NULL;
 }
 
-xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, 
u_int32_t* resolution, char *color) {
+xcb_pixmap_t create_bg_pixmap(xcb_connection_t *conn, xcb_screen_t *scr, 
u_int32_t *resolution, char *color) {
     xcb_pixmap_t bg_pixmap = xcb_generate_id(conn);
     xcb_create_pixmap(conn, scr->root_depth, bg_pixmap, scr->root,
                       resolution[0], resolution[1]);
@@ -90,9 +89,9 @@
     /* Generate a Graphics Context and fill the pixmap with background color
      * (for images that are smaller than your screen) */
     xcb_gcontext_t gc = xcb_generate_id(conn);
-    uint32_t values[] = { get_colorpixel(color) };
+    uint32_t values[] = {get_colorpixel(color)};
     xcb_create_gc(conn, gc, bg_pixmap, XCB_GC_FOREGROUND, values);
-    xcb_rectangle_t rect = { 0, 0, resolution[0], resolution[1] };
+    xcb_rectangle_t rect = {0, 0, resolution[0], resolution[1]};
     xcb_poly_fill_rectangle(conn, bg_pixmap, gc, 1, &rect);
     xcb_free_gc(conn, gc);
 
@@ -124,12 +123,12 @@
 
     xcb_create_window(conn,
                       XCB_COPY_FROM_PARENT,
-                      win, /* the window id */
+                      win,       /* the window id */
                       scr->root, /* parent == root */
                       0, 0,
                       scr->width_in_pixels,
                       scr->height_in_pixels, /* dimensions */
-                      0, /* border = 0, we draw our own */
+                      0,                     /* border = 0, we draw our own */
                       XCB_WINDOW_CLASS_INPUT_OUTPUT,
                       XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from 
parent */
                       mask,
@@ -188,8 +187,7 @@
             XCB_GRAB_MODE_ASYNC, /* keyboard mode */
             XCB_NONE,            /* confine_to = in which window should the 
cursor stay */
             cursor,              /* we change the cursor to whatever the user 
wanted */
-            XCB_CURRENT_TIME
-        );
+            XCB_CURRENT_TIME);
 
         if ((preply = xcb_grab_pointer_reply(conn, pcookie, NULL)) &&
             preply->status == XCB_GRAB_STATUS_SUCCESS) {
@@ -204,12 +202,11 @@
     while (tries-- > 0) {
         kcookie = xcb_grab_keyboard(
             conn,
-            true,                /* report events */
-            screen->root,        /* grab the root window */
+            true,         /* report events */
+            screen->root, /* grab the root window */
             XCB_CURRENT_TIME,
             XCB_GRAB_MODE_ASYNC, /* process events as normal, do not require 
sync */
-            XCB_GRAB_MODE_ASYNC
-        );
+            XCB_GRAB_MODE_ASYNC);
 
         if ((kreply = xcb_grab_keyboard_reply(conn, kcookie, NULL)) &&
             kreply->status == XCB_GRAB_STATUS_SUCCESS) {
@@ -230,8 +227,8 @@
     xcb_pixmap_t mask;
     xcb_cursor_t cursor;
 
-    unsigned char* curs_bits;
-    unsigned char* mask_bits;
+    unsigned char *curs_bits;
+    unsigned char *mask_bits;
     int curs_w, curs_h;
 
     switch (choice) {
@@ -278,9 +275,9 @@
                       cursor,
                       bitmap,
                       mask,
-                      65535,65535,65535,
-                      0,0,0,
-                      0,0);
+                      65535, 65535, 65535,
+                      0, 0, 0,
+                      0, 0);
 
     xcb_free_pixmap(conn, bitmap);
     xcb_free_pixmap(conn, mask);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/i3lock-2.6/xinerama.c new/i3lock-2.7/xinerama.c
--- old/i3lock-2.6/xinerama.c   2014-07-18 20:25:02.000000000 +0200
+++ new/i3lock-2.7/xinerama.c   2015-05-20 09:17:06.000000000 +0200
@@ -1,7 +1,7 @@
 /*
  * vim:ts=4:sw=4:expandtab
  *
- * © 2010-2012 Michael Stapelberg
+ * © 2010 Michael Stapelberg
  *
  * See LICENSE for licensing information
  *
@@ -82,8 +82,8 @@
         xr_resolutions[screen].width = screen_info[screen].width;
         xr_resolutions[screen].height = screen_info[screen].height;
         DEBUG("found Xinerama screen: %d x %d at %d x %d\n",
-                        screen_info[screen].width, screen_info[screen].height,
-                        screen_info[screen].x_org, screen_info[screen].y_org);
+              screen_info[screen].width, screen_info[screen].height,
+              screen_info[screen].x_org, screen_info[screen].y_org);
     }
 
     free(reply);



Reply via email to