discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=3b15315764e1936b56fe54cd8234c627c4527930

commit 3b15315764e1936b56fe54cd8234c627c4527930
Author: discomfitor <michael.blumenkra...@gmail.com>
Date:   Sat Oct 26 18:02:20 2013 +0100

    feature: add PIN-style desklock for lokker module
    
    accessible from the normal screen lock dialog
---
 src/bin/e_config.c                               |   1 +
 src/bin/e_config.h                               |   1 +
 src/bin/e_desklock.h                             |   1 +
 src/modules/conf_display/e_int_config_desklock.c |  47 ++++-
 src/modules/lokker/e_mod_main.h                  |   8 +-
 src/modules/lokker/lokker.c                      | 240 +++++++++++++++++++++--
 6 files changed, 281 insertions(+), 17 deletions(-)

diff --git a/src/bin/e_config.c b/src/bin/e_config.c
index 5091899..183c90a 100644
--- a/src/bin/e_config.c
+++ b/src/bin/e_config.c
@@ -570,6 +570,7 @@ _e_config_edd_init(Eina_Bool old)
    E_CONFIG_LIST(D, T, shelves, _e_config_shelf_edd);
    E_CONFIG_VAL(D, T, font_hinting, INT); /**/
    E_CONFIG_VAL(D, T, desklock_passwd, INT);
+   E_CONFIG_VAL(D, T, desklock_pin, INT);
    E_CONFIG_LIST(D, T, desklock_backgrounds, _e_config_desklock_bg_edd); /**/
    E_CONFIG_VAL(D, T, desklock_auth_method, INT);
    E_CONFIG_VAL(D, T, desklock_login_box_zone, INT);
diff --git a/src/bin/e_config.h b/src/bin/e_config.h
index 59612ba..2678302 100644
--- a/src/bin/e_config.h
+++ b/src/bin/e_config.h
@@ -207,6 +207,7 @@ struct _E_Config
    int                       font_hinting; // GUI
 
    int                       desklock_passwd; // GUI // hashed
+   int                       desklock_pin; // GUI // hashed
    Eina_List                *desklock_backgrounds; // GUI
    int                       desklock_auth_method; // GUI
    int                       desklock_login_box_zone; // GUI
diff --git a/src/bin/e_desklock.h b/src/bin/e_desklock.h
index 90a3644..55257aa 100644
--- a/src/bin/e_desklock.h
+++ b/src/bin/e_desklock.h
@@ -16,6 +16,7 @@ typedef enum
    E_DESKLOCK_AUTH_METHOD_SYSTEM = 0,
    E_DESKLOCK_AUTH_METHOD_PERSONAL = 1,
    E_DESKLOCK_AUTH_METHOD_EXTERNAL = 2,
+   E_DESKLOCK_AUTH_METHOD_PIN = 3,
 } E_Desklock_Auth_Method;
 
 typedef struct E_Desklock_Interface E_Desklock_Interface;
diff --git a/src/modules/conf_display/e_int_config_desklock.c 
b/src/modules/conf_display/e_int_config_desklock.c
index 0a6aa96..b0426d1 100644
--- a/src/modules/conf_display/e_int_config_desklock.c
+++ b/src/modules/conf_display/e_int_config_desklock.c
@@ -17,7 +17,7 @@ static void         _cb_bg_mouse_down(void *data, Evas *evas, 
Evas_Object *obj,
 
 struct _E_Config_Dialog_Data
 {
-   Evas_Object *lock_cmd_entry, *passwd_entry;
+   Evas_Object *lock_cmd_entry, *passwd_entry, *pin_entry;
    E_Config_Dialog *cfd, *bg_fsel;
 
    /* Common vars */
@@ -32,6 +32,7 @@ struct _E_Config_Dialog_Data
    int              login_zone;
    int              zone;
    char            *desklock_personal_passwd;
+   char            *pin_str;
    char            *custom_lock_cmd;
 
    /* Layout */
@@ -173,6 +174,7 @@ _free_data(E_Config_Dialog *cfd __UNUSED__, 
E_Config_Dialog_Data *cfdata)
      e_object_del(E_OBJECT(cfdata->bg_fsel));
    E_FREE(cfdata->custom_lock_cmd);
    E_FREE(cfdata->desklock_personal_passwd);
+   E_FREE(cfdata->pin_str);
    EINA_LIST_FREE(cfdata->bgs, bg)
      eina_stringshare_del(bg);
    E_FREE(cfdata);
@@ -210,6 +212,9 @@ _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas *evas, 
E_Config_Dialog_Data
    ow = e_widget_radio_add(evas, _("Use Personal Screenlock Password"), 
E_DESKLOCK_AUTH_METHOD_PERSONAL, rg);
    evas_object_smart_callback_add(ow, "changed", _login_method_change, cfdata);
    e_widget_list_object_append(ol, ow, 1, 1, 0.5);
+   ow = e_widget_radio_add(evas, _("Use PIN"), E_DESKLOCK_AUTH_METHOD_PIN, rg);
+   evas_object_smart_callback_add(ow, "changed", _login_method_change, cfdata);
+   e_widget_list_object_append(ol, ow, 1, 1, 0.5);
    ow = e_widget_radio_add(evas, _("Use External Screenlock Command"), 
E_DESKLOCK_AUTH_METHOD_EXTERNAL, rg);
    evas_object_smart_callback_add(ow, "changed", _login_method_change, cfdata);
    e_widget_list_object_append(ol, ow, 1, 1, 0.5);
@@ -220,12 +225,20 @@ _basic_create(E_Config_Dialog *cfd __UNUSED__, Evas 
*evas, E_Config_Dialog_Data
    e_widget_framelist_object_append(of, ow);
    e_widget_list_object_append(ol, of, 1, 1, 0.5);
 
+   of = e_widget_framelist_add(evas, _("PIN Entry"), 0);
+   cfdata->pin_entry = ow = e_widget_entry_add(evas, &(cfdata->pin_str), NULL, 
NULL, NULL);
+   e_widget_entry_password_set(ow, 1);
+   e_widget_framelist_object_append(of, ow);
+   e_widget_list_object_append(ol, of, 1, 1, 0.5);
+
    of = e_widget_framelist_add(evas, _("External Screenlock Command"), 0);
    cfdata->lock_cmd_entry = ow = e_widget_entry_add(evas, 
&(cfdata->custom_lock_cmd), NULL, NULL, NULL);
    e_widget_framelist_object_append(of, ow);
 
    e_widget_disabled_set(cfdata->passwd_entry,
      (cfdata->desklock_auth_method != E_DESKLOCK_AUTH_METHOD_PERSONAL));
+   e_widget_disabled_set(cfdata->pin_entry,
+     (cfdata->desklock_auth_method != E_DESKLOCK_AUTH_METHOD_PIN));
    e_widget_disabled_set(cfdata->lock_cmd_entry,
      (cfdata->desklock_auth_method != E_DESKLOCK_AUTH_METHOD_EXTERNAL));
 
@@ -397,6 +410,24 @@ _basic_apply(E_Config_Dialog *cfd __UNUSED__, 
E_Config_Dialog_Data *cfdata)
           eina_hash_djb2(cfdata->desklock_personal_passwd,
           strlen(cfdata->desklock_personal_passwd));
      }
+   else if (cfdata->desklock_auth_method == E_DESKLOCK_AUTH_METHOD_PIN)
+     {
+        if (cfdata->pin_str && cfdata->pin_str[0])
+          {
+             int test;
+             char *pp;
+
+             errno = 0;
+             test = strtol(cfdata->pin_str, &pp, 10);
+             if (errno) return 0; //NAN
+             if (pp && pp[0]) return 0;
+             if (test < 1) return 0;
+             e_config->desklock_pin = eina_hash_djb2(cfdata->pin_str, 
strlen(cfdata->pin_str));
+          }
+        else
+          /* dumb, but let them do what they want... */
+          e_config->desklock_pin = 0;
+     }
    e_config->desklock_start_locked = cfdata->start_locked;
    e_config->desklock_on_suspend = cfdata->lock_on_suspend;
    e_config->desklock_autolock_idle = cfdata->auto_lock;
@@ -480,6 +511,13 @@ _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, 
E_Config_Dialog_Data *cfda
           strlen(cfdata->desklock_personal_passwd)))
           return 1;
      }
+   if (e_config->desklock_auth_method == E_DESKLOCK_AUTH_METHOD_PIN)
+     {
+        if (e_config->desklock_pin !=
+          eina_hash_djb2(cfdata->pin_str,
+          strlen(cfdata->pin_str)))
+          return 1;
+     }
 
    if (e_config->desklock_autolock_screensaver != cfdata->screensaver_lock)
      return 1;
@@ -644,6 +682,13 @@ _login_method_change(void *data, Evas_Object *obj 
EINA_UNUSED, void *event_info
         e_widget_entry_select_all(cfdata->passwd_entry);
         e_widget_focus_set(cfdata->passwd_entry, 1);
      }
+   e_widget_disabled_set(cfdata->pin_entry,
+     (cfdata->desklock_auth_method != E_DESKLOCK_AUTH_METHOD_PIN));
+   if (!e_widget_disabled_get(cfdata->pin_entry))
+     {
+        e_widget_entry_select_all(cfdata->pin_entry);
+        e_widget_focus_set(cfdata->pin_entry, 1);
+     }
    e_widget_disabled_set(cfdata->lock_cmd_entry,
      (cfdata->desklock_auth_method != E_DESKLOCK_AUTH_METHOD_EXTERNAL));
    if (!e_widget_disabled_get(cfdata->lock_cmd_entry))
diff --git a/src/modules/lokker/e_mod_main.h b/src/modules/lokker/e_mod_main.h
index 7b88525..111235f 100644
--- a/src/modules/lokker/e_mod_main.h
+++ b/src/modules/lokker/e_mod_main.h
@@ -18,7 +18,13 @@
 #define ERR(...)  EINA_LOG_DOM_ERR(_e_lokker_log_dom, __VA_ARGS__)
 #define CRIT(...) EINA_LOG_DOM_CRIT(_e_lokker_log_dom, __VA_ARGS__)
 
+
+typedef enum
+{
+   E_DESKLOCK_AUTH_METHOD_LINES = 4,
+} E_Desklock_Auth_Method2;
+
 EINTERN Eina_Bool lokker_lock(void);
 EINTERN void lokker_unlock(void);
-
+EAPI E_Config_Dialog *e_int_config_lokker(E_Comp *comp, const char *params 
EINA_UNUSED);
 #endif
diff --git a/src/modules/lokker/lokker.c b/src/modules/lokker/lokker.c
index d42c0b9..827f730 100644
--- a/src/modules/lokker/lokker.c
+++ b/src/modules/lokker/lokker.c
@@ -34,6 +34,14 @@ static E_Zone *last_active_zone = NULL;
 
 static Lokker_Data *edd = NULL;
 
+static int _lokker_check_auth(void);
+
+static Eina_Bool
+lokker_is_pin(void)
+{
+   return e_config->desklock_auth_method == E_DESKLOCK_AUTH_METHOD_PIN;
+}
+
 static int
 _zone_count_get(void)
 {
@@ -156,6 +164,147 @@ _lokker_delete(void)
    _lokker_backspace();
 }
 
+static Eina_Bool
+_pin_mouse_button_down(Lokker_Popup *lp, int t EINA_UNUSED, 
Ecore_Event_Mouse_Button *ev)
+{
+   Evas *e;
+
+   if (ev->buttons != 1) return ECORE_CALLBACK_DONE;
+   e = e_comp_get(lp->zone)->evas;
+   evas_event_feed_mouse_move(e,
+     e_comp_canvas_x_root_adjust(lp->zone->comp, ev->root.x),
+     e_comp_canvas_y_root_adjust(lp->zone->comp, ev->root.y),
+     0, NULL);
+   evas_event_feed_mouse_down(e, 1, 0, 0, NULL);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_pin_mouse_button_up(Lokker_Popup *lp, int t EINA_UNUSED, 
Ecore_Event_Mouse_Button *ev)
+{
+   if (ev->buttons != 1) return ECORE_CALLBACK_DONE;
+   evas_event_feed_mouse_up(evas_object_evas_get(lp->comp_object), 1, 0, 0, 
NULL);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_pin_click(void *data EINA_UNUSED, Evas_Object *obj, const char *sig 
EINA_UNUSED, const char *src EINA_UNUSED)
+{
+   const char *name;
+   int num;
+
+   name = edje_object_part_text_get(obj, "e.text.label");
+   if (!name) //wtf
+     return;
+   if (!e_util_strcmp(name, "Login"))
+     {
+        _lokker_check_auth();
+        return;
+     }
+   if (!e_util_strcmp(name, "Delete"))
+     {
+        _lokker_backspace();
+        return;
+     }
+   num = strtol(name, NULL, 10);
+   if (num < 0) return;
+   if (num > 9) return;
+   if (edd->selected)
+     {
+        _lokker_null();
+        _lokker_unselect();
+     }
+   if ((strlen(edd->passwd) < (PASSWD_LEN - strlen(name))))
+     {
+        strcat(edd->passwd, name);
+        _text_passwd_update();
+     }
+}
+
+static void
+_pin_box_add(Lokker_Popup *lp)
+{
+   int mw, mh;
+   Evas *evas;
+   Evas_Object *table, *o, *o2;
+   int x, a = 0, b = 0;
+
+   evas = evas_object_evas_get(lp->bg_object);
+   lp->login_box = edje_object_add(evas);
+   evas_object_name_set(lp->login_box, "desklock->login_box");
+   e_theme_edje_object_set(lp->login_box,
+                           "base/theme/desklock",
+                           "e/desklock/pin_box");
+   edje_object_part_text_set(lp->login_box, "e.text.title",
+                             _("Please enter your PIN"));
+   table = e_table_add(evas);
+   e_comp_object_util_del_list_append(lp->login_box, table);
+   e_table_homogenous_set(table, 1);
+   e_table_freeze(table);
+   for (x = 1; x < 11; x++)
+     {
+        char buf[8];
+
+        o = edje_object_add(evas);
+        e_comp_object_util_del_list_append(lp->login_box, o);
+        e_theme_edje_object_set(o, "base/theme/desklock", 
"e/desklock/pin_button");
+        snprintf(buf, sizeof(buf), "%d", x % 10);
+        edje_object_part_text_set(o, "e.text.label", buf);
+        evas_object_show(o);
+        edje_object_signal_callback_add(o, "e,action,click", "*", _pin_click, 
lp);
+        if (x == 10) a = 1;
+        e_table_pack(table, o, a, b, 1, 1);
+        e_table_pack_options_set(o, 1, 1, 0, 0, 0.5, 0.5,
+          48 * e_scale, 48 * e_scale, 48 * e_scale, 48 * e_scale);
+        if (++a >= 3)
+          {
+             a = 0;
+             b++;
+          }
+     }
+
+   /* delete */
+   o = edje_object_add(evas);
+   e_comp_object_util_del_list_append(lp->login_box, o);
+   e_theme_edje_object_set(o, "base/theme/desklock", "e/desklock/pin_button");
+   edje_object_part_text_set(o, "e.text.label", "Delete");
+   o2 = e_icon_add(evas);
+   e_comp_object_util_del_list_append(lp->login_box, o2);
+   e_util_icon_theme_set(o2, "list-remove");
+   edje_object_part_swallow(o, "e.swallow.icon", o2);
+   evas_object_show(o2);
+   evas_object_show(o);
+   edje_object_signal_callback_add(o, "e,action,click", "*", _pin_click, lp);
+   e_table_pack(table, o, 0, 3, 1, 1);
+   e_table_pack_options_set(o, 1, 1, 0, 0, 0.5, 0.5,
+     48 * e_scale, 48 * e_scale, 48 * e_scale, 48 * e_scale);
+
+   /* login */
+   o = edje_object_add(evas);
+   e_comp_object_util_del_list_append(lp->login_box, o);
+   e_theme_edje_object_set(o, "base/theme/desklock", "e/desklock/pin_button");
+   edje_object_part_text_set(o, "e.text.label", "Login");
+   o2 = e_icon_add(evas);
+   e_comp_object_util_del_list_append(lp->login_box, o2);
+   e_util_icon_theme_set(o2, "preferences-applications-screen-unlock");
+   edje_object_part_swallow(o, "e.swallow.icon", o2);
+   evas_object_show(o2);
+   evas_object_show(o);
+   edje_object_signal_callback_add(o, "e,action,click", "*", _pin_click, lp);
+   e_table_pack(table, o, 2, 3, 1, 1);
+   e_table_pack_options_set(o, 1, 1, 0, 0, 0.5, 0.5,
+     48 * e_scale, 48 * e_scale, 48 * e_scale, 48 * e_scale);
+
+   e_table_thaw(table);
+   evas_object_show(table);
+   e_table_size_min_get(table, &mw, &mh);
+   edje_extern_object_min_size_set(table, mw, mh);
+   edje_extern_object_max_size_set(table, mw, mh);
+   edje_object_part_swallow(lp->login_box, "e.swallow.buttons", table);
+   edje_object_size_min_calc(lp->login_box, &mw, &mh);
+   edje_extern_object_min_size_set(lp->login_box, mw, mh);
+   edje_extern_object_max_size_set(lp->login_box, mw, mh);
+}
 
 static void
 _text_login_box_add(Lokker_Popup *lp)
@@ -205,10 +354,13 @@ _text_login_box_add(Lokker_Popup *lp)
 static void
 _lokker_popup_add(E_Zone *zone)
 {
+   E_Zone *current_zone;
+   int total_zone_num;
    Lokker_Popup *lp;
    E_Config_Desklock_Background *cbg;
    Eina_Stringshare *bg;
    Evas *evas;
+   int nocreate = 0;
 
    lp = E_NEW(Lokker_Popup, 1);
    cbg = eina_list_nth(e_config->desklock_backgrounds, zone->num);
@@ -265,7 +417,37 @@ _lokker_popup_add(E_Zone *zone)
    evas_object_layer_set(lp->comp_object, E_LAYER_DESKLOCK);
    evas_object_clip_set(lp->comp_object, lp->zone->bg_clip_object);
 
-   _text_login_box_add(lp);
+   last_active_zone = current_zone = 
e_util_zone_current_get(e_manager_current_get());
+   total_zone_num = _zone_count_get();
+   if (total_zone_num > 1)
+     {
+        if ((e_config->desklock_login_box_zone == -2) && (zone != 
current_zone))
+          nocreate = 1;
+        else if ((e_config->desklock_login_box_zone > -1) && 
(e_config->desklock_login_box_zone != 
(int)eina_list_count(edd->elock_wnd_list)))
+          nocreate = 1;
+     }
+
+   if (!nocreate)
+     {
+        switch (e_config->desklock_auth_method)
+          {
+           case E_DESKLOCK_AUTH_METHOD_SYSTEM:
+           case E_DESKLOCK_AUTH_METHOD_PERSONAL:
+             _text_login_box_add(lp);
+             break;
+           case E_DESKLOCK_AUTH_METHOD_PIN:
+             _pin_box_add(lp);
+             edje_object_part_swallow(lp->bg_object, "e.swallow.login_box", 
lp->login_box);
+
+             evas_object_clip_set(lp->login_box, lp->zone->bg_clip_object);
+
+             E_LIST_HANDLER_APPEND(edd->handlers, 
ECORE_EVENT_MOUSE_BUTTON_DOWN, _pin_mouse_button_down, lp);
+             E_LIST_HANDLER_APPEND(edd->handlers, ECORE_EVENT_MOUSE_BUTTON_UP, 
_pin_mouse_button_up, lp);
+             break;
+           case E_DESKLOCK_AUTH_METHOD_EXTERNAL: //handled by e_desklock
+           default: break;
+          }
+     }
 
    evas_event_thaw(evas);
 
@@ -436,8 +618,7 @@ static int
 _lokker_check_auth(void)
 {
    if (!edd) return 0;
-#ifdef HAVE_PAM
-   if (e_config->desklock_auth_method == 0)
+   if (e_desklock_is_system())
      {
         int ret;
 
@@ -446,22 +627,32 @@ _lokker_check_auth(void)
         _lokker_null();
         return ret;
      }
-   else if (e_config->desklock_auth_method == 1)
+   else if (e_desklock_is_personal())
      {
-#endif
-   if ((e_config->desklock_passwd) && (edd->passwd && edd->passwd[0]) &&
-       (e_config->desklock_passwd == eina_hash_djb2(edd->passwd, 
strlen(edd->passwd))))
+        if ((e_config->desklock_passwd) && (edd->passwd && edd->passwd[0]) &&
+            (e_config->desklock_passwd == eina_hash_djb2(edd->passwd, 
strlen(edd->passwd))))
+          {
+             /* password ok */
+             /* security - null out passwd string once we are done with it */
+             _lokker_null();
+             e_desklock_hide();
+             return 1;
+          }
+     }
+   else if (lokker_is_pin())
      {
-        /* password ok */
-        /* security - null out passwd string once we are done with it */
-        _lokker_null();
-        e_desklock_hide();
-        return 1;
+        if (edd->passwd && edd->passwd[0])
+          {
+             if (eina_hash_djb2(edd->passwd, strlen(edd->passwd)) ==
+                 e_config->desklock_pin)
+               {
+                  _lokker_null();
+                  e_desklock_hide();
+                  return 1;
+               }
+          }
      }
-#ifdef HAVE_PAM
-}
 
-#endif
    /* password is definitely wrong */
    _lokker_state_set(LOKKER_STATE_INVALID);
    _lokker_null();
@@ -518,6 +709,16 @@ _lokker_cb_key_down(void *data EINA_UNUSED, int type 
EINA_UNUSED, void *event)
         /* here we have to grab a password */
         if (ev->compose)
           {
+             if (lokker_is_pin())
+               {
+                  /* block non-digits */
+                  const char *c;
+
+                  for (c = ev->compose; c[0]; c++)
+                    {
+                       if (!isdigit(c[0])) return ECORE_CALLBACK_RENEW;
+                    }
+               }
              if (edd->selected)
                {
                   _lokker_null();
@@ -542,6 +743,15 @@ lokker_lock(void)
    E_Comp *comp;
 
    if (edd) return EINA_TRUE;
+
+   if (lokker_is_pin())
+     {
+        if (!e_config->desklock_pin)
+          {
+             e_configure_registry_call("screen/screen_lock", NULL, NULL);
+             return EINA_FALSE;
+          }
+     }
    edd = E_NEW(Lokker_Data, 1);
    if (!edd) return EINA_FALSE;
 

-- 


Reply via email to