[bug#33352] : Add pinentry-efl

Message ID 20181112140530.GB25910@macbook41
State Accepted
Headers show
Series [bug#33352] : Add pinentry-efl | expand

Checks

Context Check Description
cbaines/applying patch success Successfully applied
cbaines/applying patch success Successfully applied

Commit Message

Efraim Flashner Nov. 12, 2018, 2:05 p.m. UTC
Of course I forgot to attach the patch.

Comments

Ludovic Courtès Nov. 19, 2018, 9:43 p.m. UTC | #1
Hello!

Efraim Flashner <efraim@flashner.co.il> skribis:

> From 27e2e32b961764a4cc92cba5988f68543363abc8 Mon Sep 17 00:00:00 2001
> From: Efraim Flashner <efraim@flashner.co.il>
> Date: Mon, 12 Nov 2018 15:55:05 +0200
> Subject: [PATCH] gnu: Add pinentry-efl.
>
> * gnu/packages/gnupg.scm (pinentry-efl): New variable.
> * gnu/packages/patches/pinentry-efl.patch: New file.
> * gnu/local.mk (dist_patch_DATA): Register it.

[...]

> +    (inputs
> +     `(("efl" ,efl)
> +       ,@(package-inputs pinentry-tty)))
> +    (description
> +   "Pinentry provides a console and an EFL GUI that allows users to enter a
> +passphrase when @code{gpg} is run and needs it.")))

s/an EFL GUI/a graphical interface for the Enlightenment Foundation
Libraries (EFL)/

Otherwise LGTM!

Ludo’.
Efraim Flashner Nov. 20, 2018, 1 p.m. UTC | #2
Pushed with changes as 5e369f8ab9e230193194b4d5846a5c78bbc89943

Patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 48ee438a6..e232db5ea 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1040,6 +1040,7 @@  dist_patch_DATA =						\
   %D%/packages/patches/pinball-missing-separators.patch		\
   %D%/packages/patches/pinball-src-deps.patch			\
   %D%/packages/patches/pinball-system-ltdl.patch		\
+  %D%/packages/patches/pinentry-efl.patch			\
   %D%/packages/patches/pingus-sdl-libs-config.patch		\
   %D%/packages/patches/pius.patch       			\
   %D%/packages/patches/pixman-CVE-2016-5296.patch		\
diff --git a/gnu/packages/gnupg.scm b/gnu/packages/gnupg.scm
index a9169b25a..4dff372ae 100644
--- a/gnu/packages/gnupg.scm
+++ b/gnu/packages/gnupg.scm
@@ -40,6 +40,8 @@ 
   #:use-module (gnu packages curl)
   #:use-module (gnu packages crypto)
   #:use-module (gnu packages emacs)
+  #:use-module (gnu packages enlightenment)
+  #:use-module (gnu packages gettext)
   #:use-module (gnu packages guile)
   #:use-module (gnu packages openldap)
   #:use-module (gnu packages perl)
@@ -863,6 +865,33 @@  software.")))
    "Pinentry provides a console and a Qt GUI that allows users to enter a
 passphrase when @code{gpg} is run and needs it.")))
 
+(define-public pinentry-efl
+  (package
+    (inherit pinentry-tty)
+    (name "pinentry-efl")
+    (source
+      (origin
+        (inherit (package-source pinentry-tty))
+        (patches (search-patches "pinentry-efl.patch"))))
+    (arguments
+     '(#:configure-flags '("--enable-pinentry-efl")
+       #:phases
+       (modify-phases %standard-phases
+         (replace 'bootstrap
+           (lambda _
+             (invoke "sh" "autogen.sh"))))))
+    (native-inputs
+     `(("autoconf" ,autoconf)
+       ("automake" ,automake)
+       ("gettext" ,gettext-minimal)
+       ,@(package-native-inputs pinentry-tty)))
+    (inputs
+     `(("efl" ,efl)
+       ,@(package-inputs pinentry-tty)))
+    (description
+   "Pinentry provides a console and an EFL GUI that allows users to enter a
+passphrase when @code{gpg} is run and needs it.")))
+
 (define-public pinentry
   (package (inherit pinentry-gtk2)
     (name "pinentry")))
diff --git a/gnu/packages/patches/pinentry-efl.patch b/gnu/packages/patches/pinentry-efl.patch
new file mode 100644
index 000000000..5ba79e28d
--- /dev/null
+++ b/gnu/packages/patches/pinentry-efl.patch
@@ -0,0 +1,798 @@ 
+https://git.gnupg.org/cgi-bin/gitweb.cgi?p=pinentry.git;a=commit;h=948105b7a34ec9a9e5479d376b7c86bafee50a01
+This patch can be removed with the next release of pinentry.
+
+From 948105b7a34ec9a9e5479d376b7c86bafee50a01 Mon Sep 17 00:00:00 2001
+From: "William L. Thomson Jr" <wlt@o-sinc.com>
+Date: Tue, 29 May 2018 22:50:47 +0100
+Subject: [PATCH] efl: Add an EFL-based pinentry.
+
+* NEWS: Update.
+* Makefile.am: Add new efl subdirectory.
+* configure.ac: Add --enable-pinentry-efl option.
+* efl/Makefile.am: New file.
+* efl/pinentry-efl.c: New file.
+
+Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
+---
+ Makefile.am        |   8 +-
+ configure.ac       |  44 +++-
+ efl/Makefile.am    |  38 ++++
+ efl/pinentry-efl.c | 623 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 716 insertions(+), 2 deletions(-)
+ create mode 100644 efl/Makefile.am
+ create mode 100644 efl/pinentry-efl.c
+
+diff --git a/Makefile.am b/Makefile.am
+index 8c8b8e5..b8fd0e1 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -82,10 +82,16 @@ else
+ pinentry_fltk =
+ endif
+ 
++if BUILD_PINENTRY_EFL
++pinentry_efl = efl
++else
++pinentry_efl =
++endif
++
+ SUBDIRS = m4 secmem pinentry ${pinentry_curses} ${pinentry_tty} \
+ 	${pinentry_emacs} ${pinentry_gtk_2} ${pinentry_gnome_3} \
+ 	${pinentry_qt} ${pinentry_tqt} ${pinentry_w32} \
+-	${pinentry_fltk} doc
++	${pinentry_fltk} ${pinentry_efl} doc
+ 
+ 
+ install-exec-local:
+diff --git a/configure.ac b/configure.ac
+index ff6c2e0..e305e44 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -419,6 +419,42 @@ fi
+ 
+ 
+ dnl
++dnl Check for EFL pinentry programs.
++dnl
++AC_ARG_ENABLE(pinentry-efl,
++            AC_HELP_STRING([--enable-pinentry-efl], [build EFL pinentry]),
++            pinentry_efl=$enableval, pinentry_efl=maybe)
++
++dnl check for pkg-config
++if test "$pinentry_efl" != "no"; then
++	AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
++	if test x"${PKG_CONFIG}" = xno ; then
++		pinentry_efl=no
++	fi
++fi
++
++if test "$pinentry_efl" != "no"; then
++	AC_MSG_CHECKING([for efl])
++	"${PKG_CONFIG}" --exists 'elementary >= 1.18'
++	if test $? -ne 0 ; then
++		AC_MSG_RESULT([no])
++		AC_MSG_WARN([efl >= 1.18 is required for efl pinentry])
++		pinentry_efl=no
++	else
++		AC_MSG_RESULT([yes])
++		EFL_CFLAGS=`"${PKG_CONFIG}" --cflags ecore-x elementary`
++		EFL_LIBS=`"${PKG_CONFIG}" --libs ecore-x elementary`
++		AC_SUBST(EFL_CFLAGS)
++		AC_SUBST(EFL_LIBS)
++		if test "$pinentry_efl" != "no"
++		then
++			pinentry_efl=yes
++		fi
++	fi
++fi
++AM_CONDITIONAL(BUILD_PINENTRY_EFL, test "$pinentry_efl" = "yes")
++
++dnl
+ dnl Check for GTK+-2 / GNOME3 pinentry programs.
+ dnl
+ AC_ARG_ENABLE(pinentry-gtk2,
+@@ -645,7 +681,11 @@ else
+               if test "$pinentry_tqt" = "yes"; then
+                 PINENTRY_DEFAULT=pinentry-tqt
+               else
+-                AC_MSG_ERROR([[No pinentry enabled.]])
++                if test "$pinentry_efl" = "yes"; then
++                  PINENTRY_DEFAULT=pinentry-efl
++                else
++                  AC_MSG_ERROR([[No pinentry enabled.]])
++                fi
+               fi
+             fi
+           fi
+@@ -721,6 +761,7 @@ secmem/Makefile
+ pinentry/Makefile
+ curses/Makefile
+ tty/Makefile
++efl/Makefile
+ emacs/Makefile
+ gtk+-2/Makefile
+ gnome3/Makefile
+@@ -744,6 +785,7 @@ AC_MSG_NOTICE([
+ 	Curses Pinentry ..: $pinentry_curses
+ 	TTY Pinentry .....: $pinentry_tty
+ 	Emacs Pinentry ...: $pinentry_emacs
++	EFL Pinentry .....: $pinentry_efl
+ 	GTK+-2 Pinentry ..: $pinentry_gtk_2
+ 	GNOME 3 Pinentry .: $pinentry_gnome_3
+ 	Qt Pinentry ......: $pinentry_qt $pinentry_qt_lib_version
+diff --git a/efl/Makefile.am b/efl/Makefile.am
+new file mode 100644
+index 0000000..b986a04
+--- /dev/null
++++ b/efl/Makefile.am
+@@ -0,0 +1,38 @@
++# Makefile.am - PIN entry EFL frontend.
++# Copyright (C) 2017 Obsidian-Studios, Inc.
++# Author William L. Thomson Jr. <wlt@o-sinc.com>
++#
++# 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
++
++bin_PROGRAMS = pinentry-efl
++
++if FALLBACK_CURSES
++ncurses_include = $(NCURSES_INCLUDE)
++libcurses = ../pinentry/libpinentry-curses.a $(LIBCURSES) $(LIBICONV)
++else
++ncurses_include =
++libcurses =
++endif
++
++AM_CPPFLAGS = $(COMMON_CFLAGS) $(EFL_CFLAGS) $(ncurses_include) \
++	-I$(top_srcdir)/secmem -I$(top_srcdir)/pinentry
++LDADD = ../pinentry/libpinentry.a ../secmem/libsecmem.a \
++	$(COMMON_LIBS) $(LIBCAP) $(EFL_LIBS) $(libcurses)
++
++pinentry_efl_SOURCES = pinentry-efl.c
+diff --git a/efl/pinentry-efl.c b/efl/pinentry-efl.c
+new file mode 100644
+index 0000000..ca99693
+--- /dev/null
++++ b/efl/pinentry-efl.c
+@@ -0,0 +1,623 @@
++/* pinentry-efl.c
++   Copyright (C) 2017 Obsidian-Studios, Inc.
++     Author William L. Thomson Jr. <wlt@o-sinc.com>
++
++   Based on pinentry-gtk2.c
++   Copyright (C) 1999 Robert Bihlmeyer <robbe@orcus.priv.at>
++   Copyright (C) 2001, 2002, 2007, 2015 g10 Code GmbH
++   Copyright (C) 2004 by Albrecht Dreß <albrecht.dress@arcor.de>
++
++   pinentry-efl is a pinentry application for the EFL widget set.
++   It tries to follow the Gnome Human Interface Guide as close as
++   possible.
++
++   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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++#include <Elementary.h>
++#include <Ecore_X.h>
++#include <gpg-error.h>
++#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wstrict-prototypes"
++#endif
++#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
++#pragma GCC diagnostic pop
++#endif
++
++#ifdef HAVE_GETOPT_H
++#include <getopt.h>
++#else
++#include "getopt.h"
++#endif /* HAVE_GETOPT_H */
++
++#include "pinentry.h"
++
++#ifdef FALLBACK_CURSES
++#include "pinentry-curses.h"
++#endif
++
++#define PGMNAME "pinentry-efl"
++
++#ifndef VERSION
++#define VERSION
++#endif
++
++#define ENTRY_HIDE "Hide entry"
++#define ENTRY_SHOW "Show entry"
++
++typedef enum { CONFIRM_CANCEL, CONFIRM_OK, CONFIRM_NOTOK } confirm_value_t;
++
++static const int WIDTH = 480;
++static const int BUTTON_HEIGHT = 27;
++static const int BUTTON_WIDTH = 70;
++static const int BUTTON_ICON_SIZE = 13;
++static const int PADDING = 5;
++
++static Eina_Bool got_input;
++static Ecore_Timer *timer;
++static Evas_Object *check_label;
++static Evas_Object *error_label;
++static Evas_Object *entry;
++static Evas_Object *repeat_entry;
++static Evas_Object *qualitybar;
++static Evas_Object *win;
++static char **pargv;
++static int grab_failed;
++static int passphrase_ok;
++static int confirm_mode;
++static int pargc;
++static confirm_value_t confirm_value;
++static pinentry_t pinentry;
++
++pinentry_cmd_handler_t pinentry_cmd_handler;
++
++static void
++quit (void)
++{
++  evas_object_del(win);
++  elm_exit();
++  ecore_main_loop_quit ();
++}
++
++static void
++delete_event (void *data EINA_UNUSED,
++              Evas_Object *obj EINA_UNUSED,
++              void *event EINA_UNUSED)
++{
++  pinentry->close_button = 1;
++  quit ();
++}
++
++static void
++changed_text_handler (void *data EINA_UNUSED,
++                      Evas_Object *obj,
++                      void *event EINA_UNUSED)
++{
++  const char *s;
++  int length;
++  int percent;
++
++  got_input = EINA_TRUE;
++
++  if (pinentry->repeat_passphrase && repeat_entry)
++    {
++      elm_object_text_set (repeat_entry, "");
++      elm_object_text_set (error_label, "");
++    }
++
++  if (!qualitybar || !pinentry->quality_bar)
++    return;
++
++  s = elm_object_text_get (obj);
++  if (!s)
++    s = "";
++  length = strlen (s);
++  percent = length? pinentry_inq_quality (pinentry, s, length) : 0;
++  evas_object_color_set(qualitybar,
++                        255 - ( 2.55 * percent ),
++                        2.55 * percent, 0, 255);
++  elm_progressbar_value_set (qualitybar, (double) percent / 100.0);
++}
++
++static void
++on_check (void *data EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
++{
++  if(elm_check_state_get(obj))
++    {
++        elm_entry_password_set(entry, EINA_FALSE);
++        elm_object_text_set(check_label,ENTRY_HIDE);
++    }
++  else
++    {
++        elm_entry_password_set(entry, EINA_TRUE);
++        elm_object_text_set(check_label,ENTRY_SHOW);
++    }
++  evas_object_size_hint_min_set(check_label,
++                                ELM_SCALE_SIZE(BUTTON_WIDTH),
++                                ELM_SCALE_SIZE(BUTTON_HEIGHT));
++  evas_object_size_hint_align_set(check_label, 0, 1);
++}
++
++static void
++on_click (void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
++{
++  if (confirm_mode)
++    {
++      confirm_value = (confirm_value_t) data;
++      quit ();
++      return;
++    }
++
++  if (data)
++    {
++      const char *s;
++      const char *s2;
++
++      s = elm_entry_entry_get (entry);
++      if (!s)
++	s = "";
++
++      if (pinentry->repeat_passphrase && repeat_entry)
++	{
++	  s2 = elm_entry_entry_get (repeat_entry);
++	  if (!s2)
++	    s2 = "";
++	  if (strcmp (s, s2))
++	    {
++              elm_object_text_set(error_label,
++                                  pinentry->repeat_error_string?
++                                  pinentry->repeat_error_string:
++				   "not correctly repeated");
++              elm_object_focus_set(entry,EINA_TRUE);
++              return;
++	    }
++	  pinentry->repeat_okay = 1;
++	}
++
++      passphrase_ok = 1;
++      pinentry_setbufferlen (pinentry, strlen (s) + 1);
++      if (pinentry->pin)
++	strncpy (pinentry->pin, s, strlen(s) + 1);
++    }
++  quit ();
++}
++
++static void
++enter_callback (void *data, Evas_Object * obj, void *event_info EINA_UNUSED)
++{
++  if (data)
++    elm_object_focus_set (data, 1);
++  else
++    on_click ((void *) CONFIRM_OK, obj, NULL);
++}
++
++static Eina_Bool
++timeout_cb (const void * data)
++{
++  pinentry_t pe = (pinentry_t)data;
++  if (!got_input)
++    {
++      ecore_main_loop_quit();
++      if (pe)
++        pe->specific_err = gpg_error (GPG_ERR_TIMEOUT);
++    }
++
++  timer = NULL;
++  return ECORE_CALLBACK_DONE;
++}
++
++static void
++create_window (void)
++{
++  char *txt;
++  Evas_Object *icon;
++  Evas_Object *obj;
++  Evas_Object *table;
++  int btn_txt_len = 0;
++  int row = 0;
++  int ok_len = 0;
++
++  win = elm_win_util_dialog_add(NULL,"pinentry","enter pin");
++  elm_win_autodel_set(win, EINA_TRUE);
++  elm_win_center(win,EINA_TRUE,EINA_TRUE);
++  evas_object_smart_callback_add(win, "delete,request", delete_event, NULL);
++
++  table = elm_table_add(win);
++  elm_table_padding_set(table,ELM_SCALE_SIZE(PADDING),0);
++  evas_object_size_hint_padding_set (table,
++                                     ELM_SCALE_SIZE(PADDING),
++                                     ELM_SCALE_SIZE(PADDING),
++                                     ELM_SCALE_SIZE(PADDING),
++                                     ELM_SCALE_SIZE(PADDING));
++  evas_object_show(table);
++
++  if (pinentry->title)
++    {
++      txt = pinentry_utf8_to_local (pinentry->lc_ctype,
++                                    pinentry->title);
++      elm_win_title_set ( win, txt );
++      free (txt);
++    }
++
++  /* Description Label */
++  if (pinentry->description)
++    {
++      char* aligned;
++      int len;
++
++      obj = elm_label_add(table);
++      elm_label_line_wrap_set (obj, ELM_WRAP_WORD);
++      txt = pinentry_utf8_to_local (pinentry->lc_ctype, pinentry->description);
++      len = strlen(txt)+20; // 20 chars for align tag
++      aligned = calloc(len+1,sizeof(char));
++      if(aligned)
++        {
++          snprintf(aligned,len, "<align=left>%s</align>",txt);
++          elm_object_text_set(obj,aligned);
++          free (aligned);
++        } else
++          elm_object_text_set(obj,txt);
++      free (txt);
++      evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, 0);
++      evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, 0);
++      elm_table_pack(table, obj, 1, row, 5, 1);
++      evas_object_show(obj);
++      row++;
++    }
++  if (!confirm_mode && (pinentry->error || pinentry->repeat_passphrase))
++    {
++    /* Error Label */
++    if (pinentry->error)
++        txt = pinentry_utf8_to_local (pinentry->lc_ctype, pinentry->error);
++      else
++        txt = "";
++      obj = elm_label_add(table);
++      evas_object_color_set(obj, 255, 0, 0, 255);
++      elm_object_text_set(obj,txt);
++      elm_object_style_set(obj,"slide_bounce");
++      elm_label_slide_duration_set(obj, 10);
++      elm_label_slide_mode_set(obj, ELM_LABEL_SLIDE_MODE_ALWAYS);
++      elm_label_slide_go(obj);
++      evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, 0);
++      evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, 0);
++      elm_table_pack(table, obj, 1, row, 5, 1);
++      evas_object_show(obj);
++      if (pinentry->error)
++        free (txt);
++      row++;
++    }
++
++  qualitybar = NULL;
++
++  if (!confirm_mode)
++    {
++
++    if (pinentry->prompt)
++      {
++        /* Entry/Prompt Label */
++        obj = elm_label_add(table);
++        txt = pinentry_utf8_to_local (pinentry->lc_ctype, pinentry->prompt);
++        elm_object_text_set(obj,txt);
++        free (txt);
++        evas_object_size_hint_weight_set(obj, 0, EVAS_HINT_EXPAND);
++        evas_object_size_hint_align_set(obj, 1, EVAS_HINT_FILL);
++        elm_table_pack(table, obj, 1, row, 1, 1);
++        evas_object_show(obj);
++      }
++
++      entry = elm_entry_add(table);
++      elm_entry_scrollable_set(entry, EINA_TRUE);
++      elm_scroller_policy_set(entry,
++                              ELM_SCROLLER_POLICY_OFF,
++                              ELM_SCROLLER_POLICY_OFF);
++      elm_entry_password_set(entry, EINA_TRUE);
++      elm_entry_single_line_set(entry, EINA_TRUE);
++      evas_object_size_hint_weight_set(entry, 0, 0);
++      evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0);
++      elm_table_pack(table, entry, 2, row, 4, 1);
++      evas_object_smart_callback_add(entry,
++                                     "changed",
++                                     changed_text_handler,
++                                     NULL);
++      evas_object_show(entry);
++      row++;
++
++      /* Check box */
++      obj = elm_check_add(table);
++      evas_object_size_hint_align_set(obj, 1, EVAS_HINT_FILL);
++      elm_table_pack(table, obj, 1, row, 1, 1);
++      evas_object_smart_callback_add(obj, "changed", on_check, NULL);
++      evas_object_show(obj);
++
++      /* Check Label */
++      check_label = elm_label_add(table);
++      on_check((void *)NULL, obj, (void *)NULL);
++      elm_table_pack(table, check_label, 2, row, 4, 1);
++      evas_object_show(check_label);
++      row++;
++
++      if (pinentry->quality_bar)
++	{
++          /* Quality Bar Label */
++	  obj = elm_label_add(table);
++          txt = pinentry_utf8_to_local (pinentry->lc_ctype,
++                                        pinentry->quality_bar);
++          elm_object_text_set(obj,txt);
++          free (txt);
++          evas_object_size_hint_weight_set(obj, 0, EVAS_HINT_EXPAND);
++          evas_object_size_hint_align_set(obj, 1, EVAS_HINT_FILL);
++          elm_table_pack(table, obj, 1, row, 1, 1);
++          evas_object_show(obj);
++
++	  qualitybar = elm_progressbar_add(table);
++          evas_object_color_set(qualitybar, 255, 0, 0, 255);
++          evas_object_show(qualitybar);
++          if (pinentry->quality_bar_tt)
++	    elm_object_tooltip_text_set (qualitybar,
++					 pinentry->quality_bar_tt);
++          evas_object_size_hint_weight_set(qualitybar, EVAS_HINT_EXPAND, 0);
++          evas_object_size_hint_align_set(qualitybar, EVAS_HINT_FILL, 0);
++          elm_table_pack(table, qualitybar, 2, row, 4, 1);
++          row++;
++	}
++
++      if (pinentry->repeat_passphrase)
++        {
++          /* Repeat Label */
++	  obj = elm_label_add(table);
++          txt = pinentry_utf8_to_local (pinentry->lc_ctype,
++                                        pinentry->repeat_passphrase);
++          elm_object_text_set(obj,txt);
++          free (txt);
++          evas_object_size_hint_weight_set(obj, 0, EVAS_HINT_EXPAND);
++          evas_object_size_hint_align_set(obj, 1, EVAS_HINT_FILL);
++          elm_table_pack(table, obj, 1, row, 1, 1);
++          evas_object_show(obj);
++
++          repeat_entry = elm_entry_add(table);
++          elm_entry_scrollable_set(repeat_entry, EINA_TRUE);
++          elm_scroller_policy_set(repeat_entry,
++                                  ELM_SCROLLER_POLICY_OFF,
++                                  ELM_SCROLLER_POLICY_OFF);
++          elm_entry_password_set(repeat_entry, EINA_TRUE);
++          elm_entry_single_line_set(repeat_entry, EINA_TRUE);
++          evas_object_size_hint_weight_set(repeat_entry, 0, 0);
++          evas_object_size_hint_align_set(repeat_entry, EVAS_HINT_FILL, 0);
++          elm_table_pack(table, repeat_entry, 2, row, 4, 1);
++	  evas_object_smart_callback_add (repeat_entry, "activated",
++					  enter_callback, NULL);
++          evas_object_show(repeat_entry);
++          evas_object_smart_callback_add (entry,
++                                          "activated",
++                                          enter_callback,
++                                          repeat_entry);
++          evas_object_smart_callback_add(repeat_entry,
++                                         "activated",
++                                         on_click,
++                                         (void *) CONFIRM_OK);
++          row++;
++        }
++      else
++        evas_object_smart_callback_add(entry,
++                                       "activated",
++                                       on_click,
++                                       (void *) CONFIRM_OK);
++  }
++
++  /* Cancel Button */
++  if (!pinentry->one_button)
++    {
++      obj = elm_button_add(table);
++      icon = elm_icon_add (table);
++      evas_object_size_hint_aspect_set (icon, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
++      if (elm_icon_standard_set (icon, "dialog-cancel") ||
++          elm_icon_standard_set (icon, "window-close"))
++        {
++          evas_object_size_hint_min_set(icon,
++                                        ELM_SCALE_SIZE(BUTTON_ICON_SIZE),
++                                        ELM_SCALE_SIZE(BUTTON_ICON_SIZE));
++          elm_object_part_content_set(obj, "icon", icon);
++          evas_object_show (icon);
++        }
++      else
++        evas_object_del(icon);
++      if (pinentry->cancel || pinentry->default_cancel)
++        {
++          if(pinentry->cancel)
++            txt = pinentry_utf8_to_local (pinentry->lc_ctype, pinentry->cancel);
++          else
++            txt = pinentry_utf8_to_local (pinentry->lc_ctype,
++                                          pinentry->default_cancel);
++          if(txt[0]=='_')
++            elm_object_text_set(obj,txt+1);
++          else
++            elm_object_text_set(obj,txt);
++          btn_txt_len = ELM_SCALE_SIZE(strlen(txt) * (PADDING * 1.5));
++          free (txt);
++        }
++      else
++        elm_object_text_set(obj, "Cancel"); //STOCK_CANCEL
++      evas_object_size_hint_align_set(obj, 0, 0);
++      if(btn_txt_len>ELM_SCALE_SIZE(BUTTON_WIDTH))
++        evas_object_size_hint_min_set(obj,
++                                      btn_txt_len,
++                                      ELM_SCALE_SIZE(BUTTON_HEIGHT));
++      else
++        evas_object_size_hint_min_set(obj,
++                                      ELM_SCALE_SIZE(BUTTON_WIDTH),
++                                      ELM_SCALE_SIZE(BUTTON_HEIGHT));
++      elm_table_pack(table, obj, 4, row, 1, 1);
++      evas_object_smart_callback_add(obj,
++                                     "clicked",
++                                     on_click,
++                                     (void *) CONFIRM_CANCEL);
++      evas_object_show(obj);
++    }
++
++  /* OK Button */
++  obj = elm_button_add(table);
++  icon = elm_icon_add (table);
++  evas_object_size_hint_aspect_set (icon, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
++  if (elm_icon_standard_set (icon, "dialog-ok") ||
++      elm_icon_standard_set (icon, "list-add"))
++    {
++      evas_object_size_hint_min_set(icon,
++                                    ELM_SCALE_SIZE(BUTTON_ICON_SIZE),
++                                    ELM_SCALE_SIZE(BUTTON_ICON_SIZE));
++      elm_object_part_content_set(obj, "icon", icon);
++      evas_object_show (icon);
++    }
++  else
++    evas_object_del(icon);
++  if (pinentry->ok || pinentry->default_ok)
++    {
++      if(pinentry->ok)
++        txt = pinentry_utf8_to_local (pinentry->lc_ctype, pinentry->ok);
++      else
++        txt = pinentry_utf8_to_local (pinentry->lc_ctype, pinentry->default_ok);
++      if(txt[0]=='_')
++        elm_object_text_set(obj,txt+1);
++      else
++        elm_object_text_set(obj,txt);
++      ok_len = ELM_SCALE_SIZE(strlen(txt) * (PADDING * 1.5));
++      if(ok_len>btn_txt_len)
++        btn_txt_len = ok_len;
++      free (txt);
++    }
++  else
++    elm_object_text_set(obj,"OK"); //STOCK_OK
++  evas_object_size_hint_align_set(obj, 0, 0);
++  if(btn_txt_len>ELM_SCALE_SIZE(BUTTON_WIDTH))
++    evas_object_size_hint_min_set(obj,
++                                  btn_txt_len,
++                                  ELM_SCALE_SIZE(BUTTON_HEIGHT));
++  else
++    evas_object_size_hint_min_set(obj,
++                                  ELM_SCALE_SIZE(BUTTON_WIDTH),
++                                  ELM_SCALE_SIZE(BUTTON_HEIGHT));
++  elm_table_pack(table, obj, 5, row, 1, 1);
++  evas_object_smart_callback_add(obj, "clicked", on_click, (void *) CONFIRM_OK);
++  evas_object_show(obj);
++
++  /* Key/Lock Icon */
++  obj = elm_icon_add (win);
++  evas_object_size_hint_aspect_set (obj, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
++  if (elm_icon_standard_set (obj, "dialog-password"))
++    {
++      double ic_size = WIDTH/5;
++      if(row==0)
++        ic_size = ic_size/3.5;
++      else if(row<4)
++        ic_size = ic_size - ic_size/row;
++      evas_object_size_hint_min_set(obj,
++                                    ELM_SCALE_SIZE(ic_size),
++                                    ELM_SCALE_SIZE(ic_size));
++      evas_object_size_hint_weight_set(obj, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
++      evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, 0.5);
++      elm_table_pack(table, obj, 0, 0, 1, row? row:1);
++      evas_object_show (obj);
++    }
++  else
++      evas_object_del(obj);
++
++  /* Box for padding */
++  obj = elm_box_add (win);
++  elm_box_pack_end (obj, table);
++  evas_object_show (obj);
++
++  elm_win_resize_object_add(win,obj);
++  evas_object_show(win);
++
++  if(entry)
++    elm_object_focus_set (entry, EINA_TRUE);
++
++  if (pinentry->timeout > 0)
++    timer = ecore_timer_add (pinentry->timeout,
++                             (Ecore_Task_Cb)timeout_cb,
++                             pinentry);
++}
++
++static int
++efl_cmd_handler (pinentry_t pe)
++{
++  int want_pass = !!pe->pin;
++
++  got_input = EINA_FALSE;
++  pinentry = pe;
++  confirm_value = CONFIRM_CANCEL;
++  passphrase_ok = 0;
++  confirm_mode = want_pass ? 0 : 1;
++  /* init ecore-x explicitly using DISPLAY since this can launch
++   * from console
++   */
++  if (pe->display)
++    ecore_x_init (pe->display);
++  elm_init (pargc, pargv);
++  create_window ();
++  ecore_main_loop_begin ();
++
++  if (timer)
++    {
++      ecore_timer_del (timer);
++      timer = NULL;
++    }
++
++  if (confirm_value == CONFIRM_CANCEL || grab_failed)
++    pe->canceled = 1;
++
++  pinentry = NULL;
++  if (want_pass)
++    {
++      if (passphrase_ok && pe->pin)
++	return strlen (pe->pin);
++      else
++	return -1;
++    }
++  else
++    return (confirm_value == CONFIRM_OK) ? 1 : 0;
++}
++
++int
++main (int argc, char *argv[])
++{
++  pinentry_init (PGMNAME);
++
++#ifdef FALLBACK_CURSES
++  if (pinentry_have_display (argc, argv))
++    {
++#endif
++
++  pinentry_cmd_handler = efl_cmd_handler;
++  pargc = argc;
++  pargv = argv;
++
++#ifdef FALLBACK_CURSES
++    }
++  else
++    {
++      pinentry_cmd_handler = curses_cmd_handler;
++    }
++#endif
++
++  pinentry_parse_opts (argc, argv);
++  if (pinentry_loop ())
++    return 1;
++
++  return 0;
++}
+-- 
+2.8.0.rc3
+