Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37879934
en ru br
ALT Linux repos
S:5.69-alt1
5.0: 5.27-alt10.M50.1
4.1: 5.27-alt5.M41.1
4.0: 5.27-alt8.M40.1.1

Group :: Graphical desktop/Other
RPM: xlockmore

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: xlockmore-5.46-l10n.patch
Download


 Makefile.in             |    7 ++
 modes/Makefile.in       |    2 +-
 xlock/Makefile.in       |    7 +-
 xlock/XLock-ja.ad       |    2 +
 xlock/XLock-ru.ad       |   21 ++++
 xlock/XLock.ad          |    2 +
 xlock/msgmerge.c        |   83 ++++++++++++++++
 xlock/msgmerge.h        |   20 ++++
 xlock/resource-msg-en.h |    4 +-
 xlock/resource.c        |   13 +++
 xlock/xlock.c           |  252 +++++++++++++++++++++++------------------------
 11 files changed, 277 insertions(+), 136 deletions(-)
diff --git a/Makefile.in b/Makefile.in
index 7d99255..00e7ee1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -9,7 +9,7 @@
 MAKEIN_SUBDIR = for dir in $(SUBDIRS) ; do ( cd $$dir ; sed s/@MODULES@/\#/ Makefile.in > Makefile ; $(MAKE) $@ ) ; done
 
 all :
-	@+$(MAKE_SUBDIR)
+	for dir in $(SUBDIRS); do $(MAKE) -C $$dir all; done
 
 # this tells GNU make not to export variables into the environment
 # But other makes do not understand its significance, so it must
@@ -32,7 +32,14 @@ RM = rm -f
 VER = xlockmore
 
+datadir = @datadir@
+
 install :
+	cd po; \
+	for po in */*/*.po; do \
+	msgfmt "$$po" -o "$${po%.po}.mo" && \
+	install -p -m640 -D "$${po%.po}.mo" "$(datadir)/locale"/"$${po%.po}.mo"; \
+	done
 	@+$(MAKE_SUBDIR)
 
 install-program :
diff --git a/modes/Makefile.in b/modes/Makefile.in
index 053d36c..aefdcea 100644
--- a/modes/Makefile.in
+++ b/modes/Makefile.in
@@ -54,7 +54,7 @@ XLOCKUTILOBJS = $(DOU)xlock$(OU)passwd$(OU)resource$(OU)parsecmd$(O)$(S)\
 $(DOU)util$(OU)logout$(OU)mode$(OU)xlockimage$(OU)ras$(OU)xbm$(O)$(S)\
 $(DOU)vis$(OU)visgl$(OU)color$(OU)random$(OU)iostuff$(OU)automata$(O)$(S)\
 $(DOU)spline$(OU)sound$(OU)erase$(OU)magick$(O)$(S)\
-$(DOU)vtlock$(OU)vtlock_proc$(O)
+$(DOU)vtlock$(OU)vtlock_proc$(OU)msgmerge$(O)
 
 # This debugging is new and is untested on many systems.
 @CHECK@CHECKDEF = -DDEBUG
diff --git a/xlock/Makefile.in b/xlock/Makefile.in
index 7577bf0..06bf5a3 100644
--- a/xlock/Makefile.in
+++ b/xlock/Makefile.in
@@ -6,6 +6,7 @@
 # @SET_MAKE@
 
 datarootdir = @datarootdir@
+pkgdatadir = @datadir@/@PACKAGE@
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
@@ -44,17 +45,17 @@ XLOCKUTILOBJS = $(DOU)xlock$(OU)passwd$(OU)resource$(OU)parsecmd$(O)$(S)\
 $(DOU)util$(OU)logout$(OU)mode$(OU)xlockimage$(OU)ras$(OU)xbm$(O)$(S)\
 $(DOU)vis$(OU)visgl$(OU)color$(OU)random$(OU)iostuff$(OU)automata$(O)$(S)\
 $(DOU)spline$(OU)sound$(OU)erase$(OU)magick$(O)$(S)\
-$(DOU)vtlock$(OU)vtlock_proc$(O)$(S)$(XLOCKCHECKOBJS)
+$(DOU)vtlock$(OU)vtlock_proc$(OU)msgmerge$(O)$(S)$(XLOCKCHECKOBJS)
 
 XLOCKCHECKSRCS = $(DU)memcheck$(C)
 
 XLOCKUTILHDRS = xlock.h mode.h vroot.h xlockimage.h ras.h \
-version.h config.h
+version.h config.h msgmerge.h
 XLOCKUTILSRCS = $(DU)xlock$(CU)passwd$(CU)resource$(CU)parsecmd$(C) \
 $(DU)util$(CU)logout$(CU)mode$(CU)xlockimage$(CU)ras$(CU)xbm$(C) \
 $(DU)vis$(CU)visgl$(CU)color$(CU)random$(CU)iostuff$(CU)automata$(C) \
 $(DU)spline$(CU)sound$(CU)erase$(CU)magick$(C) \
-$(DU)vtlock$(CU)vtlock_proc$(C) $(XLOCKCHECKSRCS)
+$(DU)vtlock$(CU)vtlock_proc$(CU)msgmerge$(C) $(XLOCKCHECKSRCS)
 
 # default target
 all : $(XLOCKUTILOBJS)
diff --git a/xlock/XLock-ja.ad b/xlock/XLock-ja.ad
index ce9efd5..d49564c 100644
--- a/xlock/XLock-ja.ad
+++ b/xlock/XLock-ja.ad
@@ -1,4 +1,6 @@
 !! Japanese by: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
+XLock.fontset: -*-droid sans mono-bold-*-normal--24-*-,-*-*-bold-*-normal--14-*-,-*-*-medium-*-normal--14-*-
+XLock.planfontset: -*-droid sans mono-bold-*-normal--12-*-,-*-*-bold-*-normal--12-*-
 XLock.username: ログイン名:
 XLock.password: パスワード:
 XLock.info: Enter パスワードを入力して下さい。アイコンをクリックすると再ロックします。
diff --git a/xlock/XLock-ru.ad b/xlock/XLock-ru.ad
new file mode 100644
index 0000000..95548c8
--- /dev/null
+++ b/xlock/XLock-ru.ad
@@ -0,0 +1,21 @@
+!! Russian by Paul Wolneykien <manowar@altlinux.org>
+XLock.fontset: -*-droid sans mono-bold-*-normal--24-*-,-*-*-bold-*-normal--14-*-,-*-*-medium-*-normal--14-*-
+XLock.planfontset: -*-droid sans mono-bold-*-normal--12-*-,-*-*-bold-*-normal--12-*-
+XLock.username: 仄: 
+XLock.password: 舒仂仍: 
+XLock.info: 于亠亟亳亠 仗舒仂仍, 仂弍 仆 弍仍仂从亳仂于从. 舒亢仄亳亠 亳从仂仆从 亟仍 仗仂仄仂舒 亰舒舒于从亳.
+XLock.validate: 亠仆亳亳从舒亳...
+XLock.invalid: 亳弍从舒 舒亠仆亳亳从舒亳亳.
+XLock.invalidCapsLock: 亳弍从舒 舒亠仆亳亳从舒亳亳, 仆亳仄舒仆亳亠! CapsLock 于从仍ム亠仆.
+XLock.logoutButtonLabel: 舒于亠亳 亠舒仆
+XLock.logoutButtonHelp: \
+ 仄仂亢亠亠 亰舒于亠亳 亟舒仆仆亶 亠舒仆 亳 仆舒舒 仆仂于亶, 亠仍亳 磲仂仄\n\
+仆亠 于仂弍仂亟仆 舒弍仂亳 仄亠.\n\
+: 舒于亠亠仆亳亠 亠舒仆舒 仗亳于亠亟 从 舒于舒亳亶仆仂仄 亰舒于亠亠仆亳\n\
+于亠 亰舒仗亠仆仆 仗仂仍亰仂于舒亠仍亠仄 仗仂亞舒仄仄, 仗仂仂仄 亳仗仂仍亰亶亠\n\
+亟舒仆仆 于仂亰仄仂亢仆仂 仂仍从仂 于 仂仄 仍舒亠, 亠仍亳 仗仂仍亰仂于舒亠仍,\n\
+亰舒仗亳于亳亶 亠舒仆, 仆亠亟仂仗亠仆.
+XLock.logoutFailedString: \
+仂仗从舒 亰舒于亠亠仆亳 亠舒仆舒  丕弌亂.\n\
+弌亠舒仆 亟舒仆仆仂亞仂 仗仂仍亰仂于舒亠仍 仆亠 仄仂亢亠 弍 舒于仂仄舒亳亠从亳 亰舒于亠仆.
+XLock.logoutAuto: 仂仗从舒 舒于仂仄舒亳亠从仂亞仂 亰舒于亠亠仆亳 亠舒仆舒 仆亠 亟舒仍舒.
diff --git a/xlock/XLock.ad b/xlock/XLock.ad
index 0dc2b6b..5e0025d 100644
--- a/xlock/XLock.ad
+++ b/xlock/XLock.ad
@@ -107,6 +107,8 @@ before logging them out.
 XLock.logoutFailedString: \
 Logout attempt FAILED.\n\
 Current user could not be automatically logged out.
+XLock.attempt: %d failed attempt.
+XLock.attempts: %d failed attempts.
 
 ! Mode options: If count, cycles, or size options are set to 1 ...
 ! they are probably not used by the mode.
diff --git a/xlock/msgmerge.c b/xlock/msgmerge.c
new file mode 100644
index 0000000..92f9485
--- /dev/null
+++ b/xlock/msgmerge.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <string.h>
+#include "msgmerge.h"
+
+/* A function to merge one piece of text with another.
+ * Current text contained in the 'buf' argument should
+ * include one or more fragments inside square brackets.
+ * New text in the 'msg' argument should contain '*'
+ * characters in number equal to the number of fragments
+ * outside the square brackets in the current text.
+ * When merged, the '*' characters in the new text are
+ * replaced by the correcponding fragments of current text
+ * outside the brackets. Text inside brackets isn't used
+ * and so is missed.
+ * Resulted text is saved in the buffer 'buf'. To avoid
+ * possible overflow the 'buflen' argument is used to
+ * specify a maximum size of data in the buffer 'buf'.
+ */
+char *msgmerge(char *buf, const char *msg, int buflen)
+{
+  int i, ib, jb;
+  char *tmp;
+
+  /* Allocate a buffer for merge. */
+  tmp = malloc(buflen);
+  if (tmp == NULL)
+  {
+    return NULL;
+  }
+
+  /* Put initial copy of the 'msg'. */
+  strncpy(tmp, msg, buflen);
+  tmp[buflen - 1] = '\0';
+
+  i = 0;
+  ib = jb = 0;
+  while (i < strlen(tmp) && ib < strlen(buf))
+  {
+    /* Search for the next asterisk. */
+      for (; i < strlen(tmp) && (tmp[i] != '*' || \
+	   ((i > 0) && tmp[i-1] == '\\')); i++);
+      if (i < strlen(tmp)) {
+       /* Replacement position found. Search for next
+        * fragment outside the brackets. */
+	if (buf[ib] == '[') {
+	  for (; ib < strlen(buf) && (buf[ib] != ']' || \
+	       ((ib > 0) && buf[ib-1] == '\\')); ib++);
+	  if ((ib + 1) < strlen(buf)) {
+	    ib++;
+	  }
+	}
+	for (jb = ib; jb < strlen(buf) && (buf[jb] != '[' || \
+	     ((jb > 0) && buf[jb-1] == '\\')); jb++);
+	if (ib < strlen(buf)) {
+	  /* Shift remaining part of 'msg' by jb - ib. */
+	  if ((i + jb - ib) < buflen) {
+	    memmove(tmp + i + jb - ib, tmp + i + 1, \
+		    (strlen(tmp) + jb - ib) < buflen ? \
+		    strlen(tmp) - i : buflen - i - jb + ib);
+	  }
+	  /* Replace asterisk by the fragment. */
+	  strncpy(tmp + i, buf + ib, (i + jb - ib) < buflen ?	\
+		  jb - ib : buflen - i);
+	  i += jb - ib;
+	  ib = ib;
+	}
+      }
+  }
+
+  strncpy(buf, tmp, buflen);
+  free(tmp);
+
+  return buf;
+}
+
+/* Copying 'msgmerge' version with separate source and destination
+ * buffers. */
+char *cmsgmerge
+(char *mbuf, const char *buf, const char *msg, int mbuflen)
+{
+  strncpy(mbuf, buf, mbuflen);
+  return msgmerge(mbuf, msg, mbuflen);
+}
diff --git a/xlock/msgmerge.h b/xlock/msgmerge.h
new file mode 100644
index 0000000..aab26cc
--- /dev/null
+++ b/xlock/msgmerge.h
@@ -0,0 +1,20 @@
+/* A function to merge one piece of text with another.
+ * Current text contained in the 'buf' argument should
+ * include one or more fragments inside square brackets.
+ * New text in the 'msg' argument should contain '*'
+ * characters in number equal to the number of fragments
+ * outside the square brackets in the current text.
+ * When merged, the '*' characters in the new text are
+ * replaced by the correcponding fragments of current text
+ * outside the brackets and the text inside brackets is
+ * removed along with the brackets.
+ * Resulted text is saved in the buffer 'buf'. To avoid
+ * possible overflow the 'buflen' argument is used to
+ * specify a maximum text length in the buffer 'buf'.
+ */
+char *msgmerge(char *buf, const char *msg, int buflen);
+
+/* Copying 'msgmerge' version with separate source and destination
+ * buffers. */
+char *cmsgmerge
+(char *mbuf, const char *buf, const char *msg, int mbuflen);
diff --git a/xlock/resource-msg-en.h b/xlock/resource-msg-en.h
index 61a5782..fd15703 100644
--- a/xlock/resource-msg-en.h
+++ b/xlock/resource-msg-en.h
@@ -16,8 +16,8 @@
 #define DEF_KRBINFO		"Enter Kerberos password to unlock; select icon to lock."
 #endif /* HAVE_KRB5 */
 
-#define DEF_COUNT_FAILED	" failed attempt."
-#define DEF_COUNTS_FAILED	" failed attempts."
+#define DEF_COUNT_FAILED	"%d failed attempt."
+#define DEF_COUNTS_FAILED	"%d failed attempts."
 
 /* string that appears in logout button */
 #define DEF_BTN_LABEL		"Logout"
diff --git a/xlock/resource.c b/xlock/resource.c
index 1f72d73..b24bbc9 100644
--- a/xlock/resource.c
+++ b/xlock/resource.c
@@ -72,6 +72,7 @@ static const char sccsid[] = "@(#)resource.c	4.08 98/08/04 xlockmore";
 #include "vis.h"
 #include "iostuff.h"
 #include "version.h"
+#include <locale.h>
 #if VMS
 # if ( __VMS_VER < 70000000 )
 #  ifdef __DECC
@@ -1731,12 +1732,23 @@ getAppResources(char *homeenv, char **custom, XrmDatabase * RDB,
 	XrmDatabase cmdlineDB = (XrmDatabase) NULL;
 	XrmDatabase userDB = (XrmDatabase) NULL;
 	XrmDatabase applicationDB = (XrmDatabase) NULL;
+	char       *lang;
+	char       *lclassname;
+	XrmDatabase localeDB = (XrmDatabase) NULL;
 
 	env = getenv("XFILESEARCHPATH");
 	applicationDB = parsefilepath(
 		((env == NULL) ? (char *) DEF_FILESEARCHPATH : env),
 		"app-defaults", classname, *custom);
 
+	lang = setlocale(LC_ALL, NULL);
+	lclassname = (char *) malloc(strlen(classname) + strlen(lang) + 2);
+	strcat(strcat(strcpy(lclassname, classname), "."), lang);
+	localeDB = parsefilepath(
+		((env == NULL) ? (char *) DEF_FILESEARCHPATH : env),
+		"app-defaults", lclassname, *custom);
+	free(lclassname);
+
 	XrmParseCommand(&cmdlineDB, cmdlineTable, cmdlineEntries, ProgramName,
 		argc, argv);
 
@@ -1770,6 +1782,7 @@ getAppResources(char *homeenv, char **custom, XrmDatabase * RDB,
 		free(userfile);
 
 	(void) XrmMergeDatabases(applicationDB, RDB);
+	(void) XrmMergeDatabases(localeDB, RDB);
 	(void) XrmMergeDatabases(userDB, RDB);
 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
    * line.  PURIFY 4.0.1 on SunOS4 does not report this error. */
diff --git a/xlock/xlock.c b/xlock/xlock.c
index 9fa2970..b215b5a 100644
--- a/xlock/xlock.c
+++ b/xlock/xlock.c
@@ -582,6 +582,9 @@ xlockmore_screenhack(Display * dpy, Window window,
 }
 
 #else /* STANDALONE */
+#include <locale.h>
+#include <libintl.h>
+#include "msgmerge.h"
 #include "xlock.h"
 #include "color.h"
 #include "util.h"
@@ -1572,7 +1575,7 @@ static void
 statusUpdate(int isnew, int scr)
 {
 	int         left, x, y, len;
-	char        buf[1024];
+	char        buf[1024], mbuf[1024];
 	XWindowAttributes xgwa;
 	static int  last_time;
 
@@ -1657,28 +1657,59 @@
 	y = timey;
 
 	if (timeelapsed) {
-		if (len < 60) {
-			if (len == 1)
-				(void) sprintf(buf, TIME_ELAPSED_MINUTE, len);
-			else
-				(void) sprintf(buf, TIME_ELAPSED_MINUTES, len);
-		} else {
-			(void) sprintf(buf, TIME_ELAPSED_HOURS, len / 60, len % 60);
-		}
-		putText(dsp, Scr[scr].window, Scr[scr].textgc, buf, False, left, &x, &y);
-	}
+	  if (len < 60)
+	      (void) sprintf(buf,
+			     ngettext("%d minute elapsed since locked.",
+				      "%d minutes elapsed since locked.",
+				      len),
+			     len);
+	  else {
+	      (void) sprintf(buf,
+			     ngettext("%d hour[ elapsed since locked.]",
+				      "%d hours[ elapsed since locked.]",
+				      len / 60),
+			     len / 60);
+	      (void) sprintf(buf,
+			     cmsgmerge(mbuf, buf,
+				      ngettext("* %02d minute[ elapsed since locked.]",
+					       "* %02d minutes[ elapsed since locked.]",
+					       len % 60),
+				      sizeof(buf)),
+			     len % 60);
+	      (void) sprintf(buf,
+			     cmsgmerge(mbuf, buf, gettext("* elapsed since locked."),
+				      sizeof(buf)));
+	    }
+	    putText(dsp, Scr[scr].window, Scr[scr].textgc, buf, False, left, &x, &y);
+	  }
 #ifdef USE_BUTTON_LOGOUT
 	if (enable_button) {
 		if (logoutButton > len) {
 			int         tmp = logoutButton - len;
 
 			if (tmp < 60) {
-				if (tmp == 1)
-					(void) sprintf(buf, BUTTON_MINUTE, tmp);
-				else
-					(void) sprintf(buf, BUTTON_MINUTES, tmp);
-			} else {
-					(void) sprintf(buf, BUTTON_HOURS, tmp / 60, tmp % 60);
+			  (void) sprintf(buf,
+					 ngettext("%d minute until the public logout button appears.",
+						  "%d minutes until the public logout button appears.",
+						  tmp),
+					 tmp);
+			} else {
+			  (void) sprintf(buf,
+					 ngettext("%d hour[ until public logout button appears.]",
+						  "%d hours[ until public logout button appears.]",
+						  tmp / 60),
+					 tmp / 60);
+			  (void) sprintf(buf,
+					 cmsgmerge(mbuf, buf,
+						  ngettext("* %02d minute[ until public logout button appears.]",
+							   "* %02d minutes[ until public logout button appears.]",
+							   tmp % 60),
+						  sizeof(buf)),
+					 tmp % 60);
+			  (void) sprintf(buf,
+					 cmsgmerge(mbuf, buf,
+						  gettext("* until public logout button appears."),
+						  sizeof(buf)));
 			}
 			putText(dsp, Scr[scr].window, Scr[scr].textgc, buf, False, left, &x, &y);
 		} else {
@@ -1725,12 +1756,28 @@
 		int         tmp = logoutAuto - len;
 
 		if (tmp < 60) {
-			if (tmp == 1)
-				(void) sprintf(buf, AUTOLOGOUT_MINUTE, tmp);
-			else
-				(void) sprintf(buf, AUTOLOGOUT_MINUTES, tmp);
-		} else {
-				(void) sprintf(buf, AUTOLOGOUT_HOURS, tmp / 60, tmp % 60);
+		  (void) sprintf(buf,
+				 ngettext("%d minute until auto-logout.",
+					  "%d minutes until auto-logout.",
+					  tmp),
+				 tmp);
+		} else {
+		  (void) sprintf(buf,
+				 ngettext("%d hour[ until auto-logout.]",
+					  "%d hours[ until auto-logout.]",
+					  tmp / 60),
+				 tmp / 60);
+		  (void) sprintf(buf,
+				 cmsgmerge(mbuf, buf,
+					  ngettext("* %02d minute[ until auto-logout.]",
+						   "* %02d minutes[ until auto-logout.]",
+						   tmp % 60),
+					  sizeof(buf)),
+				 tmp % 60);
+		  (void) sprintf(buf,
+				 cmsgmerge(mbuf, buf,
+					  gettext("* until auto-logout."),
+					  sizeof(buf)));
 		}
 		putText(dsp, Scr[scr].window, Scr[scr].textgc, buf, False, left, &x, &y);
 	}
@@ -2489,21 +2489,22 @@
 	putText(dsp, Scr[screen].window, Scr[screen].textgc, text_info, False, left, &x, &y);
 	putText(dsp, Scr[screen].window, Scr[screen].textgc, "\n", False, left, &x, &y);
 	if (count_failed > 0) {
-		char * cnt = NULL;
+		char *cntt, *cnt = NULL;
+		int cntlen = 0;
 		y += fontHeight + 6;
 		if (y < Scr[screen].iconpos.y + iconheight + fontAscent + 14)
 			y = Scr[screen].iconpos.y + iconheight + fontAscent + 14;
 		x = left = Scr[screen].iconpos.x;
-		if ((cnt = (char *) malloc(strlen((count_failed == 1) ? failed_attempt : failed_attempts) + 16)) != NULL) {
-			(void) sprintf(cnt, "%d%s", count_failed,
-				(count_failed == 1) ? failed_attempt : failed_attempts);
-			putText(dsp, Scr[screen].window, Scr[screen].textgc,
-				cnt, False, left, &x, &y);
-			putText(dsp, Scr[screen].window, Scr[screen].textgc,
-				"\n", False, left, &x, &y);
-			free(cnt);
-			y -= 2 * (fontHeight + 6); /* go up */
-		}
+		cntt = ngettext(failed_attempt, failed_attempts, count_failed);
+		cntlen = strlen(cntt) + 16;
+		cnt = (char *) malloc(cntlen);
+		snprintf(cnt, cntlen, cntt, count_failed);
+		putText(dsp, Scr[screen].window, Scr[screen].textgc,
+			cnt, False, left, &x, &y);
+		free(cnt);
+		putText(dsp, Scr[screen].window, Scr[screen].textgc,
+			"\n", False, left, &x, &y);
+		y -= 2 * (fontHeight + 6); /* go up */
 	}
 	timex = x;
 	timey = y;
@@ -2793,20 +2794,21 @@
 				XTextWidth(font, textInvalid, strlen(textInvalid)),
 				fontHeight +  5 + screenOffset);
 	if (count_failed > 0) {
-		char * cnt = NULL;
+		char *cntt, *cnt = NULL;
+		int cntlen = 0;
 		y += fontHeight + 6;
 		if (y < Scr[screen].iconpos.y + iconheight + fontAscent + 14)
 			y = Scr[screen].iconpos.y + iconheight + fontAscent + 14;
 		x = left = Scr[screen].iconpos.x;
-		if ((cnt = (char *) malloc(strlen((count_failed == 1) ? failed_attempt : failed_attempts) + 16)) != NULL) {
-			(void) sprintf(cnt, "%d%s", count_failed,
-				(count_failed == 1) ? failed_attempt : failed_attempts);
-				putText(dsp, Scr[screen].window, Scr[screen].textgc,
-					cnt, False, left, &x, &y);
-				putText(dsp, Scr[screen].window, Scr[screen].textgc,
-					"\n", False, left, &x, &y);
-				free(cnt);
-		}
+		cntt = ngettext(failed_attempt, failed_attempts, count_failed);
+		cntlen = strlen(cntt) + 16;
+		cnt = (char *) malloc(cntlen);
+		snprintf(cnt, cntlen, cntt, count_failed);
+		putText(dsp, Scr[screen].window, Scr[screen].textgc,
+			cnt, False, left, &x, &y);
+		free(cnt);
+		putText(dsp, Scr[screen].window, Scr[screen].textgc,
+			"\n", False, left, &x, &y);
 	}
 
 #ifdef USE_SOUND
@@ -3150,15 +3123,31 @@ createFontSet(Display * display, char *name)
 {
 	XFontSet    xfs;
 	char       *def, **miss;
-	int         miss_count;
+	int         i, n, miss_count;
+	XFontStruct **font_struct_list;
+	char **font_name_list;
 
 #define DEF_FONTSET2 "fixed,-*-14-*"
 
 	if ((xfs = XCreateFontSet(display, name, &miss, &miss_count, &def)) == NULL) {
-		(void) fprintf(stderr, "Could not create FontSet %s\n", name);
-		if ((xfs = XCreateFontSet(display, DEF_FONTSET2, &miss, &miss_count, &def)) == NULL)
-			(void) fprintf(stderr, "Could not create FontSet %s\n", DEF_FONTSET2);
+	  (void) fprintf(stderr, "Could not create FontSet %s\n", name);
+	  for (i = 0; i < miss_count; i++) {
+	    (void) fprintf(stderr, "%s\n", miss[i]);
+	  }
+	  if ((xfs = XCreateFontSet(display, DEF_FONTSET2, &miss, &miss_count, &def)) == NULL) {
+	    (void) fprintf(stderr, "Could not create FontSet %s\n", DEF_FONTSET2);
+	    for (i = 0; i < miss_count; i++) {
+	      (void) fprintf(stderr, "%s\n", miss[i]);
+	    }
+	  }
+	}
+#ifdef DEBUG
+	(void) printf("Selected font list:\n");
+	n = XFontsOfFontSet(xfs, &font_struct_list, &font_name_list);
+	for (i = 0; i < n; i++) {
+	  (void) printf("%s\n", font_name_list[i]);
 	}
+#endif
 	return xfs;
 }
 #endif
@@ -3211,6 +3200,9 @@ main(int argc, char **argv)
 	uid_t       ruid;
 	pid_t       cmd_pid = 0;
 
+	/* Configure gettext localization */
+	textdomain("xlock");
+
 #if defined( SYSV ) || defined( SVR4 ) || ( __VMS_VER >= 70000000 )
 	static sigset_t old_sigmask;
 
@@ -3438,7 +3430,7 @@ main(int argc, char **argv)
 			minisizeconfigure.height = flags & HeightValue ? h : iconheight;
 		}
 	}
-
+	
 	planfont = XLoadQueryFont(dsp, planfontname);
 	if (planfont == NULL) {
 		(void) fprintf(stderr, "%s: can't find font: %s, using %s...\n",
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin