forked from enlightenment/enlightenment
auth and desklock - support auth by fingerprint and show status
This commit is contained in:
parent
bf44092492
commit
1cf5595208
339
src/bin/e_auth.c
339
src/bin/e_auth.c
|
@ -1,5 +1,32 @@
|
|||
#include "e.h"
|
||||
|
||||
E_API int E_EVENT_AUTH_FPRINT_AVAILABLE = 0;
|
||||
E_API int E_EVENT_AUTH_FPRINT_STATUS = 0;
|
||||
|
||||
static Eldbus_Connection *conn = NULL;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EINTERN int
|
||||
e_auth_init(void)
|
||||
{
|
||||
E_EVENT_AUTH_FPRINT_AVAILABLE = ecore_event_type_new();
|
||||
E_EVENT_AUTH_FPRINT_STATUS = ecore_event_type_new();
|
||||
|
||||
conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
|
||||
return 1;
|
||||
}
|
||||
|
||||
EINTERN int
|
||||
e_auth_shutdown(void)
|
||||
{
|
||||
if (conn) eldbus_connection_unref(conn);
|
||||
conn = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
E_API int
|
||||
e_auth_begin(char *passwd)
|
||||
{
|
||||
|
@ -72,3 +99,315 @@ out:
|
|||
e_util_memclear(buf, buflen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Eldbus_Object *obj_fprint = NULL;
|
||||
static Eldbus_Proxy *proxy_fprint = NULL;
|
||||
|
||||
static Eldbus_Object *obj_fprint_device = NULL;
|
||||
static Eldbus_Proxy *proxy_fprint_device = NULL;
|
||||
static E_Auth_Fprint_Type finger_type = E_AUTH_FPRINT_TYPE_UNKNOWN;
|
||||
static const char *finger_name = NULL;
|
||||
static const char *user_name = NULL;
|
||||
|
||||
static void
|
||||
_cb_event_free(void *data EINA_UNUSED, void *event)
|
||||
{
|
||||
free(event);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_verify_start(void *data EINA_UNUSED, const Eldbus_Message *m,
|
||||
Eldbus_Pending *p EINA_UNUSED)
|
||||
{
|
||||
const char *name = NULL, *text = NULL;
|
||||
|
||||
printf("FP: verify start...\n");
|
||||
if (eldbus_message_error_get(m, &name, &text))
|
||||
{
|
||||
fprintf(stderr, "Fprint err: %s %s\n", name, text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_verify_begin(void)
|
||||
{
|
||||
Eldbus_Message *m2;
|
||||
Eldbus_Message_Iter *iter;
|
||||
|
||||
// brute force stop a previous verify - if its active - dont care about reply
|
||||
m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "VerifyStop");
|
||||
if (m2)
|
||||
{
|
||||
eldbus_proxy_send(proxy_fprint_device, m2, NULL, NULL, -1);
|
||||
}
|
||||
m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "VerifyStart");
|
||||
if (m2)
|
||||
{
|
||||
iter = eldbus_message_iter_get(m2);
|
||||
eldbus_message_iter_basic_append(iter, 's', finger_name);
|
||||
eldbus_proxy_send(proxy_fprint_device, m2, _cb_verify_start, NULL, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_verify(void *data EINA_UNUSED, const Eldbus_Message *m)
|
||||
{
|
||||
Eina_Bool val = EINA_FALSE;
|
||||
const char *txt = NULL;
|
||||
const char *name = NULL, *text = NULL;
|
||||
E_Event_Auth_Fprint_Status *ev;
|
||||
|
||||
printf("FP: verify ...\n");
|
||||
if (eldbus_message_error_get(m, &name, &text))
|
||||
{
|
||||
fprintf(stderr, "Fprint err: %s %s\n", name, text);
|
||||
return;
|
||||
}
|
||||
if (!eldbus_message_arguments_get(m, "sb", &txt, &val)) return;
|
||||
printf("FP: verify = [%s] %i\n", txt, val);
|
||||
if (!txt) return;
|
||||
|
||||
ev = calloc(1, sizeof(E_Event_Auth_Fprint_Status));
|
||||
if (!ev) return;
|
||||
|
||||
if (!strcmp(txt, "verify-match")) ev->status = E_AUTH_FPRINT_STATUS_AUTH;
|
||||
else if (!strcmp(txt, "verify-no-match")) ev->status = E_AUTH_FPRINT_STATUS_NO_AUTH;
|
||||
else if (!strcmp(txt, "verify-swipe-too-short")) ev->status = E_AUTH_FPRINT_STATUS_SHORT_SWIPE;
|
||||
else if (!strcmp(txt, "verify-finger-not-centered")) ev->status = E_AUTH_FPRINT_STATUS_NO_CENTER;
|
||||
else if (!strcmp(txt, "verify-remove-and-retry")) ev->status = E_AUTH_FPRINT_STATUS_REMOVE_RETRY;
|
||||
else if (!strcmp(txt, "verify-retry-scan")) ev->status = E_AUTH_FPRINT_STATUS_RETRY;
|
||||
else if (!strcmp(txt, "verify-disconnected")) ev->status = E_AUTH_FPRINT_STATUS_DISCONNECT;
|
||||
else if (!strcmp(txt, "verify-unknown-error")) ev->status = E_AUTH_FPRINT_STATUS_ERROR;
|
||||
else ev->status = E_AUTH_FPRINT_STATUS_ERROR;
|
||||
ecore_event_add(E_EVENT_AUTH_FPRINT_STATUS, ev, _cb_event_free, NULL);
|
||||
// reset the verify and try again if verify end and NOT an auth ok
|
||||
if ((val) && // end of verify
|
||||
(ev->status != E_AUTH_FPRINT_STATUS_AUTH))
|
||||
{
|
||||
_verify_begin();
|
||||
}
|
||||
if (ev->status == E_AUTH_FPRINT_STATUS_AUTH)
|
||||
{
|
||||
Eldbus_Message *m2;
|
||||
|
||||
m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "Release");
|
||||
eldbus_proxy_send(proxy_fprint_device, m2, NULL, NULL, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_list_enrolled_fingers(void *data EINA_UNUSED, const Eldbus_Message *m,
|
||||
Eldbus_Pending *p EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Message_Iter *array = NULL;
|
||||
const char *name = NULL, *text = NULL;
|
||||
|
||||
printf("FP: list fingers...\n");
|
||||
if (eldbus_message_error_get(m, &name, &text))
|
||||
{
|
||||
fprintf(stderr, "Fprint err: %s %s\n", name, text);
|
||||
return;
|
||||
}
|
||||
printf("FP: list fingers...\n");
|
||||
if (eldbus_message_arguments_get(m, "as", &array))
|
||||
{
|
||||
char *txt = NULL;
|
||||
|
||||
printf("FP: ...\n");
|
||||
while (eldbus_message_iter_get_and_next(array, 's', &txt))
|
||||
{
|
||||
eina_stringshare_replace(&finger_name, txt);
|
||||
printf("FP: first finger is [%s]\n", txt);
|
||||
if (finger_type != E_AUTH_FPRINT_TYPE_UNKNOWN)
|
||||
{
|
||||
E_Event_Auth_Fprint_Available *ev = calloc(1, sizeof(E_Event_Auth_Fprint_Available));
|
||||
if (ev)
|
||||
{
|
||||
ev->type = finger_type;
|
||||
ecore_event_add(E_EVENT_AUTH_FPRINT_AVAILABLE, ev,
|
||||
_cb_event_free, NULL);
|
||||
}
|
||||
}
|
||||
_verify_begin();
|
||||
break;
|
||||
}
|
||||
// call VeriftyStart 'first finger found'
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_claim(void *data EINA_UNUSED, const Eldbus_Message *m EINA_UNUSED,
|
||||
Eldbus_Pending *p EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Proxy *proxy = proxy_fprint_device;
|
||||
Eldbus_Message *m2;
|
||||
Eldbus_Message_Iter *iter;
|
||||
const char *name = NULL, *text = NULL;
|
||||
|
||||
printf("FP: claim\n");
|
||||
if (eldbus_message_error_get(m, &name, &text))
|
||||
{
|
||||
fprintf(stderr, "Fprint err: %s %s\n", name, text);
|
||||
return;
|
||||
}
|
||||
// ListEnrolledFingrs '$USER' -> "as"
|
||||
printf("FP: claim ok\n");
|
||||
m2 = eldbus_proxy_method_call_new(proxy, "ListEnrolledFingers");
|
||||
iter = eldbus_message_iter_get(m2);
|
||||
eldbus_message_iter_basic_append(iter, 's', user_name);
|
||||
eldbus_proxy_send(proxy, m2, _cb_list_enrolled_fingers, NULL, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_prop_entry(void *data EINA_UNUSED, const void *key, Eldbus_Message_Iter *var)
|
||||
{
|
||||
const char *skey = key;
|
||||
|
||||
if (!strcmp(skey, "scan-type"))
|
||||
{
|
||||
const char *val = NULL;
|
||||
if (eldbus_message_iter_arguments_get(var, "s", &val))
|
||||
{
|
||||
if (!strcmp(val, "press")) finger_type = E_AUTH_FPRINT_TYPE_PRESS;
|
||||
else if (!strcmp(val, "swipe")) finger_type = E_AUTH_FPRINT_TYPE_SWIPE;
|
||||
printf("FP: type = %s\n", val);
|
||||
if (finger_name)
|
||||
{
|
||||
E_Event_Auth_Fprint_Available *ev =
|
||||
calloc(1, sizeof(E_Event_Auth_Fprint_Available));
|
||||
if (ev)
|
||||
{
|
||||
ev->type = finger_type;
|
||||
ecore_event_add(E_EVENT_AUTH_FPRINT_AVAILABLE, ev,
|
||||
_cb_event_free, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_props(void *data EINA_UNUSED, const Eldbus_Message *m,
|
||||
Eldbus_Pending *pending EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Message_Iter *array = NULL;
|
||||
|
||||
if (eldbus_message_error_get(m, NULL, NULL)) return;
|
||||
|
||||
if (eldbus_message_arguments_get(m, "a{sv}", &array))
|
||||
eldbus_message_iter_dict_iterate(array, "sv", _cb_prop_entry, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_get_default_device(void *data EINA_UNUSED, const Eldbus_Message *m,
|
||||
Eldbus_Pending *p EINA_UNUSED)
|
||||
{
|
||||
Eldbus_Object *obj;
|
||||
Eldbus_Proxy *proxy;
|
||||
const char *dev = NULL;
|
||||
const char *name = NULL, *text = NULL;
|
||||
|
||||
printf("FP: get default device...\n");
|
||||
if (eldbus_message_error_get(m, &name, &text))
|
||||
{
|
||||
fprintf(stderr, "Fprint err: %s %s\n", name, text);
|
||||
return;
|
||||
}
|
||||
if (!eldbus_message_arguments_get(m, "o", &dev)) return;
|
||||
printf("FP: dev = %s\n", dev);
|
||||
obj = eldbus_object_get(conn, "net.reactivated.Fprint", dev);
|
||||
if (obj)
|
||||
{
|
||||
obj_fprint_device = obj;
|
||||
|
||||
printf("FP: 22 obj = %p\n", obj);
|
||||
proxy = eldbus_proxy_get(obj, "net.reactivated.Fprint.Device");
|
||||
if (proxy)
|
||||
{
|
||||
Eldbus_Message *m2;
|
||||
Eldbus_Message_Iter *iter;
|
||||
|
||||
printf("FP: 22 proxy = %p\n", proxy);
|
||||
proxy_fprint_device = proxy;
|
||||
|
||||
eldbus_proxy_property_get_all(proxy, _cb_props, NULL);
|
||||
|
||||
eldbus_proxy_signal_handler_add(proxy, "VerifyStatus",
|
||||
_cb_verify, NULL);
|
||||
// Claim '$USER'
|
||||
m2 = eldbus_proxy_method_call_new(proxy, "Claim");
|
||||
iter = eldbus_message_iter_get(m2);
|
||||
eldbus_message_iter_basic_append(iter, 's', user_name);
|
||||
eldbus_proxy_send(proxy, m2, _cb_claim, NULL, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_auth_fprint_begin(const char *user)
|
||||
{
|
||||
Eldbus_Object *obj;
|
||||
Eldbus_Proxy *proxy;
|
||||
|
||||
printf("FP: e_auth_fprint_begin\n");
|
||||
if (conn)
|
||||
{
|
||||
eina_stringshare_replace(&user_name, user);
|
||||
obj = eldbus_object_get(conn, "net.reactivated.Fprint",
|
||||
"/net/reactivated/Fprint/Manager");
|
||||
printf("FP: obj=%p\n", obj);
|
||||
if (obj)
|
||||
{
|
||||
obj_fprint = obj;
|
||||
|
||||
proxy = eldbus_proxy_get(obj, "net.reactivated.Fprint.Manager");
|
||||
printf("FP: proxy=%p\n", proxy);
|
||||
if (proxy)
|
||||
{
|
||||
Eldbus_Message *m;
|
||||
|
||||
proxy_fprint = proxy;
|
||||
m = eldbus_proxy_method_call_new(proxy, "GetDefaultDevice");
|
||||
eldbus_proxy_send(proxy, m, _cb_get_default_device, NULL, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
E_API void
|
||||
e_auth_fprint_end(void)
|
||||
{
|
||||
if (conn)
|
||||
{
|
||||
if (obj_fprint_device)
|
||||
{
|
||||
Eldbus_Message *m2;
|
||||
|
||||
m2 = eldbus_proxy_method_call_new(proxy_fprint_device, "Release");
|
||||
eldbus_proxy_send(proxy_fprint_device, m2, NULL, NULL, -1);
|
||||
if (proxy_fprint_device)
|
||||
{
|
||||
eldbus_proxy_unref(proxy_fprint_device);
|
||||
proxy_fprint_device = NULL;
|
||||
}
|
||||
eldbus_object_unref(obj_fprint_device);
|
||||
obj_fprint_device = NULL;
|
||||
}
|
||||
if (obj_fprint)
|
||||
{
|
||||
if (proxy_fprint)
|
||||
{
|
||||
eldbus_proxy_unref(proxy_fprint);
|
||||
proxy_fprint = NULL;
|
||||
}
|
||||
eldbus_object_unref(obj_fprint);
|
||||
obj_fprint = NULL;
|
||||
}
|
||||
}
|
||||
eina_stringshare_replace(&finger_name, NULL);
|
||||
eina_stringshare_replace(&user_name, NULL);
|
||||
finger_type = E_AUTH_FPRINT_TYPE_UNKNOWN;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,41 @@
|
|||
#ifndef E_AUTH_H
|
||||
#define E_AUTH_H
|
||||
|
||||
typedef enum _E_Auth_Fprint_Type
|
||||
{
|
||||
E_AUTH_FPRINT_TYPE_UNKNOWN,
|
||||
E_AUTH_FPRINT_TYPE_PRESS,
|
||||
E_AUTH_FPRINT_TYPE_SWIPE
|
||||
} E_Auth_Fprint_Type;
|
||||
|
||||
typedef enum _E_Auth_Fprint_Status
|
||||
{
|
||||
E_AUTH_FPRINT_STATUS_AUTH,
|
||||
E_AUTH_FPRINT_STATUS_NO_AUTH,
|
||||
E_AUTH_FPRINT_STATUS_SHORT_SWIPE,
|
||||
E_AUTH_FPRINT_STATUS_NO_CENTER,
|
||||
E_AUTH_FPRINT_STATUS_REMOVE_RETRY,
|
||||
E_AUTH_FPRINT_STATUS_RETRY,
|
||||
E_AUTH_FPRINT_STATUS_DISCONNECT,
|
||||
E_AUTH_FPRINT_STATUS_ERROR
|
||||
} E_Auth_Fprint_Status;
|
||||
|
||||
typedef struct _E_Event_Auth_Fprint_Available
|
||||
{
|
||||
E_Auth_Fprint_Type type;
|
||||
} E_Event_Auth_Fprint_Available;
|
||||
|
||||
typedef struct _E_Event_Auth_Fprint_Status
|
||||
{
|
||||
E_Auth_Fprint_Status status;
|
||||
} E_Event_Auth_Fprint_Status;
|
||||
|
||||
extern E_API int E_EVENT_AUTH_FPRINT_AVAILABLE;
|
||||
extern E_API int E_EVENT_AUTH_FPRINT_STATUS;
|
||||
|
||||
EINTERN int e_auth_init(void);
|
||||
EINTERN int e_auth_shutdown(void);
|
||||
|
||||
E_API int e_auth_begin(char *passwd);
|
||||
E_API int e_auth_polkit_begin(char *passwd, const char *cookie, unsigned int uid);
|
||||
|
||||
|
@ -17,4 +52,7 @@ e_auth_hash_djb2(const char *key, int len)
|
|||
return (int)hash_num;
|
||||
}
|
||||
|
||||
E_API void e_auth_fprint_begin(const char *user);
|
||||
E_API void e_auth_fprint_end(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -859,6 +859,11 @@ main(int argc, char **argv)
|
|||
TS("E_Acpi Init Done");
|
||||
_e_main_shutdown_push(e_acpi_shutdown);
|
||||
|
||||
TS("E_Auth Init");
|
||||
e_auth_init();
|
||||
TS("E_Auth Init Done");
|
||||
_e_main_shutdown_push(e_auth_shutdown);
|
||||
|
||||
TS("E_Backlight Init");
|
||||
if (!e_backlight_init())
|
||||
{
|
||||
|
|
|
@ -1557,3 +1557,12 @@ e_util_key_geometry_action_get(const char *key, int *x, int *y, int dx, int dy)
|
|||
|
||||
return E_UTIL_ACTION_DO;
|
||||
}
|
||||
|
||||
E_API const char *
|
||||
e_username_get(void)
|
||||
{
|
||||
struct passwd *pw = getpwuid(getuid());
|
||||
|
||||
if (pw) return pw->pw_name;
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ E_API Ecore_Exe *e_util_open(const char *exe, void *data);
|
|||
|
||||
E_API Ecore_Exe *e_util_exe_safe_run(const char *cmd, void *data);
|
||||
|
||||
E_API const char *e_username_get(void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
E_UTIL_ACTION_NONE,
|
||||
|
|
|
@ -741,6 +741,64 @@ _lokker_check_auth(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_lokker_cb_fprint_available(void *data EINA_UNUSED,
|
||||
int type EINA_UNUSED,
|
||||
void *event)
|
||||
{
|
||||
E_Event_Auth_Fprint_Available *ev = event;
|
||||
Lokker_Popup *lp;
|
||||
Eina_List *l;
|
||||
const char *sig = "";
|
||||
|
||||
if (!edd) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
if (ev->type == E_AUTH_FPRINT_TYPE_UNKNOWN) sig = "e,fprint,unknown";
|
||||
else if (ev->type == E_AUTH_FPRINT_TYPE_PRESS) sig = "e,fprint,press";
|
||||
else if (ev->type == E_AUTH_FPRINT_TYPE_SWIPE) sig = "e,fprint,swipe";
|
||||
EINA_LIST_FOREACH(edd->elock_wnd_list, l, lp)
|
||||
{
|
||||
if (lp->login_box) edje_object_signal_emit(lp->login_box, sig, "e");
|
||||
if (lp->bg_object) edje_object_signal_emit(lp->bg_object, sig, "e");
|
||||
}
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_lokker_cb_fprint_status(void *data EINA_UNUSED,
|
||||
int type EINA_UNUSED,
|
||||
void *event)
|
||||
{
|
||||
E_Event_Auth_Fprint_Status *ev = event;
|
||||
Lokker_Popup *lp;
|
||||
Eina_List *l;
|
||||
const char *sig = "";
|
||||
|
||||
if (!edd) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
if (ev->status == E_AUTH_FPRINT_STATUS_AUTH) sig = "e,fprint,auth,succeed";
|
||||
else if (ev->status == E_AUTH_FPRINT_STATUS_NO_AUTH) sig = "e,fprint,auth,fail";
|
||||
else if (ev->status == E_AUTH_FPRINT_STATUS_SHORT_SWIPE) sig = "e,fprint,auth,short";
|
||||
else if (ev->status == E_AUTH_FPRINT_STATUS_NO_CENTER) sig = "e,fprint,auth,nocenter";
|
||||
else if (ev->status == E_AUTH_FPRINT_STATUS_REMOVE_RETRY) sig = "e,fprint,auth,removeretry";
|
||||
else if (ev->status == E_AUTH_FPRINT_STATUS_RETRY) sig = "e,fprint,auth,retry";
|
||||
else if (ev->status == E_AUTH_FPRINT_STATUS_DISCONNECT) sig = "e,fprint,auth,disconnect";
|
||||
else if (ev->status == E_AUTH_FPRINT_STATUS_ERROR) sig = "e,fprint,auth,error";
|
||||
|
||||
EINA_LIST_FOREACH(edd->elock_wnd_list, l, lp)
|
||||
{
|
||||
if (lp->login_box) edje_object_signal_emit(lp->login_box, sig, "e");
|
||||
if (lp->bg_object) edje_object_signal_emit(lp->bg_object, sig, "e");
|
||||
}
|
||||
if (ev->status == E_AUTH_FPRINT_STATUS_AUTH)
|
||||
{
|
||||
/* security - null out passwd string once we are done with it */
|
||||
_lokker_null();
|
||||
e_desklock_hide();
|
||||
}
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
EINTERN Eina_Bool
|
||||
lokker_key_up(Ecore_Event_Key *ev)
|
||||
{
|
||||
|
@ -875,12 +933,18 @@ lokker_lock(void)
|
|||
edd->move_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _lokker_cb_mouse_move, NULL);
|
||||
|
||||
_text_passwd_update();
|
||||
|
||||
e_auth_fprint_begin(e_username_get());
|
||||
E_LIST_HANDLER_APPEND(edd->handlers, E_EVENT_AUTH_FPRINT_AVAILABLE, _lokker_cb_fprint_available, NULL);
|
||||
E_LIST_HANDLER_APPEND(edd->handlers, E_EVENT_AUTH_FPRINT_STATUS, _lokker_cb_fprint_status, NULL);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EINTERN void
|
||||
lokker_unlock(void)
|
||||
{
|
||||
e_auth_fprint_end();
|
||||
E_FREE_LIST(edd->elock_wnd_list, _lokker_popup_free);
|
||||
e_pointer_type_pop(e_comp->pointer, e_comp->pointer, "default");
|
||||
e_pointer_type_pop(e_comp->pointer, NULL, NULL);
|
||||
|
|
Loading…
Reference in New Issue