You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
527 lines
14 KiB
527 lines
14 KiB
#include "entrance_client.h" |
|
|
|
#define ENTRANCE_PASSWD_LEN 256 |
|
|
|
typedef struct Entrance_Gui_Login_ Entrance_Gui_Login; |
|
|
|
static void _login_reset(Evas_Object *widget); |
|
static void _login_backspace(Evas_Object *widget); |
|
static void _login_delete(Evas_Object *widget); |
|
static void _login_select(Evas_Object *widget); |
|
static void _login_update(Evas_Object *widget); |
|
static void _login_check_auth(Evas_Object *widget); |
|
static void _login_password_catch(Evas_Object *widget, Eina_Bool catch); |
|
static Eina_Bool _login_key_down_cb(void *data, int type, void *event); |
|
static void _login_xsession_update(Evas_Object *obj); |
|
static void _login_xsession_guess(void *data, const char *user); |
|
static void _login_xsession_clicked_cb(void *data, Evas_Object *obj, void *event_info); |
|
static Eina_Bool _login_input_event_cb(void *data EINA_UNUSED, Evas_Object *obj, Evas_Object *src, Evas_Callback_Type type, void *event_info); |
|
static void _login_login_unfocused_cb(void *data, Evas_Object *obj, void *event); |
|
static void _login_password_focused_cb(void *data, Evas_Object *obj, void *event); |
|
static void _login_password_unfocused_cb(void *data, Evas_Object *obj, void *event); |
|
static void _login_login_activated_cb(void *data, Evas_Object *obj, void *event); |
|
static char *_login_xsession_text_get(void *data, Evas_Object *obj, const char *part); |
|
static void _login_auth_cb(void *data, const char *user, Eina_Bool granted); |
|
static void _entrance_login_session_set(Evas_Object *widget, const char *name); |
|
|
|
static Entrance_Fill *_login_fill; |
|
|
|
struct Entrance_Gui_Login_ |
|
{ |
|
Ecore_Event_Handler *handler; |
|
char passwd[ENTRANCE_PASSWD_LEN]; |
|
Entrance_Xsession *session; |
|
struct |
|
{ |
|
Entrance_Login_Cb login; |
|
void *data; |
|
} func; |
|
void *auth; |
|
Eina_Bool open_session : 1; |
|
Eina_Bool selected : 1; |
|
Eina_Bool catch : 1; |
|
Eina_Bool wait : 1; |
|
}; |
|
|
|
#define LOGIN_GET(widget) \ |
|
Entrance_Gui_Login *login; \ |
|
login = evas_object_data_get(widget, "entrance"); \ |
|
if (!login) return |
|
|
|
static void |
|
_login_reset(Evas_Object *widget) |
|
{ |
|
LOGIN_GET(widget); |
|
memset(login->passwd, 0, sizeof(char) * ENTRANCE_PASSWD_LEN); |
|
_login_update(widget); |
|
} |
|
|
|
static void |
|
_login_backspace(Evas_Object *widget) |
|
{ |
|
int len, val, pos; |
|
|
|
LOGIN_GET(widget); |
|
len = strlen(login->passwd); |
|
if (len > 0) |
|
{ |
|
pos = evas_string_char_prev_get(login->passwd, len, &val); |
|
if ((pos < len) && (pos >= 0)) |
|
{ |
|
login->passwd[pos] = '\0'; |
|
_login_update(widget); |
|
} |
|
} |
|
} |
|
|
|
static void |
|
_login_delete(Evas_Object *widget) |
|
{ |
|
_login_backspace(widget); |
|
} |
|
|
|
static void |
|
_login_select(Evas_Object *widget) |
|
{ |
|
LOGIN_GET(widget); |
|
Evas_Object *o; |
|
o = elm_object_part_content_get(widget, "entrance.password"); |
|
elm_entry_select_all(o); |
|
login->selected = EINA_TRUE; |
|
} |
|
|
|
static void |
|
_login_unselect(Evas_Object *widget) |
|
{ |
|
Evas_Object *o; |
|
LOGIN_GET(widget); |
|
o = elm_object_part_content_get(widget, "entrance.password"); |
|
elm_entry_select_none(o); |
|
login->selected = EINA_FALSE; |
|
} |
|
|
|
static void |
|
_login_update(Evas_Object *widget) |
|
{ |
|
Evas_Object *o; |
|
char str[ENTRANCE_PASSWD_LEN]; |
|
int len; |
|
LOGIN_GET(widget); |
|
|
|
len = eina_unicode_utf8_get_len(login->passwd); |
|
|
|
memset(str, '*', sizeof(char) * len); |
|
str[len] = '\0'; |
|
|
|
o = elm_object_part_content_get(widget, "entrance.password"); |
|
elm_object_text_set(o, str); |
|
elm_entry_cursor_end_set(o); |
|
} |
|
|
|
static void |
|
_login_check_auth(Evas_Object *widget) |
|
{ |
|
Evas_Object *o; |
|
const char *host; |
|
LOGIN_GET(widget); |
|
|
|
o = elm_object_part_content_get(widget, "entrance.login"); |
|
host = elm_entry_markup_to_utf8(elm_object_text_get(o)); |
|
login->wait = EINA_TRUE; |
|
if (!login->auth) |
|
login->auth = entrance_connect_auth_cb_add(_login_auth_cb, widget); |
|
if (login->session) |
|
entrance_connect_auth_send(host, login->passwd, |
|
login->session->name, |
|
login->open_session); |
|
else |
|
entrance_connect_auth_send(host, login->passwd, |
|
NULL, login->open_session); |
|
|
|
_login_reset(widget); |
|
} |
|
|
|
static void |
|
_login_password_catch(Evas_Object *widget, Eina_Bool catch) |
|
{ |
|
LOGIN_GET(widget); |
|
if (login->catch != catch) |
|
{ |
|
if (catch) |
|
{ |
|
PT("catch password\n"); |
|
login->handler = ecore_event_handler_add( |
|
ECORE_EVENT_KEY_DOWN, _login_key_down_cb, widget); |
|
} |
|
else |
|
{ |
|
PT("uncatch password\n"); |
|
ecore_event_handler_del(login->handler); |
|
login->handler = NULL; |
|
} |
|
} |
|
login->catch = catch; |
|
} |
|
|
|
static Eina_Bool |
|
_login_key_down_cb(void *data, int type EINA_UNUSED, void *event) |
|
{ |
|
Ecore_Event_Key *ev; |
|
LOGIN_GET(data) ECORE_CALLBACK_PASS_ON; |
|
ev = event; |
|
|
|
|
|
elm_object_signal_emit(data, "entrance,auth,changed", ""); |
|
elm_object_signal_emit( |
|
elm_object_part_content_get(data, "entrance.password"), |
|
"entrance,auth,changed", ""); |
|
|
|
if (!strcmp(ev->key, "KP_Enter")) |
|
{ |
|
_login_check_auth(data); |
|
} |
|
else if (!strcmp(ev->key, "Return")) |
|
{ |
|
_login_check_auth(data); |
|
} |
|
else if (!strcmp(ev->key, "BackSpace")) |
|
{ |
|
if (login->selected) |
|
{ |
|
_login_reset(data); |
|
_login_unselect(data); |
|
} |
|
else |
|
_login_backspace(data); |
|
} |
|
else if (!strcmp(ev->key, "Delete")) |
|
{ |
|
if (login->selected) |
|
{ |
|
_login_reset(data); |
|
} |
|
else |
|
_login_delete(data); |
|
} |
|
else if ((!strcmp(ev->key, "Tab")) |
|
|| (!strcmp(ev->key, "ISO_Left_Tab"))) |
|
{ |
|
if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) |
|
{ |
|
PT("focus previous\n"); |
|
elm_object_focus_next(data, ELM_FOCUS_PREVIOUS); |
|
} |
|
else |
|
{ |
|
PT("focus next\n"); |
|
elm_object_focus_next(data, ELM_FOCUS_NEXT); |
|
} |
|
} |
|
else if ((!strcmp(ev->key, "u")) |
|
&& (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) |
|
{ |
|
_login_reset(data); |
|
} |
|
else if ((!strcmp(ev->key, "a")) |
|
&& (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) |
|
{ |
|
_login_select(data); |
|
} |
|
else |
|
{ |
|
if (ev->compose) |
|
{ |
|
if (login->selected) |
|
{ |
|
_login_reset(data); |
|
_login_unselect(data); |
|
} |
|
if (strlen(login->passwd) < |
|
(ENTRANCE_PASSWD_LEN - strlen(ev->compose))) |
|
{ |
|
strcat(login->passwd, ev->compose); |
|
_login_update(data); |
|
} |
|
} |
|
} |
|
return ECORE_CALLBACK_PASS_ON; |
|
} |
|
|
|
static Eina_Bool |
|
_login_input_event_cb(void *data, Evas_Object *obj EINA_UNUSED, Evas_Object *src EINA_UNUSED, Evas_Callback_Type type, void *event_info EINA_UNUSED) |
|
{ |
|
LOGIN_GET(data) EINA_FALSE; |
|
return (login->catch |
|
&& ((type == EVAS_CALLBACK_KEY_UP) |
|
|| (type == EVAS_CALLBACK_KEY_DOWN))); |
|
} |
|
|
|
static void |
|
_login_login_unfocused_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) |
|
{ |
|
Evas_Object *o; |
|
const char *hostname; |
|
LOGIN_GET(data); |
|
|
|
o = elm_object_part_content_get(data, "entrance.login"); |
|
hostname = elm_entry_markup_to_utf8(elm_object_text_get(o)); |
|
|
|
_login_xsession_guess(data, hostname); |
|
} |
|
|
|
static void |
|
_login_password_focused_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) |
|
{ |
|
_login_password_catch(data, EINA_TRUE); |
|
} |
|
|
|
static void |
|
_login_password_unfocused_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) |
|
{ |
|
_login_password_catch(data, EINA_FALSE); |
|
} |
|
|
|
static void |
|
_login_login_activated_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) |
|
{ |
|
elm_object_focus_set(data, EINA_TRUE); |
|
edje_object_signal_emit(data, |
|
"entrance,auth,enable", ""); |
|
} |
|
|
|
static char * |
|
_login_xsession_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part) |
|
{ |
|
Entrance_Xsession *xsession; |
|
xsession = data; |
|
if ((part) && (!strcmp(part, "icon"))) |
|
{ |
|
if (xsession->icon) |
|
return strdup(xsession->icon); |
|
else |
|
return NULL; |
|
} |
|
return strdup(xsession->name); |
|
|
|
} |
|
|
|
static void |
|
_login_xsession_update(Evas_Object *obj) |
|
{ |
|
Evas_Object *o, *icon; |
|
LOGIN_GET(obj); |
|
o = elm_object_part_content_get(obj, "entrance.xsessions"); |
|
if (!login->session) return; |
|
icon = elm_icon_add(o); |
|
elm_object_text_set(o, login->session->name); |
|
elm_image_file_set(o, login->session->icon, NULL); |
|
elm_object_content_set(o, icon); |
|
} |
|
|
|
static void |
|
_login_xsession_guess(void *data, const char *user) |
|
{ |
|
const Eina_List *users, *l; |
|
Entrance_Login *eu; |
|
LOGIN_GET(data); |
|
|
|
users = entrance_gui_users_get(); |
|
EINA_LIST_FOREACH(users, l, eu) |
|
{ |
|
if (!strcmp(eu->login, user)) |
|
{ |
|
_entrance_login_session_set(data, eu->lsess); |
|
entrance_gui_user_bg_set(eu->bg.path, eu->bg.group); |
|
break; |
|
} |
|
} |
|
|
|
if (!l) |
|
{ |
|
_entrance_login_session_set(data, NULL); |
|
entrance_gui_user_bg_set(NULL, NULL); |
|
} |
|
} |
|
|
|
static void |
|
_login_xsession_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) |
|
{ |
|
LOGIN_GET(data); |
|
login->session = elm_object_item_data_get(event_info); |
|
_login_xsession_update(data); |
|
} |
|
|
|
static void |
|
_login_auth_cb(void *data, const char *user, Eina_Bool granted) |
|
{ |
|
LOGIN_GET(data); |
|
if (login->wait) |
|
{ |
|
if (login->func.login) |
|
login->func.login(login->func.data, user, granted); |
|
login->wait = EINA_FALSE; |
|
entrance_connect_auth_cb_del(login->auth); |
|
login->auth = NULL; |
|
if (!granted) |
|
{ |
|
elm_object_signal_emit(data, |
|
"entrance,auth,error", ""); |
|
elm_object_signal_emit( |
|
elm_object_part_content_get(data, "entrance.login"), |
|
"entrance,auth,error", "login"); |
|
elm_object_signal_emit( |
|
elm_object_part_content_get(data, "entrance.password"), |
|
"entrance,auth,error", "password"); |
|
} |
|
else |
|
{ |
|
elm_object_signal_emit(data, |
|
"entrance,auth,valid", ""); |
|
elm_object_signal_emit( |
|
elm_object_part_content_get(data, "entrance.login"), |
|
"entrance,auth,valid", "login"); |
|
elm_object_signal_emit( |
|
elm_object_part_content_get(data, "entrance.password"), |
|
"entrance,auth,valid", "password"); |
|
} |
|
} |
|
} |
|
|
|
static void |
|
_entrance_login_session_set(Evas_Object *widget, const char *name) |
|
{ |
|
Entrance_Xsession *sess; |
|
const Eina_List *l = NULL; |
|
LOGIN_GET(widget); |
|
if (name) |
|
{ |
|
EINA_LIST_FOREACH(entrance_gui_xsessions_get(), l, sess) |
|
{ |
|
if ((sess->name) && |
|
(!strcmp(sess->name, name))) |
|
{ |
|
break; |
|
} |
|
} |
|
} |
|
if (l) |
|
login->session = sess; |
|
else |
|
login->session = eina_list_data_get(entrance_gui_xsessions_get()); |
|
_login_xsession_update(widget); |
|
} |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
|
|
void |
|
entrance_login_init(void) |
|
{ |
|
_login_fill = entrance_fill_new(NULL, _login_xsession_text_get, |
|
NULL, NULL, NULL); |
|
} |
|
|
|
void |
|
entrance_login_shutdown(void) |
|
{ |
|
// TODO callback_del on widget |
|
//_login_password_catch(NULL, EINA_FALSE); |
|
//free(_login); |
|
entrance_fill_del(_login_fill); |
|
} |
|
|
|
Evas_Object * |
|
entrance_login_add(Evas_Object *obj, Entrance_Login_Cb login_cb, void *data) |
|
{ |
|
Evas_Object *o, *h, *p; |
|
Entrance_Gui_Login *login; |
|
|
|
/* layout */ |
|
login = calloc(1, sizeof(Entrance_Gui_Login)); |
|
login->func.login = login_cb; |
|
login->func.data = data; |
|
o = entrance_gui_theme_get(obj, "entrance/login"); |
|
evas_object_data_set(o, "entrance", login); |
|
|
|
|
|
/* login */ |
|
h = elm_entry_add(o); |
|
elm_entry_single_line_set(h, EINA_TRUE); |
|
elm_entry_scrollable_set(h, EINA_TRUE); |
|
elm_object_part_content_set(o, "entrance.login", h); |
|
elm_object_focus_set(h, EINA_TRUE); |
|
evas_object_show(h); |
|
|
|
/* password */ |
|
p = elm_entry_add(o); |
|
elm_entry_single_line_set(p, EINA_TRUE); |
|
elm_entry_scrollable_set(p, EINA_TRUE); |
|
elm_object_part_content_set(o, "entrance.password", p); |
|
evas_object_show(p); |
|
|
|
/* callbacks */ |
|
elm_object_event_callback_add(o, _login_input_event_cb, o); |
|
evas_object_smart_callback_add(h, "activated", |
|
_login_login_activated_cb, p); |
|
evas_object_smart_callback_add(h, "unfocused", |
|
_login_login_unfocused_cb, o); |
|
evas_object_smart_callback_add(p, "focused", |
|
_login_password_focused_cb, o); |
|
evas_object_smart_callback_add(p, "unfocused", |
|
_login_password_unfocused_cb, o); |
|
h = elm_hoversel_add(o); |
|
elm_hoversel_hover_parent_set(h, obj); |
|
evas_object_data_set(o, "entrance", login); |
|
elm_object_part_content_set(o, "entrance.xsessions", h); |
|
_login_xsession_update(o); |
|
return o; |
|
} |
|
|
|
void |
|
entrance_login_xsessions_populate(Evas_Object *widget, Eina_List *xsessions) |
|
{ |
|
PT("Session set\n"); |
|
Evas_Object *o; |
|
LOGIN_GET(widget); |
|
|
|
o = elm_object_part_content_get(widget, "entrance.xsessions"); |
|
entrance_fill(o, _login_fill, xsessions, NULL, |
|
_login_xsession_clicked_cb, widget); |
|
login->session = eina_list_data_get(xsessions); |
|
_login_xsession_update(widget); |
|
edje_object_signal_emit(widget, |
|
"entrance,xsession,enabled", ""); |
|
} |
|
|
|
void |
|
entrance_login_login_set(Evas_Object *widget, const char *user) |
|
{ |
|
Evas_Object *o; |
|
o = elm_object_part_content_get(widget, "entrance.login"); |
|
elm_object_text_set(o, user); |
|
elm_object_signal_emit(widget, |
|
"entrance,auth,enable", ""); |
|
o = elm_object_part_content_get(widget, "entrance.password"); |
|
elm_object_focus_set(o, EINA_TRUE); |
|
|
|
_login_xsession_guess(widget, user); |
|
} |
|
|
|
void |
|
entrance_login_open_session_set(Evas_Object *widget, Eina_Bool open_session) |
|
{ |
|
Evas_Object *o; |
|
LOGIN_GET(widget); |
|
open_session = !!open_session; |
|
if (login->open_session != open_session) |
|
{ |
|
login->open_session = open_session; |
|
o = elm_object_part_content_get(widget, "entrance.xsessions"); |
|
if (login->open_session) |
|
evas_object_show(o); |
|
else |
|
evas_object_hide(o); |
|
} |
|
} |
|
|
|
|