2 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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.
17 #include <Elementary.h>
20 #include <ui-gadget.h>
23 #include <appcore-efl.h>
27 #include "window_mgr.h"
29 #include "lock_pwd_util.h"
31 #define STR_ATOM_PANEL_SCROLLABLE_STATE "_E_MOVE_PANEL_SCROLLABLE_STATE"
32 #define ROUND_DOUBLE(x) (round(x*10)/10)
37 Eina_Bool is_registered;
38 Ecore_X_Window lock_x_window;
40 Ecore_Event_Handler *h_wincreate;
41 Ecore_Event_Handler *h_winshow;
42 Ecore_Event_Handler *h_winhide;
47 static int _is_on_screen(Ecore_X_Display * dpy, Ecore_X_Window window)
58 unsigned int width = 0;
59 unsigned int height = 0;
60 unsigned int border = 0;
61 unsigned int depth = 0;
62 unsigned int root_w = 0;
63 unsigned int root_h = 0;
65 Eina_Bool ret = FALSE;
67 root = ecore_x_window_root_first_get();
68 XGetGeometry(dpy, root, &win, &rel_x, &rel_y, &root_w, &root_h, &border, &depth);
69 _D("root rel_x[%d] rel_y[%d] border[%d] width[%d] height[%d]", rel_x, rel_y, border, root_w, root_h);
71 if (XGetGeometry(dpy, window, &win, &rel_x, &rel_y, &width, &height, &border, &depth)) {
72 if (XTranslateCoordinates(dpy, window, root, 0, 0, &abs_x, &abs_y, &child)) {
73 _D("abs_x[%d] abs_y[%d] border[%d] width[%d] height[%d]", abs_x, abs_y, border, width, height);
74 if ((abs_x - border) >= root_w
75 || (abs_y - border) >= root_h
76 || (width + abs_x) <= 0 || (height + abs_y) <= 0)
80 ret = (width == root_w) && (height == root_h);
90 static Window _get_user_created_window(Window win)
93 int ret, size_ret = 0;
94 unsigned long num_ret = 0, bytes = 0;
95 unsigned char *prop_ret = NULL;
97 Atom prop_user_created_win;
99 prop_user_created_win = XInternAtom(ecore_x_display_get(), "_E_USER_CREATED_WINDOW", False);
101 ret = XGetWindowProperty(ecore_x_display_get()
102 , win, prop_user_created_win
105 , &type_ret, &size_ret
108 if (ret != Success) {
110 XFree((void *) prop_ret);
112 } else if (!prop_ret) {
116 memcpy(&xid, prop_ret, sizeof(unsigned int));
117 XFree((void *)prop_ret);
125 int window_mgr_get_focus_window_pid(void)
127 Ecore_X_Window x_win_focused = 0;
131 _D("%s, %d", __func__, __LINE__);
133 x_win_focused = ecore_x_window_focus_get();
134 ret = ecore_x_netwm_pid_get(x_win_focused, &pid);
136 _E("Can't get pid for focus x window (%x)\n", x_win_focused);
139 _D("PID(%d) for focus x window (%x)\n", pid, x_win_focused);
146 static void _pwd_transient_set(Ecore_X_Window win, Ecore_X_Window for_win)
148 _W("%p is transient for %p", win, for_win);
150 ecore_x_icccm_transient_for_set(win, for_win);
155 static void _pwd_transient_unset(Ecore_X_Window xwin)
159 _W("%p is not transient", xwin);
160 ecore_x_icccm_transient_for_unset(xwin);
165 Eina_Bool window_mgr_pwd_transient_set(void *data)
167 Evas_Object *pwd_win = NULL;
168 Ecore_X_Window pwd_x_win;
169 lockw_data *lockw = (lockw_data *) data;
170 retv_if(!lockw, EINA_FALSE);
172 pwd_win = lock_pwd_util_win_get();
173 retv_if(!pwd_win, EINA_FALSE);
175 pwd_x_win = elm_win_xwindow_get(pwd_win);
176 retv_if(!pwd_x_win, EINA_FALSE);
178 retv_if(!lockw->lock_x_window, EINA_FALSE);
180 /* unset transient */
181 _pwd_transient_unset(lockw->lock_x_window);
184 _pwd_transient_set(lockw->lock_x_window, pwd_x_win);
191 Eina_Bool window_mgr_set_prop(lockw_data * data, int lock_app_pid, void *event)
193 Ecore_X_Event_Window_Create *e = event;
194 Ecore_X_Window user_window = 0;
195 lockw_data *lockw = (lockw_data *) data;
199 retv_if(!lockw, EINA_FALSE);
201 user_window = _get_user_created_window((Window) (e->win));
203 ret = ecore_x_netwm_pid_get(user_window, &pid);
204 retv_if(ret != 1, EINA_FALSE);
206 _D("Check PID(%d) window. (lock_app_pid : %d)", pid, lock_app_pid);
208 if (lock_app_pid == pid) {
209 if (_is_on_screen(ecore_x_display_get(), user_window) == TRUE) {
210 lockw->lock_x_window = user_window;
211 /* window effect : fade in /out */
212 ecore_x_icccm_name_class_set(user_window, "LOCK_SCREEN", "LOCK_SCREEN");
213 ecore_x_netwm_window_type_set(user_window, ECORE_X_WINDOW_TYPE_NOTIFICATION);
214 utilx_set_system_notification_level(ecore_x_display_get(), user_window, UTILX_NOTIFICATION_LEVEL_NORMAL);
215 utilx_set_window_opaque_state(ecore_x_display_get(), user_window, UTILX_OPAQUE_STATE_ON);
218 if (!window_mgr_pwd_transient_set(lockw)) {
219 _E("Failed to set transient");
230 Eina_Bool window_mgr_set_effect(lockw_data * data, int lock_app_pid, void *event)
232 Ecore_X_Event_Window_Create *e = event;
233 Ecore_X_Window user_window = 0;
237 user_window = _get_user_created_window((Window) (e->win));
238 ret = ecore_x_netwm_pid_get(user_window, &pid);
239 retv_if(ret != 1, EINA_FALSE);
241 if (lock_app_pid == pid) {
242 if (_is_on_screen(ecore_x_display_get(), user_window) == TRUE) {
243 Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0;
244 unsigned int effect_state = 0;
246 ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
247 if (ATOM_WINDOW_EFFECT_ENABLE) {
248 ecore_x_window_prop_card32_set(user_window, ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
250 _E("ecore_x_atom_get() failed");
260 void window_mgr_set_scroll_prop(lockw_data *data, int lock_type)
262 lockw_data *lockw = (lockw_data *) data;
263 Ecore_X_Atom ATOM_PANEL_SCROLLABLE_STATE = 0;
264 unsigned int val[3] = { 0, };
268 ATOM_PANEL_SCROLLABLE_STATE = ecore_x_atom_get(STR_ATOM_PANEL_SCROLLABLE_STATE);
269 if (lock_type == SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD ||
270 lock_type == SETTING_SCREEN_LOCK_TYPE_PASSWORD) {
271 val[0] = 0; // always enable F
272 val[1] = 0; // quickpanel enable F
273 val[2] = 0; // apptray enable F
275 val[0] = 0; // always enable F
276 val[1] = 1; // quickpanel enable T
277 val[2] = 0; // apptray enable F
279 ecore_x_window_prop_card32_set(lockw->lock_x_window, ATOM_PANEL_SCROLLABLE_STATE, val, 3);
284 void window_mgr_register_event(void *data, lockw_data * lockw,
285 Eina_Bool (*create_cb) (void *, int, void *),
286 Eina_Bool (*show_cb) (void *, int, void *))
288 Ecore_X_Window root_window;
292 if (lockw->is_registered) {
293 _E("Already register event cb");
297 /* For getting window x event */
298 root_window = ecore_x_window_root_first_get();
299 ecore_x_window_client_sniff(root_window);
301 lockw->h_wincreate = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, create_cb, data);
302 lockw->h_winshow = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, show_cb, data);
304 lockw->is_registered = EINA_TRUE;
309 static inline void _unregister_event(lockw_data *lockw)
311 Ecore_X_Window root_window;
313 /* unset transient */
314 _pwd_transient_unset(lockw->lock_x_window);
316 /* delete getting window x event */
317 root_window = ecore_x_window_root_first_get();
318 ecore_x_window_client_sniff(root_window);
320 /* delete window create event handler */
321 if (lockw->h_wincreate) {
322 ecore_event_handler_del(lockw->h_wincreate);
323 lockw->h_wincreate = NULL;
325 if (lockw->h_winshow) {
326 ecore_event_handler_del(lockw->h_winshow);
327 lockw->h_winshow = NULL;
329 if (lockw->h_winhide) {
330 ecore_event_handler_del(lockw->h_winhide);
331 lockw->h_winhide = NULL;
334 ecore_x_pointer_ungrab();
336 lockw->is_registered = EINA_FALSE;
341 void window_mgr_unregister_event(lockw_data *lockw)
345 if (!lockw->is_registered) {
346 _E("event cb is not registered");
350 _unregister_event(lockw);
355 lockw_data *window_mgr_init(void)
357 lockw_data *lockw = NULL;
359 lockw = calloc(1, sizeof(*lockw));
366 void window_mgr_fini(lockw_data *lockw)
370 if (lockw->is_registered) {
371 _unregister_event(lockw);
379 static void _update_scale(void)
381 int target_width, target_height, target_width_mm, target_height_mm;
382 double target_inch, scale, profile_factor;
389 target_height_mm = 0;
390 profile_factor = 1.0;
393 ecore_x_randr_screen_current_size_get(ecore_x_window_root_first_get(), &target_width, &target_height, &target_width_mm, &target_height_mm);
394 target_inch = ROUND_DOUBLE(sqrt(target_width_mm * target_width_mm + target_height_mm * target_height_mm) / 25.4);
395 dpi = (int)(((sqrt(target_width * target_width + target_height * target_height) / target_inch) * 10 + 5) / 10);
397 profile = elm_config_profile_get();
398 _D("profile : %s", profile);
400 if (!strcmp(profile, "wearable")) {
401 profile_factor = 0.4;
402 } else if (!strcmp(profile, "mobile") ||
403 !strcmp(profile, "default")) {
404 if (target_inch <= 4.0) {
405 profile_factor = 0.7;
407 profile_factor = 0.8;
409 } else if (!strcmp(profile, "desktop")) {
410 profile_factor = 1.0;
413 scale = ROUND_DOUBLE(dpi / 90.0 * profile_factor);
414 _D("scale : %f", scale);
416 elm_config_scale_set(scale);
421 Evas_Object *window_mgr_pwd_lock_win_create(void)
423 Evas_Object *win = NULL;
425 /* Set scale value */
428 win = elm_win_add(NULL, "LOCKSCREEN_PWD", ELM_WIN_NOTIFICATION);
431 elm_win_alpha_set(win, EINA_TRUE);
432 elm_win_borderless_set(win, EINA_TRUE);
433 elm_win_autodel_set(win, EINA_TRUE);
434 elm_win_conformant_set(win, EINA_TRUE);
435 elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_SHOW);
437 efl_util_set_notification_window_level(win, EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM);
439 Ecore_X_Window xwin = elm_win_xwindow_get(win);
441 ecore_x_netwm_window_type_set(xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
442 utilx_set_window_opaque_state(ecore_x_display_get(), xwin, UTILX_OPAQUE_STATE_ON);
444 Ecore_X_Atom ATOM_PANEL_SCROLLABLE_STATE = ecore_x_atom_get(STR_ATOM_PANEL_SCROLLABLE_STATE);
445 unsigned int val[3] = { 0, };
447 ecore_x_window_prop_card32_set(xwin, ATOM_PANEL_SCROLLABLE_STATE, val, 3);