2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <Elementary.h>
22 #include <ui-gadget.h>
25 #include <appcore-efl.h>
28 #include "lockd-debug.h"
29 #include "lockd-window-mgr.h"
31 #define PACKAGE "starter"
32 #define SOS_KEY_COUNT 3
33 #define SOS_KEY_INTERVAL 0.5
36 Evas_Object *main_win;
37 Evas_Object *main_layout;
39 Ecore_X_Window lock_x_window;
41 Ecore_Event_Handler *h_keydown;
42 Ecore_Event_Handler *h_wincreate;
43 Ecore_Event_Handler *h_winshow;
45 Ecore_Timer *pTimerId; /* volume key timer */
48 int phone_lock_state; /* 0 : disable, 1 : enable */
49 int phone_lock_app_pid;
52 Eina_Bool volume_key_expire_cb(void *pData)
56 lockw_data *lockw = (lockw_data *) pData;
58 _DBG("volume_key_expire_cb..!!");
60 lockw->volume_key_cnt = 0;
62 return ECORE_CALLBACK_CANCEL;
65 static Eina_Bool _lockd_window_key_down_cb(void *data, int type, void *event)
67 Ecore_Event_Key *ev = event;
68 lockw_data *lockw = (lockw_data *) data;
72 LOCKD_DBG("Key Down CB : %s", ev->keyname);
74 ret = vconf_get_int(VCONFKEY_MESSAGE_SOS_STATE, &vconf_val);
78 LOCKD_ERR("_lockd_window_key_down_cb:VCONFKEY_MESSAGE_SOS_STATE FAILED");
79 return ECORE_CALLBACK_CANCEL;
82 if (!strcmp(ev->keyname, KEY_VOLUMEUP) || !strcmp(ev->keyname, KEY_VOLUMEDOWN)) {
83 if (vconf_val == VCONFKEY_MESSAGE_SOS_IDLE) {
84 if (lockw->volume_key_cnt == 0) {
85 lockw->volume_key_cnt++;
86 LOCKD_DBG("Volume key is pressed %d times", lockw->volume_key_cnt);
87 lockw->pTimerId = ecore_timer_add(SOS_KEY_INTERVAL, volume_key_expire_cb, lockw);
88 } else if (lockw->volume_key_cnt == SOS_KEY_COUNT) {
89 LOCKD_DBG("SOS msg invoked");
90 if (lockw->pTimerId != NULL) {
91 ecore_timer_del(lockw->pTimerId);
92 lockw->pTimerId = NULL;
93 lockw->volume_key_cnt =0;
94 vconf_set_int(VCONFKEY_MESSAGE_SOS_STATE, VCONFKEY_MESSAGE_SOS_INVOKED);
95 ecore_x_pointer_grab(lockw->lock_x_window);
98 if (lockw->pTimerId != NULL) {
99 ecore_timer_del(lockw->pTimerId);
100 lockw->pTimerId = NULL;
101 lockw->volume_key_cnt++;
102 LOCKD_DBG("Volume key is pressed %d times", lockw->volume_key_cnt);
103 lockw->pTimerId = ecore_timer_add(SOS_KEY_INTERVAL, volume_key_expire_cb, lockw);
107 } else if (!strcmp(ev->keyname, KEY_HOME)) {
108 if (vconf_val != VCONFKEY_MESSAGE_SOS_IDLE) {
109 LOCKD_DBG("Home key is pressed set to idle", lockw->volume_key_cnt);
110 vconf_set_int(VCONFKEY_MESSAGE_SOS_STATE, VCONFKEY_MESSAGE_SOS_IDLE);
111 ecore_x_pointer_ungrab();
115 return ECORE_CALLBACK_PASS_ON;
119 _lockd_window_check_validate_rect(Ecore_X_Display * dpy, Ecore_X_Window window)
122 Ecore_X_Window child;
129 unsigned int width = 0;
130 unsigned int height = 0;
131 unsigned int border = 0;
132 unsigned int depth = 0;
134 Eina_Bool ret = FALSE;
136 root = ecore_x_window_root_first_get();
139 (dpy, window, &root, &rel_x, &rel_y, &width, &height, &border,
141 if (XTranslateCoordinates
142 (dpy, window, root, 0, 0, &abs_x, &abs_y, &child)) {
143 if ((abs_x - border) >= 480 || (abs_y - border) >= 800
144 || (width + abs_x) <= 0 || (height + abs_y) <= 0) {
155 static Evas_Object *lockd_create_main_window(const char *pkgname)
157 Evas_Object *eo = NULL;
159 LOCKD_DBG("%s, %d", __func__, __LINE__);
161 eo = elm_win_add(NULL, pkgname, ELM_WIN_BASIC);
163 elm_win_title_set(eo, pkgname);
164 elm_win_borderless_set(eo, EINA_TRUE);
165 ecore_x_window_size_get(ecore_x_window_root_first_get(),
167 LOCKD_DBG("%s, %d, w = %d, h = %d", __func__, __LINE__, w, h);
168 evas_object_resize(eo, w, h);
173 static Evas_Object *lockd_create_main_layout(Evas_Object * parent)
175 Evas_Object *ly = NULL;
176 LOCKD_DBG("%s, %d", __func__, __LINE__);
178 ly = elm_layout_add(parent);
180 LOCKD_ERR("UI layout add error");
184 elm_layout_theme_set(ly, "layout", "application", "default");
185 evas_object_size_hint_weight_set(ly, EVAS_HINT_EXPAND,
187 evas_object_show(ly);
189 elm_win_resize_object_add(parent, ly);
190 elm_win_indicator_mode_set(parent, ELM_WIN_INDICATOR_SHOW);
195 static void _lockd_phone_lock_alpha_ug_layout_cb(ui_gadget_h ug,
196 enum ug_mode mode, void *priv)
198 lockw_data *lockw = (lockw_data *) priv;;
199 Evas_Object *base = NULL;
200 LOCKD_DBG("%s, %d", __func__, __LINE__);
205 base = ug_get_layout(ug);
210 case UG_MODE_FULLVIEW:
211 evas_object_size_hint_weight_set(base, EVAS_HINT_EXPAND,
213 elm_win_resize_object_add(lockw->main_win, base);
214 ug_disable_effect(ug); /* not use effect when destroy phone lock UG */
215 evas_object_show(base);
217 case UG_MODE_FRAMEVIEW:
218 /* elm_layout_content_set(lockw->main_layout, "content", base); *//* not used */
225 static void _lockd_phone_lock_alpha_ug_result_cb(ui_gadget_h ug,
226 service_h service, void *priv)
229 const char *val1 = NULL, *val2 = NULL;
230 lockw_data *lockw = (lockw_data *) priv;;
231 LOCKD_DBG("%s, %d", __func__, __LINE__);
236 service_get_extra_data(service, "name", &val1);
238 LOCKD_DBG("val1 = %s", val1);
243 service_get_extra_data(service, "result", &val2);
248 LOCKD_DBG("val2 = %s", val2);
251 if (!strcmp(val1, "phonelock-ug")) {
252 if (!strcmp(val2, "success")) {
253 LOCKD_DBG("password verified. Unlock!\n");
255 } else if (!strcmp(val1, "phonelock-ug-alpha")) {
266 static void _lockd_phone_lock_alpha_ug_destroy_cb(ui_gadget_h ug,
269 lockw_data *lockw = (lockw_data *) priv;;
270 LOCKD_DBG("%s, %d", __func__, __LINE__);
277 lockd_destroy_ug_window(lockw);
278 vconf_set_bool(VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION, TRUE);
281 static void _lockd_ug_window_set_win_prop(void *data, int type)
284 Evas_Object *win = NULL;
285 lockw_data *lockw = (lockw_data *) data;;
286 LOCKD_DBG("%s, %d", __func__, __LINE__);
291 win = lockw->main_win;
293 w = elm_win_xwindow_get(win);
295 if (type == ECORE_X_WINDOW_TYPE_NORMAL) {
296 ecore_x_netwm_window_type_set(w, ECORE_X_WINDOW_TYPE_NORMAL);
297 } else if (type == ECORE_X_WINDOW_TYPE_NOTIFICATION) {
298 ecore_x_netwm_window_type_set(w,
299 ECORE_X_WINDOW_TYPE_NOTIFICATION);
300 utilx_set_system_notification_level(ecore_x_display_get(), w,
301 UTILX_NOTIFICATION_LEVEL_NORMAL);
305 static void _lockd_ug_window_set_key_grab(void *data)
309 Evas_Object *win = NULL;
310 lockw_data *lockw = (lockw_data *) data;;
311 LOCKD_DBG("%s, %d", __func__, __LINE__);
316 win = lockw->main_win;
317 w = elm_win_xwindow_get(win);
318 ret = utilx_grab_key(ecore_x_display_get(), w, KEY_HOME, EXCLUSIVE_GRAB);
321 LOCKD_ERR("Key grab error : KEY_HOME");
323 ret = utilx_grab_key(ecore_x_display_get(), w, KEY_CONFIG, TOP_POSITION_GRAB);
326 LOCKD_ERR("Key grab error : KEY_CONFIG");
330 static void _lockd_ug_window_set_key_ungrab(void *data)
333 Ecore_X_Display *disp = NULL;
334 lockw_data *lockw = (lockw_data *) data;;
339 LOCKD_DBG("%s, %d", __func__, __LINE__);
340 disp = ecore_x_display_get();
341 xwin = elm_win_xwindow_get(lockw->main_win);
343 utilx_ungrab_key(disp, xwin, KEY_HOME);
344 utilx_ungrab_key(disp, xwin, KEY_CONFIG);
347 static void _lockd_ug_window_vconf_call_state_changed_cb(keynode_t * node,
352 lockw_data *lockw = (lockw_data *) data;
357 LOCKD_DBG("%s, %d", __func__, __LINE__);
358 api_ret = vconf_get_int(VCONFKEY_CALL_STATE, &vconf_val);
360 LOCKD_DBG("fail to get vconf key %s value",
361 VCONFKEY_CALL_STATE);
363 if (vconf_val == VCONFKEY_CALL_OFF) {
364 LOCKD_DBG("call off state..");
365 _lockd_ug_window_set_win_prop(lockw,
366 ECORE_X_WINDOW_TYPE_NOTIFICATION);
368 LOCKD_DBG("call on state..");
369 _lockd_ug_window_set_win_prop(lockw,
370 ECORE_X_WINDOW_TYPE_NORMAL);
376 static void _lockd_ug_window_register_vconf_changed(void *data)
378 LOCKD_DBG("%s, %d", __func__, __LINE__);
379 if (vconf_notify_key_changed
380 (VCONFKEY_CALL_STATE, _lockd_ug_window_vconf_call_state_changed_cb,
382 LOCKD_DBG("Fail to register");
386 static void _lockd_ug_window_unregister_vconf_changed(void *data)
388 LOCKD_DBG("%s, %d", __func__, __LINE__);
390 if (vconf_ignore_key_changed
391 (VCONFKEY_CALL_STATE,
392 _lockd_ug_window_vconf_call_state_changed_cb) != 0) {
393 LOCKD_DBG("Fail to unregister");
398 void _lockd_window_transient_for_set(void *data)
400 lockw_data *lockw = (lockw_data *) data;
401 Ecore_X_Window xwin_ug;
402 Ecore_X_Window xwin_lock;
407 LOCKD_DBG("%s, %d", __func__, __LINE__);
408 xwin_ug = elm_win_xwindow_get(lockw->main_win);
409 xwin_lock = lockw->lock_x_window;
411 LOCKD_DBG("ug win id : %x, and lock win id is :%x", xwin_ug, xwin_lock);
412 ecore_x_icccm_transient_for_set(xwin_ug, xwin_lock);
415 Eina_Bool _lockd_window_set_window_property_timer_cb(void *data)
417 Ecore_X_Window win = (Ecore_X_Window) data;
419 ("[MINSU] win id(%x) set lock screen window property to notification and level low\n",
422 /* Set notification type */
423 ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NOTIFICATION);
425 /* Set notification's priority */
426 utilx_set_system_notification_level(ecore_x_display_get(), win,
427 UTILX_NOTIFICATION_LEVEL_LOW);
432 static Window get_user_created_window(Window win)
435 int ret, size_ret = 0;
436 unsigned long num_ret = 0, bytes = 0;
437 unsigned char *prop_ret = NULL;
439 Atom prop_user_created_win;
441 prop_user_created_win =
442 XInternAtom(ecore_x_display_get(), "_E_USER_CREATED_WINDOW", False);
445 XGetWindowProperty(ecore_x_display_get(), win,
446 prop_user_created_win, 0L, 1L, False, 0,
447 &type_ret, &size_ret, &num_ret, &bytes,
450 if (ret != Success) {
452 XFree((void *)prop_ret);
454 } else if (!prop_ret) {
458 memcpy(&xid, prop_ret, sizeof(unsigned int));
459 XFree((void *)prop_ret);
466 lockd_window_set_window_property(lockw_data * data, int lock_app_pid,
469 Ecore_X_Event_Window_Create *e = event;
470 Ecore_X_Window user_window = 0;
471 lockw_data *lockw = (lockw_data *) data;
477 LOCKD_DBG("%s, %d", __func__, __LINE__);
479 user_window = get_user_created_window((Window) (e->win));
481 int ret = ecore_x_netwm_pid_get(user_window, &pid);
486 LOCKD_DBG("Check PID(%d) window. (lock_app_pid : %d)\n", pid,
489 if (lock_app_pid == pid) {
490 if (_lockd_window_check_validate_rect
491 (ecore_x_display_get(), user_window) == TRUE) {
492 lockw->lock_x_window = user_window;
494 ("This is lock application. Set window property. win id : %x",
497 /* window effect : fade in /out */
498 ecore_x_icccm_name_class_set(user_window, "LOCK_SCREEN",
501 /* Set notification type */
502 ecore_x_netwm_window_type_set(user_window,
503 ECORE_X_WINDOW_TYPE_NOTIFICATION);
505 /* Set notification's priority */
506 utilx_set_system_notification_level(ecore_x_display_get
508 UTILX_NOTIFICATION_LEVEL_NORMAL);
509 /* Set opaque state */
510 utilx_set_window_opaque_state(ecore_x_display_get(),
512 UTILX_OPAQUE_STATE_ON);
518 lockd_window_set_window_effect(lockw_data * data, int lock_app_pid, void *event)
520 Ecore_X_Event_Window_Create *e = event;
521 Ecore_X_Window user_window = 0;
524 user_window = get_user_created_window((Window) (e->win));
525 int ret = ecore_x_netwm_pid_get(user_window, &pid);
530 LOCKD_DBG("%s, %d", __func__, __LINE__);
532 LOCKD_DBG("PID(%d) window created. (lock_app_pid : %d)\n", pid,
535 if (lock_app_pid == pid) {
536 if (_lockd_window_check_validate_rect
537 (ecore_x_display_get(), user_window) == TRUE) {
539 ("This is lock application. Disable window effect. win id : %x\n",
542 utilx_set_window_effect_state(ecore_x_display_get(),
548 void lockd_window_set_phonelock_pid(lockw_data * data, int phone_lock_pid)
550 lockw_data *lockw = (lockw_data *) data;
555 LOCKD_DBG("%s, %d", __func__, __LINE__);
556 lockw->phone_lock_app_pid = phone_lock_pid;
557 LOCKD_DBG("%s, %d, lockw->phone_lock_app_pid = %d", __func__, __LINE__,
558 lockw->phone_lock_app_pid);
562 lockd_window_mgr_ready_lock(void *data, lockw_data * lockw,
563 Eina_Bool(*create_cb) (void *, int, void *),
564 Eina_Bool(*show_cb) (void *, int, void *))
567 LOCKD_ERR("lockw is NULL.");
570 /* Register window create CB */
572 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, create_cb,
575 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, show_cb, data);
577 lockw->volume_key_cnt = 0;
579 /* Register keydown event handler */
581 ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
582 _lockd_window_key_down_cb, lockw);
585 void lockd_window_mgr_finish_lock(lockw_data * lockw)
590 LOCKD_ERR("lockw is NULL.");
593 /* delete window create event handler */
594 if (lockw->h_wincreate != NULL) {
595 ecore_event_handler_del(lockw->h_wincreate);
596 lockw->h_wincreate = NULL;
598 if (lockw->h_winshow != NULL) {
599 ecore_event_handler_del(lockw->h_winshow);
600 lockw->h_winshow = NULL;
603 ecore_x_pointer_ungrab();
605 /* delete keydown event handler */
606 if (lockw->h_keydown != NULL) {
607 ecore_event_handler_del(lockw->h_keydown);
608 lockw->h_keydown = NULL;
612 lockw_data *lockd_window_init(void)
614 lockw_data *lockw = NULL;
617 /* Create lockd window data */
618 lockw = (lockw_data *) malloc(sizeof(lockw_data));
619 memset(lockw, 0x0, sizeof(lockw_data));
626 void lockd_create_ug_window(void *data)
628 lockw_data *lockw = NULL;
629 LOCKD_DBG("%s, %d", __func__, __LINE__);
631 lockw = (lockw_data *) data;
636 lockd_destroy_ug_window(lockw);
638 /* create main window */
639 lockw->main_win = lockd_create_main_window(PACKAGE);
641 /* create main layout */
642 /* remove indicator in running time */
643 /* lockw->main_layout = lockd_create_main_layout(lockw->main_win); */
644 appcore_set_i18n(PACKAGE, NULL);
645 _lockd_ug_window_set_key_grab(lockw);
646 _lockd_ug_window_register_vconf_changed(lockw);
647 lockw->phone_lock_state = 1;
650 void lockd_destroy_ug_window(void *data)
652 lockw_data *lockw = NULL;
653 LOCKD_DBG("%s, %d", __func__, __LINE__);
655 lockw = (lockw_data *) data;
660 _lockd_ug_window_set_key_ungrab(lockw);
661 _lockd_ug_window_unregister_vconf_changed(lockw);
663 if (lockw->main_win) {
664 evas_object_del(lockw->main_win);
665 lockw->main_win = NULL;
667 lockw->phone_lock_state = 0;
670 void lockd_show_phonelock_alpha_ug(void *data)
672 lockw_data *lockw = NULL;
674 struct ug_cbs cbs = { 0, };
675 LOCKD_DBG("%s, %d", __func__, __LINE__);
677 lockw = (lockw_data *) data;
682 cbs.layout_cb = _lockd_phone_lock_alpha_ug_layout_cb;
683 cbs.result_cb = _lockd_phone_lock_alpha_ug_result_cb;
684 cbs.destroy_cb = _lockd_phone_lock_alpha_ug_destroy_cb;
685 cbs.priv = (void *)data;
687 service_create(&service);
689 service_add_extra_data(service, "phone-lock-type", "phone-lock");
690 service_add_extra_data(service, "window-type", "alpha");
692 elm_win_alpha_set(lockw->main_win, TRUE);
693 evas_object_color_set(lockw->main_win, 0, 0, 0, 0);
695 /* window effect : fade in /out */
696 ecore_x_icccm_name_class_set(elm_win_xwindow_get(lockw->main_win),
697 "LOCK_SCREEN", "LOCK_SCREEN");
699 UG_INIT_EFL(lockw->main_win, UG_OPT_INDICATOR_ENABLE);
700 ug_create(NULL, "phone-lock-efl", UG_MODE_FULLVIEW, service, &cbs);
701 LOCKD_DBG("%s, %d", __func__, __LINE__);
703 service_destroy(service);
705 LOCKD_DBG("%s, %d", __func__, __LINE__);
707 evas_object_show(lockw->main_win);
708 _lockd_ug_window_set_win_prop(lockw, ECORE_X_WINDOW_TYPE_NOTIFICATION);