upload tizen1.0 source
[apps/home/starter.git] / lock-mgr / src / lockd-window-mgr.c
1 /*
2  *  starter
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <Elementary.h>
23 #include <Ecore_X.h>
24 #include <utilX.h>
25 #include <vconf.h>
26 #include <bundle.h>
27 #include <appcore-efl.h>
28
29 #include "lockd-debug.h"
30 #include "lockd-window-mgr.h"
31
32 #define PACKAGE                 "starter"
33 #define VCONFKEY_PHONE_LOCK_VERIFICATION "memory/lockscreen/phone_lock_verification"
34
35 struct _lockw_data {
36         Ecore_X_Window input_x_window;
37
38         Evas_Object *main_win;
39         Evas_Object *main_layout;
40
41         Ecore_X_Window lock_x_window;
42
43         Ecore_Event_Handler *h_keydown;
44         Ecore_Event_Handler *h_wincreate;
45         Ecore_Event_Handler *h_winshow;
46
47         int phone_lock_state;
48         int phone_lock_app_pid;
49 };
50
51 static Eina_Bool _lockd_window_key_down_cb(void *data, int type, void *event)
52 {
53         LOCKD_DBG("Key Down CB.");
54         return ECORE_CALLBACK_PASS_ON;
55 }
56
57 static int
58 _lockd_window_check_validate_rect(Ecore_X_Display * dpy, Ecore_X_Window window)
59 {
60         Ecore_X_Window root;
61         Ecore_X_Window child;
62
63         int rel_x = 0;
64         int rel_y = 0;
65         int abs_x = 0;
66         int abs_y = 0;
67
68         unsigned int width = 0;
69         unsigned int height = 0;
70         unsigned int border = 0;
71         unsigned int depth = 0;
72
73         Eina_Bool ret = FALSE;
74
75         root = ecore_x_window_root_first_get();
76
77         if (XGetGeometry
78             (dpy, window, &root, &rel_x, &rel_y, &width, &height, &border,
79              &depth)) {
80                 if (XTranslateCoordinates
81                     (dpy, window, root, 0, 0, &abs_x, &abs_y, &child)) {
82                         if ((abs_x - border) >= 480 || (abs_y - border) >= 800
83                             || (width + abs_x) <= 0 || (height + abs_y) <= 0) {
84                                 ret = FALSE;
85                         } else {
86                                 ret = TRUE;
87                         }
88                 }
89         }
90         return ret;
91 }
92
93 static Window get_user_created_window(Window win)
94 {
95         Atom type_ret = 0;
96         int ret, size_ret = 0;
97         unsigned long num_ret = 0, bytes = 0;
98         unsigned char *prop_ret = NULL;
99         unsigned int xid;
100         Atom prop_user_created_win;
101
102         prop_user_created_win =
103             XInternAtom(ecore_x_display_get(), "_E_USER_CREATED_WINDOW", False);
104
105         ret =
106             XGetWindowProperty(ecore_x_display_get(), win,
107                                prop_user_created_win, 0L, 1L, False, 0,
108                                &type_ret, &size_ret, &num_ret, &bytes,
109                                &prop_ret);
110
111         if (ret != Success) {
112                 if (prop_ret)
113                         XFree((void *)prop_ret);
114                 return win;
115         } else if (!prop_ret) {
116                 return win;
117         }
118
119         memcpy(&xid, prop_ret, sizeof(unsigned int));
120         XFree((void *)prop_ret);
121
122         return xid;
123 }
124
125 void
126 lockd_window_set_window_property(lockw_data * data, int lock_app_pid,
127                                  void *event)
128 {
129         Ecore_X_Event_Window_Create *e = event;
130         Ecore_X_Window user_window = 0;
131         lockw_data *lockw = (lockw_data *) data;
132         int pid = 0;
133
134         if (!lockw) {
135                 return;
136         }
137         LOCKD_DBG("%s, %d", __func__, __LINE__);
138
139         user_window = get_user_created_window((Window) (e->win));
140
141         ecore_x_netwm_pid_get(user_window, &pid);
142
143         LOCKD_DBG("Check PID(%d) window. (lock_app_pid : %d)\n", pid,
144                   lock_app_pid);
145
146         if (lock_app_pid == pid) {
147                 if (_lockd_window_check_validate_rect
148                     (ecore_x_display_get(), user_window) == TRUE) {
149                         lockw->lock_x_window = user_window;
150                         LOCKD_DBG
151                             ("This is lock application. Set window property. win id : %x",
152                              user_window);
153
154                         ecore_x_icccm_name_class_set(user_window, "LOCK_SCREEN",
155                                                      "LOCK_SCREEN");
156
157                         ecore_x_netwm_window_type_set(user_window,
158                                                       ECORE_X_WINDOW_TYPE_NOTIFICATION);
159
160                         utilx_set_system_notification_level(ecore_x_display_get
161                                                             (), user_window,
162                                                             UTILX_NOTIFICATION_LEVEL_NORMAL);
163
164                         utilx_set_window_opaque_state(ecore_x_display_get(),
165                                                       user_window,
166                                                       UTILX_OPAQUE_STATE_ON);
167                 }
168         }
169 }
170
171 void
172 lockd_window_set_window_effect(lockw_data * data, int lock_app_pid, void *event)
173 {
174         Ecore_X_Event_Window_Create *e = event;
175         Ecore_X_Window user_window = 0;
176         int pid = 0;
177
178         user_window = get_user_created_window((Window) (e->win));
179         ecore_x_netwm_pid_get(user_window, &pid);
180
181         LOCKD_DBG("%s, %d", __func__, __LINE__);
182
183         LOCKD_DBG("PID(%d) window created. (lock_app_pid : %d)\n", pid,
184                   lock_app_pid);
185
186         if (lock_app_pid == pid) {
187                 if (_lockd_window_check_validate_rect
188                     (ecore_x_display_get(), user_window) == TRUE) {
189                         LOCKD_DBG
190                             ("This is lock application. Disable window effect. win id : %x\n",
191                              user_window);
192
193                         utilx_set_window_effect_state(ecore_x_display_get(),
194                                                       user_window, 0);
195                 }
196         }
197 }
198
199 void lockd_window_set_phonelock_pid(lockw_data * data, int phone_lock_pid)
200 {
201         lockw_data *lockw = (lockw_data *) data;
202
203         if (!lockw) {
204                 return;
205         }
206         LOCKD_DBG("%s, %d", __func__, __LINE__);
207         lockw->phone_lock_app_pid = phone_lock_pid;
208         LOCKD_DBG("%s, %d, lockw->phone_lock_app_pid = %d", __func__, __LINE__,
209                   lockw->phone_lock_app_pid);
210 }
211
212 void
213 lockd_window_mgr_ready_lock(void *data, lockw_data * lockw,
214                             Eina_Bool(*create_cb) (void *, int, void *),
215                             Eina_Bool(*show_cb) (void *, int, void *))
216 {
217         Ecore_X_Window xwin;
218
219         if (lockw == NULL) {
220                 LOCKD_ERR("lockw is NULL.");
221                 return;
222         }
223
224         lockw->h_wincreate =
225             ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, create_cb,
226                                     data);
227         lockw->h_winshow =
228             ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, show_cb, data);
229
230         xwin = lockw->input_x_window;
231         utilx_grab_key(ecore_x_display_get(), xwin, KEY_SELECT, EXCLUSIVE_GRAB);
232
233         lockw->h_keydown =
234             ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
235                                     _lockd_window_key_down_cb, NULL);
236 }
237
238 void lockd_window_mgr_finish_lock(lockw_data * lockw)
239 {
240         Ecore_X_Window xwin;
241
242         if (lockw == NULL) {
243                 LOCKD_ERR("lockw is NULL.");
244                 return;
245         }
246         if (lockw->h_wincreate != NULL) {
247                 ecore_event_handler_del(lockw->h_wincreate);
248                 lockw->h_wincreate = NULL;
249         }
250         if (lockw->h_winshow != NULL) {
251                 ecore_event_handler_del(lockw->h_winshow);
252                 lockw->h_winshow = NULL;
253         }
254
255         xwin = lockw->input_x_window;
256         utilx_ungrab_key(ecore_x_display_get(), xwin, KEY_SELECT);
257
258         if (lockw->h_keydown != NULL) {
259                 ecore_event_handler_del(lockw->h_keydown);
260                 lockw->h_keydown = NULL;
261         }
262 }
263
264 lockw_data *lockd_window_init(void)
265 {
266         lockw_data *lockw = NULL;
267         Ecore_X_Window input_x_window;
268         Ecore_X_Window root_window;
269         long pid;
270
271         lockw = (lockw_data *) malloc(sizeof(lockw_data));
272         memset(lockw, 0x0, sizeof(lockw_data));
273
274         pid = getpid();
275         input_x_window = ecore_x_window_input_new(0, 0, 0, 1, 1);
276         ecore_x_icccm_title_set(input_x_window, "lock-daemon-input-window");
277         ecore_x_netwm_name_set(input_x_window, "lock-daemon-input-window");
278         ecore_x_netwm_pid_set(input_x_window, pid);
279         LOCKD_DBG("Created input window : %p", input_x_window);
280         lockw->input_x_window = input_x_window;
281
282         root_window = ecore_x_window_root_first_get();
283         ecore_x_window_client_sniff(root_window);
284
285         return lockw;
286 }
287