diff --git a/Makefile.am b/Makefile.am index ef80f6c..1f62939 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,117 +1,123 @@ # Makefile.am # Copyright (C) 2002, 2012, 2015 g10 Code GmbH # # This file is part of PINENTRY. # # PINENTRY is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # PINENTRY is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ## Process this file with automake to produce Makefile.in ACLOCAL_AMFLAGS = -I m4 DISTCHECK_CONFIGURE_FLAGS = --disable-pinentry-qt --enable-pinentry-emacs GITLOG_TO_CHANGELOG=gitlog-to-changelog EXTRA_DIST = autogen.sh autogen.rc README.GIT ChangeLog-old \ build-aux/gitlog-to-changelog \ build-aux/git-log-fix build-aux/git-log-footer if BUILD_PINENTRY_CURSES pinentry_curses = curses else pinentry_curses = endif if BUILD_PINENTRY_TTY pinentry_tty = tty else pinentry_tty = endif if BUILD_PINENTRY_EMACS pinentry_emacs = emacs else pinentry_emacs = endif if BUILD_PINENTRY_GTK_2 pinentry_gtk_2 = gtk+-2 else pinentry_gtk_2 = endif if BUILD_PINENTRY_GNOME_3 pinentry_gnome_3 = gnome3 else pinentry_gnome_3 = endif if BUILD_PINENTRY_QT pinentry_qt = qt else pinentry_qt = endif if BUILD_PINENTRY_W32 pinentry_w32 = w32 else pinentry_w32 = endif +if BUILD_PINENTRY_FLTK +pinentry_fltk = fltk +else +pinentry_fltk = +endif + SUBDIRS = m4 secmem pinentry ${pinentry_curses} ${pinentry_tty} \ ${pinentry_emacs} ${pinentry_gtk_2} ${pinentry_gnome_3} \ - ${pinentry_qt} ${pinentry_w32} doc + ${pinentry_qt} ${pinentry_w32} ${pinentry_fltk} doc install-exec-local: @list='$(bin_PROGRAMS)'; for p in $$list; do \ echo " $(SETCAP) cap_ipc_lock+p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ $(SETCAP) cap_ipc_lock+p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'` || true; \ done (cd $(DESTDIR)$(bindir); \ rm -f pinentry; \ $(LN_S) $(PINENTRY_DEFAULT)$(EXEEXT) pinentry) dist-hook: gen-ChangeLog echo "$(VERSION)" > $(distdir)/VERSION distcheck-hook: set -e; ( \ pref="#+macro: pinentry_" ;\ reldate="$$(date -u +%Y-%m-%d)" ;\ echo "$${pref}ver $(PACKAGE_VERSION)" ;\ echo "$${pref}date $${reldate}" ;\ list='$(DIST_ARCHIVES)'; for i in $$list; do \ case "$$i" in *.tar.bz2) \ echo "$${pref}size $$(wc -c <$$i|awk '{print int($$1/1024)}')k" ;\ echo "$${pref}sha1 $$(sha1sum <$$i|cut -d' ' -f1)" ;\ echo "$${pref}sha2 $$(sha256sum <$$i|cut -d' ' -f1)" ;;\ esac;\ done ) | tee $(distdir).swdb gen_start_date = 2012-08-08T00:00:00 .PHONY: gen-ChangeLog gen-ChangeLog: if test -d $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ $(GITLOG_TO_CHANGELOG) --append-dot --tear-off \ --amend=build-aux/git-log-fix \ --since=$(gen_start_date) ) > $(distdir)/cl-t; \ cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\ rm -f $(distdir)/ChangeLog; \ mv $(distdir)/cl-t $(distdir)/ChangeLog; \ fi diff --git a/NEWS b/NEWS index 16988fa..107a65d 100644 --- a/NEWS +++ b/NEWS @@ -1,356 +1,357 @@ Noteworthy changes in version 1.0.1 (unreleased) ------------------------------------------------ + * A FLTK1.3-based pinentry has been contributed. Noteworthy changes in version 1.0.0 (2016-11-22) ------------------------------------------------ * Qt pinentry now supports repeat mode in one dialog. * Qt and GTK pinentries now make it possible to show the entered value. * Qt pinentry now only grabs the keyboard if an entry field is focused. * Fixed foreground handling in pinentry-qt if compiled with Qt5 for Windows. * Fixed potential crash in Qt qualitybar calculation. * GTK keyboard grabbing is now a bit more robust. The cursor is changed to a big dot as a visual indication that a pinentry has popped up and is waiting for input. * The GNOME pinentry now falls back to curses if it can't use the GCR system prompter or a screenlock is active. * Fixed error output for cached passwords. * A show/hide passphrase button or checkbox is now available with some pinentry flavors. * Improved diagnostics and error codes. Noteworthy changes in version 0.9.7 (2015-12-07) ------------------------------------------------ * Fix regressions in the Qt pinentry. * Fix minor problems pinnetyr-tty. * New option --invisible-char. Noteworthy changes in version 0.9.6 (2015-09-10) ------------------------------------------------ * Many improvements for the dump tty pinentry. * Use the standard GTK+-2 text entry widget instead of our outdated and back-then-it-was-more-secure text widget. * Use the standard Qt text widget. * Allow for building a static Qt variant. * Fix regression in w32 pinentry. Noteworthy changes in version 0.9.5 (2015-07-01) ------------------------------------------------ * Replaced the internal Assuan and gpg-error code by the standard libassuan and libgpg-error libraries. * Add a new Emacs pinentry and use as fallback for GUI programs. * gnome3: The use-password-manager checkbox does now work. * Gtk: Improved fallback to curses feature. * curses: Recognize DEL as backspace. Noteworthy changes in version 0.9.4 (2015-06-05) ------------------------------------------------ * Fix regression in GTK+ and curses pinentries. Noteworthy changes in version 0.9.3 (2015-06-01) ------------------------------------------------ * Improved documentation * New pinentry-gnome3 * More improvements for pinentry-tty. * Fixes for pinentry-curses including support for Ctrl-W, Ctrl-U, Ctrl-H, Ctrl-L, and Alt-Backspace * New Assuan command to request clearing an external cache. * Fixed problems linking to ncursesw. * All kind of other minor fixes. Noteworthy changes in version 0.9.2 (2015-05-11) ------------------------------------------------ * Support for saving the passphrase with libsecret. * Escape key works in the Gtk+ pinentry. * Improvements for pinentry-tty. * Minor cleanups for the native Windows pinentry. Noteworthy changes in version 0.9.1 (2015-03-18) ------------------------------------------------ * Fixed build problems for systems without ncurses. * Reworked the option parser to allow building on systems without getopt_long. * Fixed Qt4 build problems. Noteworthy changes in version 0.9.0 (2014-10-26) ------------------------------------------------ * New command SETREPEAT. Currently only supported for Gtk+-2. * Gtk+-2: Pasting using the mouse is now supported. * curses: Check that it is actually connected to a tty. * Removed the old qt-3 and gtk+-1 pinentries. Noteworthy changes in version 0.8.4 (2014-09-18) ------------------------------------------------ * New pinentry-tty version for dumb terminals. * Qt4: New option to enable pasting the passphrase from clipboard * Qt4: Improved accessiblity * Qt4: Raise confirm message windows into foreground * Qt4 (Windows): Improve the way pinentry-qt raises itself in the foreground. * Improved the build system. Noteworthy changes in version 0.8.3 (2013-04-26) ------------------------------------------------ * Build fixes for newer mingw32 toolchains. * Add SETTIMEOUT command for the gtk+-2 pinentry. Noteworthy changes in version 0.8.2 (2012-08-08) ------------------------------------------------ * New SETTIMEOUT command for the qt4 pinentry. * Wide character support for the curses pinentry. * Various bug fixes. Noteworthy changes in version 0.8.1 (2010-12-16) ------------------------------------------------ * The W32 pinentry now supports WindowsCE. * The GTK pinentry now always sticks to the top and properly grabs the keyboard. * The protocol options default-cancel and default-ok now work for the pinentry-gtk2 and pinentry-qt (that is QT3). Noteworthy changes in version 0.8.0 (2010-03-03) ------------------------------------------------ * Beautified the qt4 pinentry * Minor enhancements. Noteworthy changes in version 0.7.6 (2009-06-19) ------------------------------------------------ * Make Gtk+-2 pinentry transient to the root window. * Add Qt4 pinentry. * Add native W32 pinentry. * Fix utf-8 problem in Qt pinentries. * Return GPG_ERR_CANCELED if during a "CONFIRM" command the user closed the window. * Add quality bar. Noteworthy changes in version 0.7.5 (2008-02-15) ------------------------------------------------ * Fix cross compilation for Gtk+-2 pinentry. * New Assuan command GETINFO with subcommands "version" and "pid". Noteworthy changes in version 0.7.4 (2007-11-29) ------------------------------------------------ * Pinentry-gtk-2 and pinentry-qt now support a simple passphrase quality indicator. Noteworthy changes in version 0.7.3 (2007-07-06) ------------------------------------------------ * New command MESSAGE and --one-button compatibility option to CONFIRM. * New Assuan option touch-file to set a file which will be touched after ncurses does not need the display anymore. * New option --colors=FG,BG,SO to set the colors for the curses pinentry. * Pinentry-w32 does now basically work. It needs some finishing though. For example the buttons should resize themself according to the size of the text. Noteworthy changes in version 0.7.2 (2005-01-27) ------------------------------------------------ * Remove bug in configure script that would use installed version of Qt even if another path was explicitely specified with QTDIR. * Honor the rpath setting for Qt. * Add GTK+-2 pinentry. * Install a symbolic link under the name "pinentry" that defaults to pinentry-gtk, pinentry-qt, pinentry-gtk-2, or pinentry-curses, in that order. Noteworthy changes in version 0.7.1 (2004-04-21) ------------------------------------------------ * Removed unneeded Assuan cruft. * Fixes for *BSD. Noteworthy changes in version 0.7.0 (2003-12-23) ------------------------------------------------ * Make UTF8 description (prompt, error message, button texts) work. * Make sure that secmem_term is called before program termination. * Make assuan in Gtk and Curses pinentry use secure memory for storage. * Fixed a bug that would occur if a canceled GETPIN was immediately followed by a CONFIRM. * Disabled undo/redo in Qt pinentry. * Print diagnostics for locale problems and return a new error code in that case. Noteworthy changes in version 0.6.8 (2003-02-07) ------------------------------------------------ * Bug fix in pinentry-qt. Noteworthy changes in version 0.6.7 (2002-11-20) ------------------------------------------------ * Workaround for a bug in the curses version which led to an infinite loop. Noteworthy changes in version 0.6.6 (2002-11-09) ------------------------------------------------ * Fixed handling of DISPLAY and --display for the sake of the curses fallback. * UTF-8 conversion does now work for the GTK+ and CURSES version. Noteworthy changes in version 0.6.5 (2002-09-30) ------------------------------------------------ * Handle Assuan options in the qt version. Noteworthy changes in version 0.6.4 (2002-08-19) ------------------------------------------------ * Handle CONFIRM command in the qt version. Noteworthy changes in version 0.6.3 (2002-06-26) ------------------------------------------------ * Minor bug fixes to the qt version. Noteworthy changes in version 0.6.2 (2002-05-13) ------------------------------------------------ * Error texts can now be percent-escaped. * The Curses pinentry supports multi-line error texts. * The GTK+ and Qt pinentry can fall back to curses if no display is available. Noteworthy changes in version 0.6.1 (2002-04-25) ------------------------------------------------ * The Curses pinentry supports user-provided button texts via the new SETOK and SETCANCEL commands. * The Curses pinentry supports setting the desired character set locale with --lc-ctype and correctly translates the UTF-8 strings into that. Noteworthy changes in version 0.6.0 (2002-04-05) ------------------------------------------------ * Merged all pinentry frontends into a single module. * There is now a Curses frontend. * The curses pinentry supports --ttyname and --ttytype options to set the desired input/output terminal and its type. Noteworthy changes in version 0.5.1 (2002-02-18) ------------------------------------------------ * CONFIRM command works Noteworthy changes in version 0.5.0 (2002-01-04) ------------------------------------------------ * Window layout is somewhat nicer * percent escape sequences do now work for SETDESC and SETERROR diff --git a/configure.ac b/configure.ac index 5119e4a..8b38149 100644 --- a/configure.ac +++ b/configure.ac @@ -1,720 +1,762 @@ # configure.ac # Copyright (C) 1999 Robert Bihlmeyer # Copyright (C) 2001, 2002, 2003, 2004, 2007, 2015, 2016 g10 Code GmbH # # This file is part of PINENTRY. # # PINENTRY is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # PINENTRY is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # (Process this file with autoconf to produce a configure script.) AC_PREREQ(2.69) min_automake_version="1.14" # To build a release you need to create a tag with the version number # (git tag -s pinentry-n.m.k) and run "./autogen.sh --force". Please # bump the version number immediately after the release, do another # commit, and a push so that the git magic is able to work. m4_define(mym4_version, [1.0.1]) # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a # flag indicating a development version (mym4_isgit). Note that the # m4 processing is done by autoconf and not during the configure run. m4_define([mym4_revision], m4_esyscmd([git branch -v 2>/dev/null \ | awk '/^\* / {printf "%s",$3}'])) m4_define([mym4_revision_dec], m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))])) m4_define([mym4_betastring], m4_esyscmd_s([git describe --match 'pinentry-[0-9].[0-9].*[0-9]' \ --long| awk -F- '$3!=0{print"-beta"$3}'])) m4_define([mym4_isgit],m4_if(mym4_betastring,[],[no],[yes])) m4_define([mym4_full_version],[mym4_version[]mym4_betastring]) AC_INIT([pinentry],[mym4_full_version], [https://bugs.gnupg.org]) AC_CONFIG_AUX_DIR([build-aux]) AM_CONFIG_HEADER(config.h) AC_CONFIG_SRCDIR(pinentry/pinentry.h) AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip]) AC_GNU_SOURCE AM_MAINTAINER_MODE AC_CANONICAL_HOST AH_TOP([ #ifndef PINENTRY_CONFIG_H_INCLUDED #define PINENTRY_CONFIG_H_INCLUDED /* Enable gpg-error's strerror macro under W32CE. */ #define GPG_ERR_ENABLE_ERRNO_MACROS 1 ]) AH_BOTTOM([ #endif /*PINENTRY_CONFIG_H_INCLUDED*/ ]) dnl Checks for programs. AC_PROG_MAKE_SET AM_SANITY_CHECK missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_RANLIB # We need to check for cplusplus here because we may not do the test # for Qt and autoconf does does not allow that. AC_PROG_CXX AC_PROG_LN_S AC_CHECK_TOOL(WINDRES, windres, :) AC_CHECK_PROGS(GITLOG_TO_CHANGELOG, gitlog-to-changelog, [build-aux/gitlog-to-changelog]) have_dosish_system=no have_w32_system=no have_w32ce_system=no case "${host}" in *-mingw32*) AC_DEFINE(USE_ONLY_8DOT3,1, [Set this to limit filenames to the 8.3 format]) have_dosish_system=yes have_w32_system=yes case "${host}" in *-mingw32ce*) have_w32ce_system=yes ;; *) AC_DEFINE(HAVE_DRIVE_LETTERS,1, [Defined if the OS supports drive letters.]) ;; esac ;; i?86-emx-os2 | i?86-*-os2*emx ) # OS/2 with the EMX environment AC_DEFINE(HAVE_DRIVE_LETTERS) have_dosish_system=yes ;; i?86-*-msdosdjgpp*) # DOS with the DJGPP environment AC_DEFINE(HAVE_DRIVE_LETTERS) have_dosish_system=yes ;; esac if test "$have_dosish_system" = yes; then AC_DEFINE(HAVE_DOSISH_SYSTEM,1, [Defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2) with special properties like no file modes]) fi AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = yes) if test "$have_w32_system" = yes; then AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system]) if test "$have_w32ce_system" = yes; then AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE]) fi fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes) dnl Checks for compiler features. if test "$GCC" = yes; then # Check whether gcc does not emit a diagnositc for unknown -Wno-* # options. This is the case for gcc >= 4.6 AC_MSG_CHECKING([if gcc ignores unknown -Wno-* options]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6 ) #kickerror #endif]],[])],[_gcc_silent_wno=yes],[_gcc_silent_wno=no]) AC_MSG_RESULT($_gcc_silent_wno) if test "$USE_MAINTAINER_MODE" = "yes"; then CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security" if test x"$_gcc_silent_wno" = xyes ; then _gcc_warn=yes else AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers]) _gcc_cflags_save=$CFLAGS CFLAGS="-Wno-missing-field-initializers" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], [_gcc_warn=yes],[_gcc_warn=no]) AC_MSG_RESULT($_gcc_warn) CFLAGS=$_gcc_cflags_save; fi if test x"$_gcc_warn" = xyes ; then CFLAGS="$CFLAGS -W -Wno-sign-compare -Wno-missing-field-initializers" fi AC_MSG_CHECKING([if gcc supports -Wdeclaration-after-statement]) _gcc_cflags_save=$CFLAGS CFLAGS="-Wdeclaration-after-statement" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_warn=yes,_gcc_warn=no) AC_MSG_RESULT($_gcc_warn) CFLAGS=$_gcc_cflags_save; if test x"$_gcc_warn" = xyes ; then CFLAGS="$CFLAGS -Wdeclaration-after-statement" fi else # Not in maintainer mode: Use standard warnings. CFLAGS="$CFLAGS -Wall" fi CPPFLAGS="$CPPFLAGS -Wall" if test x"$_gcc_silent_wno" = xyes ; then _gcc_warn=yes else AC_MSG_CHECKING([if gcc supports -Wno-pointer-sign]) _gcc_cflags_save=$CFLAGS CFLAGS="-Wno-pointer-sign" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],[_gcc_warn=yes],[_gcc_warn=no]) AC_MSG_RESULT($_gcc_warn) CFLAGS=$_gcc_cflags_save; fi if test x"$_gcc_warn" = xyes ; then CFLAGS="$CFLAGS -Wno-pointer-sign" fi AC_MSG_CHECKING([if gcc supports -Wpointer-arith]) _gcc_cflags_save=$CFLAGS CFLAGS="-Wpointer-arith" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_warn=yes,_gcc_warn=no) AC_MSG_RESULT($_gcc_warn) CFLAGS=$_gcc_cflags_save; if test x"$_gcc_warn" = xyes ; then CFLAGS="$CFLAGS -Wpointer-arith" fi fi # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(string.h unistd.h langinfo.h termio.h locale.h utime.h wchar.h) dnl Checks for library functions. AC_CHECK_FUNCS(seteuid stpcpy mmap) GNUPG_CHECK_MLOCK dnl Checks for standard types. AC_TYPE_UINT32_T # Common libraries and cflags. COMMON_CFLAGS= COMMON_LIBS= AC_SUBST(COMMON_CFLAGS) AC_SUBST(COMMON_LIBS) dnl Checks for libgpg-error # # libgpg-error is a library with error codes shared between GnuPG # related projects. # NEED_GPG_ERROR_VERSION=1.16 have_gpg_error=no AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", have_gpg_error=yes,have_gpg_error=no) COMMON_CFLAGS="$GPG_ERROR_CFLAGS $COMMON_CFLAGS" COMMON_LIBS="$GPG_ERROR_LIBS $COMMON_LIBS" AC_DEFINE_UNQUOTED(GPG_ERR_ENABLE_GETTEXT_MACROS, 1, [Under Windows we use the gettext code from libgpg-error]) AC_DEFINE_UNQUOTED(GPG_ERR_ENABLE_ERRNO_MACROS, 1, [Under WindowsCE we use the strerror replacement from libgpg-error.]) dnl Checks for libassuan. # # libassuan is used for IPC # NEED_LIBASSUAN_API=2 NEED_LIBASSUAN_VERSION=2.1.0 have_libassuan=no AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", have_libassuan=yes,have_libassuan=no) if test "$have_libassuan" = "yes"; then AC_DEFINE_UNQUOTED(GNUPG_LIBASSUAN_VERSION, "$libassuan_version", [version of the libassuan library]) fi COMMON_CFLAGS="$LIBASSUAN_CFLAGS $COMMON_CFLAGS" COMMON_LIBS="$LIBASSUAN_LIBS $COMMON_LIBS" dnl Checks for libsecmem. GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF) GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF) dnl Check for libcap AC_ARG_WITH([libcap], AC_HELP_STRING([--without-libcap], [Disable support for capabilities library])) if test "x$with_libcap" != "xno"; then AC_PATH_PROG(SETCAP, setcap, :, "$PATH:/sbin:/usr/sbin") AC_CHECK_LIB(cap, cap_set_proc, [ AC_DEFINE(USE_CAPABILITIES,1,[The capabilities support library is installed]) LIBCAP=-lcap ]) fi AC_SUBST(LIBCAP) dnl dnl Check for curses pinentry program. dnl AC_ARG_ENABLE(pinentry-curses, AC_HELP_STRING([--enable-pinentry-curses], [build curses pinentry]), pinentry_curses=$enableval, pinentry_curses=maybe) AC_ARG_ENABLE(fallback-curses, AC_HELP_STRING([--enable-fallback-curses], [include curses fallback]), fallback_curses=$enableval, fallback_curses=maybe) dnl dnl Checks for curses libraries. Deal correctly with $pinentry_curses = maybe dnl and $fallback_curses = maybe. dnl if test "$pinentry_curses" != "no" -o "$fallback_curses" != "no"; then IU_LIB_CURSES fi if test "$LIBCURSES"; then if test "$pinentry_curses" != "no"; then pinentry_curses=yes fi if test "$fallback_curses" != "no"; then fallback_curses=yes AC_DEFINE(FALLBACK_CURSES, 1, [The GUI pinentries should fall back to curses if X is not available.]) fi else if test "$pinentry_curses" = "yes" -o "$fallback_curses" = "yes"; then AC_MSG_ERROR([[ *** *** The curses library is required. The latest version of *** ncurses is always available from ftp://ftp.gnu.org/gnu/ncurses/. ***]]) fi pinentry_curses=no fallback_curses=no fi AM_CONDITIONAL(BUILD_LIBPINENTRY_CURSES, test "$pinentry_curses" = "yes" -o "$fallback_curses" = "yes") AM_CONDITIONAL(BUILD_PINENTRY_CURSES, test "$pinentry_curses" = "yes") AM_CONDITIONAL(FALLBACK_CURSES, test "$fallback_curses" = "yes") if test "$pinentry_curses" = "yes"; then AC_DEFINE(PINENTRY_CURSES, 1, [The Curses version of Pinentry is to be build]) fi dnl dnl Check for tty pinentry program. dnl AC_ARG_ENABLE(pinentry-tty, AC_HELP_STRING([--enable-pinentry-tty], [build tty pinentry]), pinentry_tty=$enableval, pinentry_tty=maybe) AM_CONDITIONAL(BUILD_PINENTRY_TTY, test "$pinentry_tty" = "yes") if test "$pinentry_tty" = "yes"; then AC_DEFINE(PINENTRY_TTY, 1, [The TTY version of Pinentry is to be build]) fi dnl dnl Additional checks pinentry Curses. dnl if test "$pinentry_curses" = "yes" \ -o "$fallback_curses" = "yes" ; then AM_ICONV if test "$am_cv_func_iconv" != "yes"; then AC_MSG_ERROR([[ *** *** The iconv function is required. You can specify its location *** using the --with-libiconv-prefix=PREFIX option to configure. ***]]) fi fi dnl dnl Check for emacs pinentry program. dnl AC_ARG_ENABLE(pinentry-emacs, AC_HELP_STRING([--enable-pinentry-emacs], [build emacs pinentry]), pinentry_emacs=$enableval, pinentry_emacs=no) AC_ARG_ENABLE(inside-emacs, AC_HELP_STRING([--enable-inside-emacs], [include emacs hack]), inside_emacs=$enableval, inside_emacs=maybe) if test "$pinentry_emacs" != "no" -o "$inside_emacs" != "no"; then AC_MSG_CHECKING([if Unix domain socket is supported]) AC_TRY_COMPILE([ #include #include ], [int s = socket (AF_UNIX, SOCK_STREAM, 0);], [_unixsock_works=yes], [_unixsock_works=no]) AC_MSG_RESULT($_unixsock_works) if test "$_unixsock_works" = "yes"; then if test "$pinentry_emacs" != "no"; then pinentry_emacs=yes fi if test "$inside_emacs" != "no"; then inside_emacs=yes AC_DEFINE(INSIDE_EMACS, 1, [The GUI pinentries should respect INSIDE_EMACS envvar.]) fi else if test "$pinentry_emacs" = "yes" -o "$inside_emacs" = "yes"; then AC_MSG_ERROR([[ *** *** Support for Unix domain sockets is required. ***]]) fi pinentry_emacs=no inside_emacs=no fi fi AM_CONDITIONAL(BUILD_LIBPINENTRY_EMACS, test "$pinentry_emacs" = "yes" -o "$inside_emacs" = "yes") AM_CONDITIONAL(BUILD_PINENTRY_EMACS, test "$pinentry_emacs" = "yes") AM_CONDITIONAL(INSIDE_EMACS, test "$inside_emacs" = "yes") if test "$pinentry_emacs" = "yes"; then AC_DEFINE(PINENTRY_EMACS, 1, [The Emacs version of Pinentry is to be build]) fi dnl dnl Check for GTK+-2 / GNOME3 pinentry programs. dnl AC_ARG_ENABLE(pinentry-gtk2, AC_HELP_STRING([--enable-pinentry-gtk2], [build GTK+-2 pinentry]), pinentry_gtk_2=$enableval, pinentry_gtk_2=maybe) AC_ARG_ENABLE(pinentry-gnome3, AC_HELP_STRING([--enable-pinentry-gnome3], [build GNOME 3 pinentry]), pinentry_gnome_3=$enableval, pinentry_gnome_3=maybe) dnl check for pkg-config if test "$pinentry_gtk_2" != "no" -o "$pinentry_gnome_3" != "no"; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) if test x"${PKG_CONFIG}" = xno ; then pinentry_gtk_2=no pinentry_gnome_3=no fi fi dnl check if the module gtk+-2.0 exists if test "$pinentry_gtk_2" != "no"; then AC_MSG_CHECKING([for gtk+-2]) "${PKG_CONFIG}" --exists gtk+-2.0 if test $? -ne 0 ; then AC_MSG_RESULT([no]) AC_MSG_WARN([pkg-config could not find the module gtk+-2.0]) pinentry_gtk_2=no else AC_MSG_RESULT([yes]) AC_MSG_CHECKING([gtk+-2 version >= 2.4.0]) modvers=`"${PKG_CONFIG}" --modversion gtk+-2.0` AC_MSG_RESULT([$modvers]) "${PKG_CONFIG}" --atleast-version=2.4.0 gtk+-2.0 if test $? -ne 0 ; then AC_MSG_WARN([building GTK+-2 pinentry disabled]) pinentry_gtk_2=no else GTK2CFLAGS=`"${PKG_CONFIG}" --cflags gtk+-2.0` GTK2LIBS=`"${PKG_CONFIG}" --libs gtk+-2.0` AC_SUBST(GTK2CFLAGS) AC_SUBST(GTK2LIBS) if test "$pinentry_gtk_2" != "no" then pinentry_gtk_2=yes fi fi fi fi AM_CONDITIONAL(BUILD_PINENTRY_GTK_2, test "$pinentry_gtk_2" = "yes") if test "$pinentry_gnome_3" != "no"; then AC_MSG_CHECKING([for gcr]) "${PKG_CONFIG}" --exists gcr-base-3 if test $? -ne 0 ; then AC_MSG_RESULT([no]) AC_MSG_WARN([pkg-config could not find the module gcr-base-3]) pinentry_gnome_3=no else AC_MSG_RESULT([yes]) GNOME3CFLAGS=`"${PKG_CONFIG}" --cflags gcr-base-3` GNOME3LIBS=`"${PKG_CONFIG}" --libs gcr-base-3` AC_SUBST(GNOME3CFLAGS) AC_SUBST(GNOME3LIBS) AC_DEFINE(GCR_API_SUBJECT_TO_CHANGE, 1, [Nod nod]) pinentry_gnome_3=yes fi fi AM_CONDITIONAL(BUILD_PINENTRY_GNOME_3, test "$pinentry_gnome_3" = "yes") dnl dnl Check for libsecret. dnl AC_ARG_ENABLE(libsecret, AC_HELP_STRING([--enable-libsecret], [optionally cache passphrases using libsecret]), libsecret=$enableval, libsecret=maybe) dnl check for pkg-config if test "$libsecret" != "no" -o "$pinentry-qt" != "no"; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) if test x"${PKG_CONFIG}" = xno ; then if test "$pinentry_qt" = "yes"; then AC_MSG_ERROR([[ *** *** pkg-config is required to find the Qt libraries for pinentry-qt ***]]) else pinentry_qt=no fi libsecret=no fi fi dnl check if the module libsecret exists if test "$libsecret" != "no"; then AC_MSG_CHECKING([for libsecret]) "${PKG_CONFIG}" --exists 'libsecret-1' if test $? -ne 0 ; then AC_MSG_RESULT([no]) AC_MSG_WARN([pkg-config could not find the modules libsecret-1]) libsecret=no else AC_MSG_RESULT([yes]) LIBSECRET_CFLAGS=`"${PKG_CONFIG}" --cflags 'libsecret-1'` LIBSECRET_LIBS=`"${PKG_CONFIG}" --libs 'libsecret-1'` libsecret=yes fi fi AM_CONDITIONAL(BUILD_WITH_LIBSECRET, test "$libsecret" = "yes") if test "$libsecret" = "yes"; then AC_DEFINE(HAVE_LIBSECRET, 1, [The pinentries should optionally cache the passphrase using libsecret.]) COMMON_CFLAGS="$LIBSECRET_CFLAGS $COMMON_CFLAGS" COMMON_LIBS="$LIBSECRET_LIBS $COMMON_LIBS" fi dnl dnl Check for Qt pinentry program. dnl AC_ARG_ENABLE(pinentry-qt, AC_HELP_STRING([--enable-pinentry-qt], [build qt pinentry]), pinentry_qt=$enableval, pinentry_qt=maybe) dnl dnl Checks for qt libraries. Deal correctly with $pinentry_qt = maybe. dnl Tries to find Qt5, falls back on Qt4 dnl if test "$pinentry_qt" != "no"; then FIND_QT if test "$have_qt4_libs" != "yes" -a "$have_qt5_libs" != "yes"; then if test "$pinentry_qt" = "yes"; then AC_MSG_ERROR([[ *** *** Qt4 (QtCore, QtGui) or Qt5 (Qt5Core, Qt5Gui, Qt5Widgets) is required. ***]]) else pinentry_qt=no fi fi fi AC_SUBST(PINENTRY_QT_CFLAGS) AC_SUBST(PINENTRY_QT_LIBS) AC_SUBST(MOC) dnl If we have come so far, qt pinentry can be build. if test "$pinentry_qt" != "no"; then pinentry_qt=yes fi AM_CONDITIONAL(BUILD_PINENTRY_QT, test "$pinentry_qt" = "yes") if test "$pinentry_qt" = "yes"; then AC_DEFINE(PINENTRY_QT, 1, [The qt version of Pinentry is to be build]) if test "$have_qt4_libs" = "yes"; then pinentry_qt_lib_version="(Qt4)" else pinentry_qt_lib_version="(Qt5)" fi fi # # Check whether we should build the W32 pinentry. This is actually # the simplest check as we do this only for that platform. # pinentry_w32=no test $have_w32_system = yes && pinentry_w32=yes AM_CONDITIONAL(BUILD_PINENTRY_W32, test "$pinentry_w32" = "yes") +dnl +dnl Check for FLTK pinentry program. +dnl +AC_ARG_ENABLE(pinentry-fltk, + AC_HELP_STRING([--enable-pinentry-fltk], [build FLTK 1.3 pinentry]), + pinentry_fltk=$enableval, pinentry_fltk=maybe) + +dnl check for fltk-config +if test "$pinentry_fltk" != "no"; then + AC_PATH_PROG(FLTK_CONFIG, fltk-config, no) + if test x"${FLTK_CONFIG}" = xno ; then + AC_MSG_WARN([fltk-config is not found]) + pinentry_fltk=no + fi +fi + +dnl check for FLTK libraries and set flags +if test "$pinentry_fltk" != "no"; then + AC_MSG_CHECKING([for FLTK 1.3]) + FLTK_VERSION=`${FLTK_CONFIG} --api-version` + if test ${FLTK_VERSION} != "1.3" ; then + AC_MSG_RESULT([no]) + AC_MSG_WARN([FLTK 1.3 not found (available $FLTK_VERSION)]) + pinentry_fltk=no + else + AC_MSG_RESULT([yes]) + FLTKCFLAGS=`${FLTK_CONFIG} --cflags` + FLTKCXXFLAGS=`${FLTK_CONFIG} --cxxflags` + FLTKLIBS=`${FLTK_CONFIG} --ldflags` + AC_SUBST(FLTKCFLAGS) + AC_SUBST(FLTKCXXFLAGS) + AC_SUBST(FLTKLIBS) + pinentry_fltk=yes + fi +fi +AM_CONDITIONAL(BUILD_PINENTRY_FLTK, test "$pinentry_fltk" = "yes") # Figure out the default pinentry. We are very conservative here. # Please change the order only after verifying that the preferred # pinentry really is better (more feature-complete and more secure). if test "$pinentry_gtk_2" = "yes"; then PINENTRY_DEFAULT=pinentry-gtk-2 else if test "$pinentry_qt" = "yes"; then PINENTRY_DEFAULT=pinentry-qt else if test "$pinentry_gnome_3" = "yes"; then PINENTRY_DEFAULT=pinentry-gnome3 else if test "$pinentry_curses" = "yes"; then PINENTRY_DEFAULT=pinentry-curses else if test "$pinentry_tty" = "yes"; then PINENTRY_DEFAULT=pinentry-tty else if test "$pinentry_w32" = "yes"; then PINENTRY_DEFAULT=pinentry-w32 else - AC_MSG_ERROR([[No pinentry enabled.]]) + if test "$pinentry_fltk" = "yes"; then + PINENTRY_DEFAULT=pinentry-fltk + else + AC_MSG_ERROR([[No pinentry enabled.]]) + fi fi fi fi fi fi fi AC_SUBST(PINENTRY_DEFAULT) # # Print errors here so that they are visible all # together and the user can acquire them all together. # die=no if test "$have_gpg_error" = "no"; then die=yes AC_MSG_NOTICE([[ *** *** You need libgpg-error to build this program. ** This library is for example available at *** ftp://ftp.gnupg.org/gcrypt/libgpg-error *** (at least version $NEED_GPG_ERROR_VERSION is required.) ***]]) fi if test "$have_libassuan" = "no"; then die=yes AC_MSG_NOTICE([[ *** *** You need libassuan to build this program. *** This library is for example available at *** ftp://ftp.gnupg.org/gcrypt/libassuan/ *** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required). ***]]) fi if test "$die" = "yes"; then AC_MSG_ERROR([[ *** *** Required libraries not found. Please consult the above messages *** and install them before running configure again. ***]]) fi # # To avoid double inclusion of config.h which might happen at some # places, we add the usual double inclusion protection at the top of # config.h. # AH_TOP([ #ifndef GNUPG_CONFIG_H_INCLUDED #define GNUPG_CONFIG_H_INCLUDED ]) # # Stuff which goes at the bottom of config.h. # AH_BOTTOM([ #ifdef GPG_ERR_SOURCE_DEFAULT # error GPG_ERR_SOURCE_DEFAULT already defined #endif #define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_PINENTRY #endif /*GNUPG_CONFIG_H_INCLUDED*/ ]) AC_CONFIG_FILES([ m4/Makefile secmem/Makefile pinentry/Makefile curses/Makefile tty/Makefile emacs/Makefile gtk+-2/Makefile gnome3/Makefile qt/Makefile w32/Makefile +fltk/Makefile doc/Makefile Makefile ]) AC_OUTPUT AC_MSG_NOTICE([ Pinentry v${VERSION} has been configured as follows: Revision: mym4_revision (mym4_revision_dec) Platform: $host Curses Pinentry ..: $pinentry_curses TTY Pinentry .....: $pinentry_tty Emacs Pinentry ...: $pinentry_emacs GTK+-2 Pinentry ..: $pinentry_gtk_2 GNOME 3 Pinentry .: $pinentry_gnome_3 Qt Pinentry ......: $pinentry_qt $pinentry_qt_lib_version W32 Pinentry .....: $pinentry_w32 + FLTK Pinentry ....: $pinentry_fltk Fallback to Curses: $fallback_curses Emacs integration : $inside_emacs libsecret ........: $libsecret Default Pinentry .: $PINENTRY_DEFAULT ]) diff --git a/fltk/Makefile.am b/fltk/Makefile.am new file mode 100644 index 0000000..2c9338f --- /dev/null +++ b/fltk/Makefile.am @@ -0,0 +1,16 @@ +# Makefile.am - PIN entry FLTK frontend. + +bin_PROGRAMS = pinentry-fltk + +if FALLBACK_CURSES +ncurses_include = $(NCURSES_INCLUDE) +libcurses = ../pinentry/libpinentry-curses.a $(LIBCURSES) $(LIBICONV) +else +ncurses_include = +libcurses = +endif + +AM_CPPFLAGS = $(COMMON_CFLAGS) $(FLTKCXXFLAGS) $(ncurses_include) -I$(top_srcdir)/secmem -I$(top_srcdir)/pinentry +LDADD = ../pinentry/libpinentry.a ../secmem/libsecmem.a $(COMMON_LIBS) $(LIBCAP) $(FLTKLIBS) $(libcurses) + +pinentry_fltk_SOURCES = main.cxx pinwindow.cxx passwindow.cxx qualitypasswindow.cxx diff --git a/fltk/encrypt.xpm b/fltk/encrypt.xpm new file mode 100644 index 0000000..80402e3 --- /dev/null +++ b/fltk/encrypt.xpm @@ -0,0 +1,83 @@ +/* XPM */ +static const char * const encrypt_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 45 32 1 ", +" c #9B7738", +". c #B08830", +"X c #CA9703", +"o c #C99607", +"O c #CD9A02", +"+ c #D19D03", +"@ c #D4A002", +"# c #D7A305", +"$ c #D8A501", +"% c #DFAB01", +"& c #DCA803", +"* c #E3B103", +"= c #E7B702", +"- c #C39A31", +"; c #D4AC2F", +": c #E6BE26", +"> c #EFC002", +", c #F5CD06", +"< c #FEE21D", +"1 c #FCE01F", +"2 c #F6D424", +"3 c #B49A55", +"4 c #CAAC5F", +"5 c #FCE854", +"6 c #888887", +"7 c #9A9A9A", +"8 c #A7A7A7", +"9 c #B8B8B7", +"0 c #F3F08F", +"q c #C3C3C3", +"w c gray85", +"e c None", +/* pixels */ +"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", +"eeeeeeeeeee889qqqq987eeeeeeeeeee", +"eeeeeeeee89qwwwqqwwww88eeeeeeeee", +"eeeeeeee99qq877777669wq8eeeeeeee", +"eeeeeee99q888888888876ww9eeeeeee", +"eeeeee99q888888887778869q9eeeeee", +"eeeee89q8888eeeeeeee7786wq8eeeee", +"eeeee999888eeeeeeeeee7777wqeeeee", +"eeee899778eeeeeeeeeeee776wq8eeee", +"eeee8q977eeeeeeeeeeeeee779q9eeee", +"eeee8q977eeeeeeeeeeeeee777w9eeee", +"eeee8q867eeeeeeeeeeeeee776wqeeee", +"eeee8q768eeeeeeeeeeeeee766wqeeee", +"eeee8q768eeeeeeeeeeeeee766wqeeee", +"eeee8q778eeeeeeeeeeeeee776wqeeee", +"eeee8q778eeeeeeeeeeeeee776wqeeee", +"eeee8q888eeeeeeeeeeeeee786wqeeee", +"eeee8q888eeeeeeeeeeeeee786wqeeee", +"eeee8q898eeeeeeeeeeeeee796wqeeee", +"eeee8q898eeeeeeeeeeeeee896wqeeee", +"e45444443333 3333444003e", +"e4552::;;--... ...--;;:25003e", +"e4552,>>=&@OXXooXO+@$&*=>,15003e", +"e4552,>>*&#+ooooo++##&*=>,15003e", +"e4552,>>*&#+XXXXXO+@#&*=>,<5003e", +"e4552,>>=%$+OXXOO++##&*=>,15003e", +"e4552,>>=%$OooXXO+@@#&%=,,<5003e", +"e4552,>>=%$@OXXO+@@#&&*=>,15003e", +"e4552,>>*&$+XXXXOO++@#%=>,<5003e", +"e4552,>>=&$+OXXO++@@$&*=,,<5003e", +"e4552,>>=%$+XXXXOO+@#&*=>,<5003e", +"e4552,>>*&#+ooXO++@##&*>,,<5003e", +"e4552,>>=%$@OXXO++@$$%*>,,<5003e", +"e4552,>>=%$+OXXO++@#$&*=,,<5003e", +"e4552,>>=%$@OOOO++@$&%*=>,<5003e", +"e4552,>>=%$+OXXOO+@#&%=>,,<5003e", +"e4552,>>=%$+OXXOO+@##%*=>,<5003e", +"e4552,>>*&#+oooO++@#&&*>,,<5003e", +"e4552,>>=%$@OOOO+@$&%%*>,,<5003e", +"e4552,>>=%$@OOXO+@$&%%*>,,<5003e", +"e4552,>>=%$+OXXO+@$&&%*>,,<5003e", +"e4552,>>=%$@OOO+@@$&%%=>,,<5003e", +"e4552,>>=%$@OOO+@@$&%%=>,,<5003e", +"e4552,>>=%$@OOO+@@$&%%=>,,<5003e", +"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" +}; diff --git a/fltk/icon.xpm b/fltk/icon.xpm new file mode 100644 index 0000000..eed3cd6 --- /dev/null +++ b/fltk/icon.xpm @@ -0,0 +1,37 @@ +/* XPM */ +static const char *const icon_xpm[] = { +"31 29 3 1 ", +" c black", +". c yellow", +"X c None", + +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +" XXXXXXXXXXXXXXXXXX", +" ........... XXXXXXXXXXXXXXXXXX", +" ........... XXXXXXXXXXXXXXXXXX", +" ... ... XXXXXXXXXXXXXXXXXX", +" ... XXX ... ", +" ... XXX ... ................. ", +" ... XXX ... ................. ", +" ... XXX ... ... ... ", +" ... ... XXXXXXX ... X ... ", +" ........... XXXXXXX ... X ... ", +" ........... XXXXXXX X ... ", +" XXXXXXXXXXXXX ", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; diff --git a/fltk/main.cxx b/fltk/main.cxx new file mode 100644 index 0000000..7526656 --- /dev/null +++ b/fltk/main.cxx @@ -0,0 +1,391 @@ +/* + main.cpp - A Fltk based dialog for PIN entry. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define PGMNAME (PACKAGE_NAME"-fltk") + +#include +#include +#include +#include +#include +#include + +#include "memory.h" +#include + +#include +#ifdef FALLBACK_CURSES +#include +#endif + +#include +#include +#include + + +#include +#include +#include + +#include "pinwindow.h" +#include "passwindow.h" +#include "qualitypasswindow.h" + +#define CONFIRM_STRING "Confirm" +#define REPEAT_ERROR_STRING "Texts do not match" +#define OK_STRING "OK" +#define CANCEL_STRING "Cancel" + +char *application = NULL; + +static std::string escape_accel_utf8(const char *s) +{ + std::string result; + if (NULL != s) + { + result.reserve(strlen(s)); + for (const char *p = s; *p; ++p) + { + if ('&' == *p) + result.push_back(*p); + result.push_back(*p); + } + } + return result; +} + +class cancel_exception +{ + +}; + +static int get_quality(const char *passwd, void *ptr) +{ + if (NULL == passwd || 0 == *passwd) + return 0; + + pinentry_t* pe = reinterpret_cast(ptr); + return pinentry_inq_quality(*pe, passwd, strlen(passwd)); +} + +bool is_short(const char *str) +{ + return fl_utf_nb_char(reinterpret_cast(str), strlen(str)) < 16; +} + +bool is_empty(const char *str) +{ + return (NULL == str) || (0 == *str); +} + +static int fltk_cmd_handler(pinentry_t pe) +{ + int ret = -1; + + try + { + // TODO: Add parent window to pinentry-fltk window + //if (pe->parent_wid){} + std::string title = !is_empty(pe->title)?pe->title:PGMNAME; + std::string ok = escape_accel_utf8(pe->ok?pe->ok:(pe->default_ok?pe->default_ok:OK_STRING)); + std::string cancel = escape_accel_utf8(pe->cancel?pe->cancel:(pe->default_cancel?pe->default_cancel:CANCEL_STRING)); + + if (!!pe->pin) // password (or confirmation) + { + std::auto_ptr window; + + bool isSimple = (NULL == pe->quality_bar) && // pinenty.h: If this is not NULL ... + is_empty(pe->error) && is_empty(pe->description) && + is_short(pe->prompt); + if (isSimple) + { + assert(NULL == pe->description); + window.reset(PinWindow::create()); + window->prompt(pe->prompt); + } + else + { + PassWindow *pass = NULL; + + if (pe->quality_bar) // pinenty.h: If this is not NULL ... + { + QualityPassWindow *p = QualityPassWindow::create(get_quality, &pe); + window.reset(p); + pass = p; + p->quality(pe->quality_bar); + } + else + { + pass = PassWindow::create(); + window.reset(pass); + } + + if (NULL == pe->description) + { + pass->description(pe->prompt); + pass->prompt(" "); + } + else + { + pass->description(pe->description); + pass->prompt(escape_accel_utf8(pe->prompt).c_str()); + } + pass->description(pe->description); + pass->prompt(escape_accel_utf8(pe->prompt).c_str()); + + + if (NULL != pe->error) + pass->error(pe->error); + } + + window->ok(ok.c_str()); + window->cancel(cancel.c_str()); + window->title(title.c_str()); + window->showModal((NULL != application)?1:0, &application); + + if (NULL == window->passwd()) + throw cancel_exception(); + + const std::string password = window->passwd(); + window.reset(); + + if (pe->repeat_passphrase) + { + const char *dont_match = NULL; + do + { + if (NULL == dont_match && is_short(pe->repeat_passphrase)) + { + window.reset(PinWindow::create()); + window->prompt(escape_accel_utf8(pe->repeat_passphrase).c_str()); + } + else + { + PassWindow *pass = PassWindow::create(); + window.reset(pass); + pass->description(pe->repeat_passphrase); + pass->prompt(" "); + pass->error(dont_match); + } + + window->ok(ok.c_str()); + window->cancel(cancel.c_str()); + window->title(title.c_str()); + window->showModal(); + + if (NULL == window->passwd()) + throw cancel_exception(); + + if (password == window->passwd()) + { + pe->repeat_okay = 1; + ret = 1; + break; + } + else + { + dont_match = (NULL!=pe->repeat_error_string)? pe->repeat_error_string:REPEAT_ERROR_STRING; + } + } while (true); + } + else + ret = 1; + + pinentry_setbufferlen(pe, password.size()+1); + if (pe->pin) + { + memcpy(pe->pin, password.c_str(), password.size()+1); + pe->result = password.size(); + ret = password.size(); + } + } + else + { + // Confirmation or Message Dialog title, desc + Fl_Window dummy(0,0, 1,1); + + dummy.border(0); + dummy.show((NULL != application)?1:0, &application); + dummy.hide(); + + fl_message_title(title.c_str()); + + int result = -1; + + const char *message = (NULL != pe->description)?pe->description:CONFIRM_STRING; + + if (pe->one_button) + { + fl_ok = ok.c_str(); + fl_message(message); + result = 1; // OK + } + else if (pe->notok) + { + switch (fl_choice(message, ok.c_str(), cancel.c_str(), pe->notok)) + { + case 0: result = 1; break; + case 2: result = 0; break; + default: + case 1: result = -1;break; + } + } + else + { + switch (fl_choice(message, ok.c_str(), cancel.c_str(), NULL)) + { + case 0: result = 1; break; + default: + case 1: result = -1;break; + } + } + + // cancel -> pe->canceled = true, 0 + // ok/y -> 1 + // no -> 0 + if (-1 == result) + pe->canceled = true; + ret = (1 == result); + } + Fl::check(); + } + catch (const cancel_exception&) + { + ret = -1; + } + catch (...) + { + ret = -1; + } + // do_touch_file(pe); only for NCURSES? + return ret; + } + +pinentry_cmd_handler_t pinentry_cmd_handler = fltk_cmd_handler; + +int main(int argc, char *argv[]) +{ + application = *argv; + pinentry_init(PGMNAME); + +#ifdef FALLBACK_CURSES + if (!pinentry_have_display(argc, argv)) + pinentry_cmd_handler = curses_cmd_handler; + else +#endif + { + //FLTK understood only -D (--display) + // and should be converted into -di[splay] + const static struct option long_options[] = + { + {"display", required_argument, 0, 'D' }, + {NULL, no_argument, 0, 0 } + }; + + for (int i = 0; i < argc-1; ++i) + { + switch (getopt_long(argc-i, argv+i, "D:", long_options, NULL)) + { + case 'D': + { + char* emul[] = {application, (char*)"-display", optarg}; + Fl::args(3, emul); + i = argc; + break; + } + default: + break; + } + } + } + + pinentry_parse_opts(argc, argv); + return pinentry_loop() ?EXIT_FAILURE:EXIT_SUCCESS; +} + +/* +int get_quality(const char *pass) +{ + size_t len = strlen(pass); + return len>4?(80+len):-len*10; +} + +int main(int argc, char *argv[]) +{ + std::auto_ptr window; + window.reset(QualityPassWindow::create(get_quality)); + +// window->message("Lorem ipsum dolor sit amet"); +// window->message("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor. Phasellus tempor orci vel metus eleifend ultrices. Curabitur tempor euismod lorem"); + window->prompt("Lorem ipsum:"); + window->ok("YES!"); + window->cancel("OTMEHA"); +// window->error("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla"); +// window->error("Some error ellus adipiscing elit portt text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor a porttitor!"); + window->timeout(100); + window->title(PGMNAME); + window->showModal(argc, argv); + return 0; +} +// */ + +/* +int main(int argc, char *argv[]) +{ + Fl::args(argc, argv); + std::auto_ptr window; + window.reset(PinWindow::create()); +// window->message("PIN:"); +// window->message("Phasellus adipiscing elit porttitor nisi a fringilla porttitor:"); + window->ok("YES!"); + window->cancel("OTMEHA"); + window->timeout(100); + window->title(PGMNAME); + window->showModal(argc, argv); + return 0; +} +// */ + +/* +int main(int argc, char *argv[]) +{ + Fl::args(argc, argv); + std::auto_ptr window; + window.reset(PassWindow::create()); +// window->message("Descr&iption"); +// window->message("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor:"); +// window->prompt("Prompt sit amet:"); + window->ok("YES!"); + window->cancel("OTMEHA"); +// window->error("Password is empty."); +// window->error("Some error text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor!"); +// window->error("Some error ellus adipiscing elit portt text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor!"); + window->timeout(100); + window->title(PGMNAME); + window->showModal(argc, argv); + return 0; +} +// */ diff --git a/fltk/passwindow.cxx b/fltk/passwindow.cxx new file mode 100644 index 0000000..78b3b2c --- /dev/null +++ b/fltk/passwindow.cxx @@ -0,0 +1,85 @@ +/* + passwindow.cxx - PassWindow is a more complex fltk dialog with more longer + desc field and possibility to show some error text. + if needed qualitybar - should be used QualityPassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "passwindow.h" + +#include +#include +#include + +const char *PassWindow::DESCRIPTION = "Please enter the passphrase:"; + +PassWindow::PassWindow() : error_(NULL) +{ +} + +void PassWindow::prompt(const char *name) +{ + set_label(input_, name, PROMPT); +} + +void PassWindow::description(const char *name) +{ + set_label(message_, name, DESCRIPTION); +} + +void PassWindow::error(const char *name) +{ + set_label(error_, name, ""); +} + +int PassWindow::init(const int cx, const int cy) +{ + int y = PinWindow::init(cx, cy); + + assert(window_ == Fl_Group::current()); // make_window should all add current + + y = icon_->y(); // move back to icon's + + const int mx = icon_->x()+icon_->w(); + message_->resize(mx, icon_->y(), cx-mx-10, icon_->h()); + message_->align(Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); + description(NULL); + y += icon_->h(); + + input_->resize(130, y+5, cx-150, 25); + input_->labeltype(FL_NORMAL_LABEL); + prompt(NULL); + y = input_->y()+input_->h(); + + error_ = new Fl_Box(20, y+5, cx-30, 30); + error_->labelcolor(FL_RED); + error_->align(Fl_Align(FL_ALIGN_CENTER | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); // if not fit - user can read + y = error_->y()+error_->h(); + return y; +} + +PassWindow* PassWindow::create() +{ + PassWindow* p = new PassWindow; + p->init(460, 185); + p->window_->end(); + p->input_->take_focus(); + return p; +} diff --git a/fltk/passwindow.h b/fltk/passwindow.h new file mode 100644 index 0000000..43813cd --- /dev/null +++ b/fltk/passwindow.h @@ -0,0 +1,50 @@ +/* + passwindow.h - PassWindow is a more complex fltk dialog with more longer + desc field and possibility to show some error text. + if needed qualitybar - should be used QualityPassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __PASSWINDOW_H__ +#define __PASSWINDOW_H__ + +#include "pinwindow.h" + +class PassWindow : public PinWindow +{ +protected: + static const char *DESCRIPTION; + +protected: + Fl_Box *error_; + PassWindow(); + +public: + virtual void prompt(const char *message); + virtual void description(const char *desc); + virtual void error(const char *err); + + static PassWindow* create(); + +protected: + virtual int init(const int cx, const int cy); +}; + +#endif //#ifndef __PASSWINDOW_H__ diff --git a/fltk/pinwindow.cxx b/fltk/pinwindow.cxx new file mode 100644 index 0000000..ad11e91 --- /dev/null +++ b/fltk/pinwindow.cxx @@ -0,0 +1,250 @@ +/* + pinwindow.cxx - PinWindow is a simple fltk dialog for entring password + with timeout. if needed description (long text), error message, qualitybar + and etc should used PassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "memory.h" + +#include "encrypt.xpm" +#include "icon.xpm" + +#include "pinwindow.h" + +const char *PinWindow::TITLE = "Password"; +const char *PinWindow::BUTTON_OK = "OK"; +const char *PinWindow::BUTTON_CANCEL = "Cancel"; +const char *PinWindow::PROMPT = "Passphrase:"; + +static const char *timeout_format = "%s(%d)"; + +static Fl_Pixmap encrypt(encrypt_xpm); +static Fl_Pixmap icon(icon_xpm); + +PinWindow::PinWindow() : window_(NULL) + ,message_(NULL) ,input_(NULL) ,ok_(NULL) ,cancel_(NULL) + ,cancel_name_(BUTTON_CANCEL) + ,passwd_(NULL) ,timeout_(0) +{ +} + +PinWindow::~PinWindow() +{ + wipe(); + release(); + delete window_; +} + +void PinWindow::release() +{ + if (NULL != passwd_) + { + memset(passwd_, 0, strlen(passwd_)); + secmem_free(passwd_); + } + passwd_ = NULL; +} + +void PinWindow::title(const char *name) +{ + set_label(window_, name, TITLE); +} + +void PinWindow::ok(const char* name) +{ + set_label(ok_, name, BUTTON_OK); +} + +void PinWindow::cancel(const char* label) +{ + if (NULL != label && 0 != *label) + cancel_name_ = label; + else + cancel_name_ = BUTTON_CANCEL; + + update_cancel_label(); +} + +void PinWindow::prompt(const char *name) +{ + set_label(message_, name, PROMPT); +} + +void PinWindow::timeout(unsigned int time) +{ + if (timeout_ == time) + return; + + // A xor B ~ A != B + if ( (time>0) != (timeout_>0)) + { + //enable or disable + if (time>0) + Fl::add_timeout(1.0, timeout_cb, this); + else + Fl::remove_timeout(timeout_cb, this); + } + + timeout_=time; + update_cancel_label(); + --timeout_; +} + +void PinWindow::showModal() +{ + if (NULL != window_) + { + window_->show(); + Fl::run(); + } + Fl::check(); +} + +void PinWindow::showModal(const int argc, char* argv[]) +{ + if (NULL != window_) + { + window_->show(argc, argv); + Fl::run(); + } + Fl::check(); +} + +int PinWindow::init(const int cx, const int cy) +{ + assert(NULL == window_); + window_ = new Fl_Window(cx, cy, TITLE); + + Fl_RGB_Image app(&icon); + window_->icon(&app); + + icon_ = new Fl_Box(10, 10, 64, 64); + icon_->image(encrypt); + + message_ = new Fl_Box(79, 5, cx-99, 44, PROMPT); + message_->align(Fl_Align(FL_ALIGN_LEFT_TOP | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); // left + + input_ = new Fl_Secret_Input(79, 59, cx-99, 25); + input_->labeltype(FL_NO_LABEL); + + + const int button_y = cy-40; + ok_ = new Fl_Return_Button(cx-300, button_y, 120, 25, BUTTON_OK); + ok_->callback(ok_cb, this); + + cancel_ = new Fl_Button(cx-160, button_y, 120, 25); + update_cancel_label(); + cancel_->callback(cancel_cb, this); + + window_->hotspot(input_); + window_->set_modal(); + + return 84; +}; + +void PinWindow::update_cancel_label() +{ + if (timeout_ == 0) + { + cancel_->label(cancel_name_.c_str()); + } + else + { + const size_t len = cancel_name_.size()+strlen(timeout_format)+10+1; + char *buf = new char[len]; + snprintf(buf, len, timeout_format, cancel_name_.c_str(), timeout_); + cancel_->copy_label(buf); + delete[] buf; // no way to attach label + } +} + +void PinWindow::timeout_cb(void* val) +{ + PinWindow *self = reinterpret_cast(val); + if (self->timeout_ == 0) + { + cancel_cb(self->cancel_, self); + } + else + { + self->update_cancel_label(); + --self->timeout_; + Fl::repeat_timeout(1.0, timeout_cb, val); + } +} + +void PinWindow::cancel_cb(Fl_Widget *button, void *val) +{ + PinWindow *self = reinterpret_cast(val); + + self->wipe(); + self->release(); + self->window_->hide(); +} + +void PinWindow::ok_cb(Fl_Widget *button, void *val) +{ + PinWindow *self = reinterpret_cast(val); + + self->release(); + + const char *passwd = self->input_->value(); + size_t len = strlen(passwd)+1; + self->passwd_ = reinterpret_cast(secmem_malloc(len)); + if (NULL != self->passwd_) + memcpy(self->passwd_, passwd, len); + + self->wipe(); + self->window_->hide(); +} + +void PinWindow::wipe() +{ + int len = input_->size(); + char* emul = new char[len+1]; + for (int i=0; ireplace(0, len, emul, len); + delete[] emul; + + input_->value(TITLE); // hide size too +} + +PinWindow* PinWindow::create() +{ + PinWindow* p = new PinWindow; + p->init(410, 140); + p->window_->end(); + p->input_->take_focus(); + return p; +} diff --git a/fltk/pinwindow.h b/fltk/pinwindow.h new file mode 100644 index 0000000..e1d009e --- /dev/null +++ b/fltk/pinwindow.h @@ -0,0 +1,108 @@ +/* + pinwindow.h - PinWindow is a simple fltk dialog for entring password + with timeout. if needed description (long text), error message, qualitybar + and etc should used PassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __PINWINDOW_H__ +#define __PINWINDOW_H__ + +#include "config.h" + +class Fl_Window; +class Fl_Box; +class Fl_Input; +class Fl_Button; +class Fl_Widget; + +#include +#include + +class PinWindow +{ +protected: + static const char *TITLE; + static const char *BUTTON_OK; + static const char *BUTTON_CANCEL; + static const char *PROMPT; + +protected: + PinWindow(const PinWindow&); + PinWindow& operator=(const PinWindow&); + + Fl_Window *window_; + Fl_Box *icon_; + + Fl_Box *message_; + Fl_Input *input_; + + Fl_Button *ok_, *cancel_; + + std::string cancel_name_; + char *passwd_; // SECURE_MEMORY + unsigned int timeout_; // click cancel if timeout + +public: + virtual ~PinWindow(); + + static PinWindow* create(); + + inline const char* passwd() const { return passwd_; } + + virtual void timeout(unsigned int time); // 0 - infinity, seconds + virtual void title(const char *title); + virtual void ok(const char* ok); + virtual void cancel(const char* cancel); + virtual void prompt(const char *message); + + virtual void showModal(); + virtual void showModal(const int argc, char* argv[]); + +protected: + PinWindow(); + + void wipe(); // clear UI memory + void release(); // clear secure memory + void update_cancel_label(); + + virtual int init(const int cx, const int cy); + + //callbacks + static void cancel_cb(Fl_Widget *button, void *val); + static void ok_cb(Fl_Widget *button, void *val); + static void timeout_cb(void*); + + // ISSUE: Fl_Window component in tinycore works only as Fl_Window::label(...); not Fl_Widget + template void set_label(TWidget* widget, const char *label, const char *def) + { + assert(NULL != widget); // widget must be created + + if (NULL != widget) + { + if (NULL != label && 0 != *label) + widget->copy_label(label); + else + widget->label(def); + } + }; +}; + +#endif //#ifndef __PINWINDOW_H__ diff --git a/fltk/qualitypasswindow.cxx b/fltk/qualitypasswindow.cxx new file mode 100644 index 0000000..6d7f7cc --- /dev/null +++ b/fltk/qualitypasswindow.cxx @@ -0,0 +1,92 @@ +/* + qualitypasswindow.cxx - QualityPassWindow pin entry + with Password QualityBar and etc + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include "qualitypasswindow.h" + +const char *QualityPassWindow::QUALITY = "Quality"; + +QualityPassWindow::QualityPassWindow(QualityPassWindow::GetQualityFn qualify, void* ptr) + : get_quality_(qualify) + ,get_quality_user_(ptr) + ,quality_(NULL) +{ + assert(NULL != qualify); +} + +void QualityPassWindow::input_changed(Fl_Widget *input, void *val) +{ + QualityPassWindow *self = reinterpret_cast(val); + + assert(NULL != self->get_quality_); // function should be assigned in ctor + assert(NULL != self->quality_); // quality progress bar must be created in init + + if (NULL != self->quality_ && NULL != self->get_quality_) + { + int result = self->get_quality_(self->input_->value(), self->get_quality_user_); + bool isErr = (result <= 0); + if (isErr) + result = -result; + self->quality_->selection_color(isErr?FL_RED:FL_GREEN); + self->quality_->value(std::min(result, 100)); + } +} + +QualityPassWindow* QualityPassWindow::create(QualityPassWindow::GetQualityFn qualify, void *user) +{ + QualityPassWindow *p = new QualityPassWindow(qualify, user); + p->init(460, 215); + p->window_->end(); + p->input_->take_focus(); + return p; +} + +void QualityPassWindow::quality(const char *name) +{ + set_label(quality_, name, QUALITY); +} + +int QualityPassWindow::init(const int cx, const int cy) +{ + int y = PassWindow::init(cx, cy); + assert(window_ == Fl_Group::current()); // make_window should all add current + + input_->when(FL_WHEN_CHANGED); + input_->callback(input_changed, this); + + y = input_->y() + input_->h(); + + quality_ = new Fl_Progress(input_->x(), y+5, input_->w(), 25, QUALITY); + quality_->align(Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP | FL_ALIGN_WRAP)); + quality_->maximum(100.1); + quality_->minimum(0.0); + y = quality_->y() + quality_->h(); + + error_->position(error_->x(), y+5); + + return error_->y() + error_->h(); +} diff --git a/fltk/qualitypasswindow.h b/fltk/qualitypasswindow.h new file mode 100644 index 0000000..164c10d --- /dev/null +++ b/fltk/qualitypasswindow.h @@ -0,0 +1,54 @@ +/* + qualitypasswindow.h - QualityPassWindow pin entry with Password QualityBar + and etc + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef __QUALITYPASSWINDOW_H__ +#define __QUALITYPASSWINDOW_H__ + +#include "passwindow.h" +class Fl_Progress; + +class QualityPassWindow : public PassWindow +{ +protected: + static const char *QUALITY; + +public: + typedef int (*GetQualityFn)(const char *passwd, void *ptr); + + static QualityPassWindow* create(GetQualityFn qualify, void* user); + + void quality(const char *name); + +protected: + QualityPassWindow(GetQualityFn qualify, void*); + + const GetQualityFn get_quality_; + void* const get_quality_user_; + + Fl_Progress *quality_; + virtual int init(const int cx, const int cy); + + static void input_changed(Fl_Widget *input, void *val); +}; + +#endif //#ifndef __QUALITYPASSWINDOW_H__