cdf5e74c7976d440400a68acb01ffa61aa2cdd09
[apps/home/starter.git] / lock-mgr / src / lockd-window-mgr.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
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
7  *
8  *  http://www.tizenopensource.org/license
9  *
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.
15  */
16
17 #include <Elementary.h>
18 #include <Ecore_X.h>
19 #include <utilX.h>
20 #include <vconf.h>
21 #include <bundle.h>
22 #include <appcore-efl.h>
23 #include <app.h>
24
25 #include "lockd-debug.h"
26 #include "lockd-window-mgr.h"
27
28 #define PACKAGE                 "starter"
29
30 struct _lockw_data {
31         Ecore_X_Window input_x_window;
32
33         Evas_Object *main_win;
34         Evas_Object *main_layout;
35
36         Ecore_X_Window lock_x_window;
37
38         Ecore_Event_Handler *h_keydown;
39         Ecore_Event_Handler *h_wincreate;
40         Ecore_Event_Handler *h_winshow;
41
42 };
43
44 static Eina_Bool _lockd_window_key_down_cb(void *data, int type, void *event)
45 {
46         LOCKD_DBG("Key Down CB.");
47
48         return ECORE_CALLBACK_PASS_ON;
49 }
50
51 static int
52 _lockd_window_check_validate_rect(Ecore_X_Display * dpy, Ecore_X_Window window)
53 {
54         Ecore_X_Window root;
55         Ecore_X_Window child;
56
57         int rel_x = 0;
58         int rel_y = 0;
59         int abs_x = 0;
60         int abs_y = 0;
61
62         unsigned int width = 0;
63         unsigned int height = 0;
64         unsigned int border = 0;
65         unsigned int depth = 0;
66
67         Eina_Bool ret = FALSE;
68
69         root = ecore_x_window_root_first_get();
70
71         if (XGetGeometry
72             (dpy, window, &root, &rel_x, &rel_y, &width, &height, &border,
73              &depth)) {
74                 if (XTranslateCoordinates
75                     (dpy, window, root, 0, 0, &abs_x, &abs_y, &child)) {
76                         if ((abs_x - border) >= 480 || (abs_y - border) >= 800
77                             || (width + abs_x) <= 0 || (height + abs_y) <= 0) {
78                                 ret = FALSE;
79                         } else {
80                                 ret = TRUE;
81                         }
82                 }
83         }
84
85         return ret;
86 }
87
88 static Window get_user_created_window(Window win)
89 {
90         Atom type_ret = 0;
91         int ret, size_ret = 0;
92         unsigned long num_ret = 0, bytes = 0;
93         unsigned char *prop_ret = NULL;
94         unsigned int xid;
95         Atom prop_user_created_win;
96
97         prop_user_created_win =
98             XInternAtom(ecore_x_display_get(), "_E_USER_CREATED_WINDOW", False);
99
100         ret =
101             XGetWindowProperty(ecore_x_display_get(), win,
102                                prop_user_created_win, 0L, 1L, False, 0,
103                                &type_ret, &size_ret, &num_ret, &bytes,
104                                &prop_ret);
105
106         if (ret != Success) {
107                 if (prop_ret)
108                         XFree((void *)prop_ret);
109                 return win;
110         } else if (!prop_ret) {
111                 return win;
112         }
113
114         memcpy(&xid, prop_ret, sizeof(unsigned int));
115         XFree((void *)prop_ret);
116
117         return xid;
118
119 }
120
121 void
122 lockd_window_set_window_property(lockw_data * data, int lock_app_pid,
123                                  void *event)
124 {
125         Ecore_X_Event_Window_Create *e = event;
126         Ecore_X_Window user_window = 0;
127         lockw_data *lockw = (lockw_data *) data;
128         int pid = 0;
129
130         if (!lockw) {
131                 return;
132         }
133         LOCKD_DBG("%s, %d", __func__, __LINE__);
134
135         user_window = get_user_created_window((Window) (e->win));
136
137         ecore_x_netwm_pid_get(user_window, &pid);
138
139         LOCKD_DBG("Check PID(%d) window. (lock_app_pid : %d)\n", pid,
140                   lock_app_pid);
141
142         if (lock_app_pid == pid) {
143                 if (_lockd_window_check_validate_rect
144                     (ecore_x_display_get(), user_window) == TRUE) {
145                         lockw->lock_x_window = user_window;
146                         LOCKD_DBG
147                             ("This is lock application. Set window property. win id : %x",
148                              user_window);
149
150                         ecore_x_icccm_name_class_set(user_window, "LOCK_SCREEN",
151                                                      "LOCK_SCREEN");
152
153                         ecore_x_netwm_window_type_set(user_window,
154                                                       ECORE_X_WINDOW_TYPE_NOTIFICATION);
155
156                         utilx_set_system_notification_level(ecore_x_display_get
157                                                             (), user_window,
158                                                             UTILX_NOTIFICATION_LEVEL_NORMAL);
159
160                         utilx_set_window_opaque_state(ecore_x_display_get(),
161                                                       user_window,
162                                                       UTILX_OPAQUE_STATE_ON);
163                 }
164         }
165 }
166
167 void
168 lockd_window_set_window_effect(lockw_data * data, int lock_app_pid, void *event)
169 {
170         Ecore_X_Event_Window_Create *e = event;
171         Ecore_X_Window user_window = 0;
172         int pid = 0;
173
174         user_window = get_user_created_window((Window) (e->win));
175         ecore_x_netwm_pid_get(user_window, &pid);
176
177         LOCKD_DBG("%s, %d", __func__, __LINE__);
178
179         LOCKD_DBG("PID(%d) window created. (lock_app_pid : %d)\n", pid,
180                   lock_app_pid);
181
182         if (lock_app_pid == pid) {
183                 if (_lockd_window_check_validate_rect
184                     (ecore_x_display_get(), user_window) == TRUE) {
185                         LOCKD_DBG
186                             ("This is lock application. Disable window effect. win id : %x\n",
187                              user_window);
188
189                         utilx_set_window_effect_state(ecore_x_display_get(),
190                                                       user_window, 0);
191                 }
192         }
193 }
194
195 void
196 lockd_window_mgr_ready_lock(void *data, lockw_data * lockw,
197                             Eina_Bool(*create_cb) (void *, int, void *),
198                             Eina_Bool(*show_cb) (void *, int, void *))
199 {
200         Ecore_X_Window xwin;
201
202         if (lockw == NULL) {
203                 LOCKD_ERR("lockw is NULL.");
204                 return;
205         }
206
207         lockw->h_wincreate =
208             ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, create_cb,
209                                     data);
210         lockw->h_winshow =
211             ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, show_cb, data);
212
213         xwin = lockw->input_x_window;
214         utilx_grab_key(ecore_x_display_get(), xwin, KEY_SELECT, EXCLUSIVE_GRAB);
215
216         lockw->h_keydown =
217             ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
218                                     _lockd_window_key_down_cb, NULL);
219 }
220
221 void lockd_window_mgr_finish_lock(lockw_data * lockw)
222 {
223         Ecore_X_Window xwin;
224
225         if (lockw == NULL) {
226                 LOCKD_ERR("lockw is NULL.");
227                 return;
228         }
229         if (lockw->h_wincreate != NULL) {
230                 ecore_event_handler_del(lockw->h_wincreate);
231                 lockw->h_wincreate = NULL;
232         }
233         if (lockw->h_winshow != NULL) {
234                 ecore_event_handler_del(lockw->h_winshow);
235                 lockw->h_winshow = NULL;
236         }
237
238         xwin = lockw->input_x_window;
239         utilx_ungrab_key(ecore_x_display_get(), xwin, KEY_SELECT);
240
241         if (lockw->h_keydown != NULL) {
242                 ecore_event_handler_del(lockw->h_keydown);
243                 lockw->h_keydown = NULL;
244         }
245 }
246
247 lockw_data *lockd_window_init(void)
248 {
249         lockw_data *lockw = NULL;
250         Ecore_X_Window input_x_window;
251         Ecore_X_Window root_window;
252         long pid;
253
254         lockw = (lockw_data *) malloc(sizeof(lockw_data));
255         memset(lockw, 0x0, sizeof(lockw_data));
256
257         pid = getpid();
258
259         input_x_window = ecore_x_window_input_new(0, 0, 0, 1, 1);
260         ecore_x_icccm_title_set(input_x_window, "lock-daemon-input-window");
261         ecore_x_netwm_name_set(input_x_window, "lock-daemon-input-window");
262         ecore_x_netwm_pid_set(input_x_window, pid);
263         LOCKD_DBG("Created input window : %p", input_x_window);
264         lockw->input_x_window = input_x_window;
265
266         root_window = ecore_x_window_root_first_get();
267         ecore_x_window_client_sniff(root_window);
268
269         return lockw;
270 }