summaryrefslogtreecommitdiff
path: root/src/mobile/window_mgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mobile/window_mgr.c')
-rw-r--r--src/mobile/window_mgr.c451
1 files changed, 451 insertions, 0 deletions
diff --git a/src/mobile/window_mgr.c b/src/mobile/window_mgr.c
new file mode 100644
index 0000000..7822e96
--- /dev/null
+++ b/src/mobile/window_mgr.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <utilX.h>
+#include <ui-gadget.h>
+#include <vconf.h>
+#include <bundle.h>
+#include <appcore-efl.h>
+#include <app.h>
+#include <efl_util.h>
+
+#include "window_mgr.h"
+#include "util.h"
+#include "lock_pwd_util.h"
+
+#define STR_ATOM_PANEL_SCROLLABLE_STATE "_E_MOVE_PANEL_SCROLLABLE_STATE"
+#define ROUND_DOUBLE(x) (round(x*10)/10)
+
+
+
+struct _lockw_data {
+ Eina_Bool is_registered;
+ Ecore_X_Window lock_x_window;
+
+ Ecore_Event_Handler *h_wincreate;
+ Ecore_Event_Handler *h_winshow;
+ Ecore_Event_Handler *h_winhide;
+};
+
+
+
+static int _is_on_screen(Ecore_X_Display * dpy, Ecore_X_Window window)
+{
+ Ecore_X_Window root;
+ Window child;
+ Window win;
+
+ int rel_x = 0;
+ int rel_y = 0;
+ int abs_x = 0;
+ int abs_y = 0;
+
+ unsigned int width = 0;
+ unsigned int height = 0;
+ unsigned int border = 0;
+ unsigned int depth = 0;
+ unsigned int root_w = 0;
+ unsigned int root_h = 0;
+
+ Eina_Bool ret = FALSE;
+
+ root = ecore_x_window_root_first_get();
+ XGetGeometry(dpy, root, &win, &rel_x, &rel_y, &root_w, &root_h, &border, &depth);
+ _D("root rel_x[%d] rel_y[%d] border[%d] width[%d] height[%d]", rel_x, rel_y, border, root_w, root_h);
+
+ if (XGetGeometry(dpy, window, &win, &rel_x, &rel_y, &width, &height, &border, &depth)) {
+ if (XTranslateCoordinates(dpy, window, root, 0, 0, &abs_x, &abs_y, &child)) {
+ _D("abs_x[%d] abs_y[%d] border[%d] width[%d] height[%d]", abs_x, abs_y, border, width, height);
+ if ((abs_x - border) >= root_w
+ || (abs_y - border) >= root_h
+ || (width + abs_x) <= 0 || (height + abs_y) <= 0)
+ {
+ ret = FALSE;
+ } else {
+ ret = (width == root_w) && (height == root_h);
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+static Window _get_user_created_window(Window win)
+{
+ Atom type_ret = 0;
+ int ret, size_ret = 0;
+ unsigned long num_ret = 0, bytes = 0;
+ unsigned char *prop_ret = NULL;
+ unsigned int xid;
+ Atom prop_user_created_win;
+
+ prop_user_created_win = XInternAtom(ecore_x_display_get(), "_E_USER_CREATED_WINDOW", False);
+
+ ret = XGetWindowProperty(ecore_x_display_get()
+ , win, prop_user_created_win
+ , 0L, 1L
+ , False, 0
+ , &type_ret, &size_ret
+ , &num_ret, &bytes
+ , &prop_ret);
+ if (ret != Success) {
+ if (prop_ret)
+ XFree((void *) prop_ret);
+ return win;
+ } else if (!prop_ret) {
+ return win;
+ }
+
+ memcpy(&xid, prop_ret, sizeof(unsigned int));
+ XFree((void *)prop_ret);
+
+ return xid;
+
+}
+
+
+
+int window_mgr_get_focus_window_pid(void)
+{
+ Ecore_X_Window x_win_focused = 0;
+ int pid = 0;
+ int ret = -1;
+
+ _D("%s, %d", __func__, __LINE__);
+
+ x_win_focused = ecore_x_window_focus_get();
+ ret = ecore_x_netwm_pid_get(x_win_focused, &pid);
+ if(ret != 1) {
+ _E("Can't get pid for focus x window (%x)\n", x_win_focused);
+ return -1;
+ }
+ _D("PID(%d) for focus x window (%x)\n", pid, x_win_focused);
+
+ return pid;
+}
+
+
+
+static void _pwd_transient_set(Ecore_X_Window win, Ecore_X_Window for_win)
+{
+ _W("%p is transient for %p", win, for_win);
+
+ ecore_x_icccm_transient_for_set(win, for_win);
+}
+
+
+
+static void _pwd_transient_unset(Ecore_X_Window xwin)
+{
+ ret_if(!xwin);
+
+ _W("%p is not transient", xwin);
+ ecore_x_icccm_transient_for_unset(xwin);
+}
+
+
+
+Eina_Bool window_mgr_pwd_transient_set(void *data)
+{
+ Evas_Object *pwd_win = NULL;
+ Ecore_X_Window pwd_x_win;
+ lockw_data *lockw = (lockw_data *) data;
+ retv_if(!lockw, EINA_FALSE);
+
+ pwd_win = lock_pwd_util_win_get();
+ retv_if(!pwd_win, EINA_FALSE);
+
+ pwd_x_win = elm_win_xwindow_get(pwd_win);
+ retv_if(!pwd_x_win, EINA_FALSE);
+
+ retv_if(!lockw->lock_x_window, EINA_FALSE);
+
+ /* unset transient */
+ _pwd_transient_unset(lockw->lock_x_window);
+
+ /* set transient */
+ _pwd_transient_set(lockw->lock_x_window, pwd_x_win);
+
+ return EINA_TRUE;
+}
+
+
+
+Eina_Bool window_mgr_set_prop(lockw_data * data, int lock_app_pid, void *event)
+{
+ Ecore_X_Event_Window_Create *e = event;
+ Ecore_X_Window user_window = 0;
+ lockw_data *lockw = (lockw_data *) data;
+ int pid = 0;
+ int ret = 0;
+
+ retv_if(!lockw, EINA_FALSE);
+
+ user_window = _get_user_created_window((Window) (e->win));
+
+ ret = ecore_x_netwm_pid_get(user_window, &pid);
+ retv_if(ret != 1, EINA_FALSE);
+
+ _D("Check PID(%d) window. (lock_app_pid : %d)", pid, lock_app_pid);
+
+ if (lock_app_pid == pid) {
+ if (_is_on_screen(ecore_x_display_get(), user_window) == TRUE) {
+ lockw->lock_x_window = user_window;
+ /* window effect : fade in /out */
+ ecore_x_icccm_name_class_set(user_window, "LOCK_SCREEN", "LOCK_SCREEN");
+ ecore_x_netwm_window_type_set(user_window, ECORE_X_WINDOW_TYPE_NOTIFICATION);
+ utilx_set_system_notification_level(ecore_x_display_get(), user_window, UTILX_NOTIFICATION_LEVEL_NORMAL);
+ utilx_set_window_opaque_state(ecore_x_display_get(), user_window, UTILX_OPAQUE_STATE_ON);
+
+ /* set transient */
+ if (!window_mgr_pwd_transient_set(lockw)) {
+ _E("Failed to set transient");
+ }
+
+ return EINA_TRUE;
+ }
+ }
+ return EINA_FALSE;
+}
+
+
+
+Eina_Bool window_mgr_set_effect(lockw_data * data, int lock_app_pid, void *event)
+{
+ Ecore_X_Event_Window_Create *e = event;
+ Ecore_X_Window user_window = 0;
+ int pid = 0;
+ int ret = 0;
+
+ user_window = _get_user_created_window((Window) (e->win));
+ ret = ecore_x_netwm_pid_get(user_window, &pid);
+ retv_if(ret != 1, EINA_FALSE);
+
+ if (lock_app_pid == pid) {
+ if (_is_on_screen(ecore_x_display_get(), user_window) == TRUE) {
+ Ecore_X_Atom ATOM_WINDOW_EFFECT_ENABLE = 0;
+ unsigned int effect_state = 0;
+
+ ATOM_WINDOW_EFFECT_ENABLE = ecore_x_atom_get("_NET_CM_WINDOW_EFFECT_ENABLE");
+ if (ATOM_WINDOW_EFFECT_ENABLE) {
+ ecore_x_window_prop_card32_set(user_window, ATOM_WINDOW_EFFECT_ENABLE, &effect_state, 1);
+ } else {
+ _E("ecore_x_atom_get() failed");
+ }
+ return EINA_TRUE;
+ }
+ }
+ return EINA_FALSE;
+}
+
+
+
+void window_mgr_set_scroll_prop(lockw_data *data, int lock_type)
+{
+ lockw_data *lockw = (lockw_data *) data;
+ Ecore_X_Atom ATOM_PANEL_SCROLLABLE_STATE = 0;
+ unsigned int val[3] = { 0, };
+
+ ret_if(!lockw);
+
+ ATOM_PANEL_SCROLLABLE_STATE = ecore_x_atom_get(STR_ATOM_PANEL_SCROLLABLE_STATE);
+ if (lock_type == SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD ||
+ lock_type == SETTING_SCREEN_LOCK_TYPE_PASSWORD) {
+ val[0] = 0; // always enable F
+ val[1] = 0; // quickpanel enable F
+ val[2] = 0; // apptray enable F
+ } else {
+ val[0] = 0; // always enable F
+ val[1] = 1; // quickpanel enable T
+ val[2] = 0; // apptray enable F
+ }
+ ecore_x_window_prop_card32_set(lockw->lock_x_window, ATOM_PANEL_SCROLLABLE_STATE, val, 3);
+}
+
+
+
+void window_mgr_register_event(void *data, lockw_data * lockw,
+ Eina_Bool (*create_cb) (void *, int, void *),
+ Eina_Bool (*show_cb) (void *, int, void *))
+{
+ Ecore_X_Window root_window;
+
+ ret_if(!lockw);
+
+ if (lockw->is_registered) {
+ _E("Already register event cb");
+ return;
+ }
+
+ /* For getting window x event */
+ root_window = ecore_x_window_root_first_get();
+ ecore_x_window_client_sniff(root_window);
+
+ lockw->h_wincreate = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, create_cb, data);
+ lockw->h_winshow = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, show_cb, data);
+
+ lockw->is_registered = EINA_TRUE;
+}
+
+
+
+static inline void _unregister_event(lockw_data *lockw)
+{
+ Ecore_X_Window root_window;
+
+ /* unset transient */
+ _pwd_transient_unset(lockw->lock_x_window);
+
+ /* delete getting window x event */
+ root_window = ecore_x_window_root_first_get();
+ ecore_x_window_client_sniff(root_window);
+
+ /* delete window create event handler */
+ if (lockw->h_wincreate) {
+ ecore_event_handler_del(lockw->h_wincreate);
+ lockw->h_wincreate = NULL;
+ }
+ if (lockw->h_winshow) {
+ ecore_event_handler_del(lockw->h_winshow);
+ lockw->h_winshow = NULL;
+ }
+ if (lockw->h_winhide) {
+ ecore_event_handler_del(lockw->h_winhide);
+ lockw->h_winhide = NULL;
+ }
+
+ ecore_x_pointer_ungrab();
+
+ lockw->is_registered = EINA_FALSE;
+}
+
+
+
+void window_mgr_unregister_event(lockw_data *lockw)
+{
+ ret_if(!lockw);
+
+ if (!lockw->is_registered) {
+ _E("event cb is not registered");
+ return;
+ }
+
+ _unregister_event(lockw);
+}
+
+
+
+lockw_data *window_mgr_init(void)
+{
+ lockw_data *lockw = NULL;
+
+ lockw = calloc(1, sizeof(*lockw));
+
+ return lockw;
+}
+
+
+
+void window_mgr_fini(lockw_data *lockw)
+{
+ ret_if(!lockw);
+
+ if (lockw->is_registered) {
+ _unregister_event(lockw);
+ }
+
+ free(lockw);
+}
+
+
+
+static void _update_scale(void)
+{
+ int target_width, target_height, target_width_mm, target_height_mm;
+ double target_inch, scale, profile_factor;
+ int dpi;
+ char *profile;
+
+ target_width = 0;
+ target_height = 0;
+ target_width_mm = 0;
+ target_height_mm = 0;
+ profile_factor = 1.0;
+ scale = 1.0;
+
+ ecore_x_randr_screen_current_size_get(ecore_x_window_root_first_get(), &target_width, &target_height, &target_width_mm, &target_height_mm);
+ target_inch = ROUND_DOUBLE(sqrt(target_width_mm * target_width_mm + target_height_mm * target_height_mm) / 25.4);
+ dpi = (int)(((sqrt(target_width * target_width + target_height * target_height) / target_inch) * 10 + 5) / 10);
+
+ profile = elm_config_profile_get();
+ _D("profile : %s", profile);
+
+ if (!strcmp(profile, "wearable")) {
+ profile_factor = 0.4;
+ } else if (!strcmp(profile, "mobile") ||
+ !strcmp(profile, "default")) {
+ if (target_inch <= 4.0) {
+ profile_factor = 0.7;
+ } else {
+ profile_factor = 0.8;
+ }
+ } else if (!strcmp(profile, "desktop")) {
+ profile_factor = 1.0;
+ }
+
+ scale = ROUND_DOUBLE(dpi / 90.0 * profile_factor);
+ _D("scale : %f", scale);
+
+ elm_config_scale_set(scale);
+}
+
+
+
+Evas_Object *window_mgr_pwd_lock_win_create(void)
+{
+ Evas_Object *win = NULL;
+
+ /* Set scale value */
+ _update_scale();
+
+ win = elm_win_add(NULL, "LOCKSCREEN_PWD", ELM_WIN_NOTIFICATION);
+ retv_if(!win, NULL);
+
+ elm_win_alpha_set(win, EINA_TRUE);
+ elm_win_borderless_set(win, EINA_TRUE);
+ elm_win_autodel_set(win, EINA_TRUE);
+ elm_win_conformant_set(win, EINA_TRUE);
+ elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_SHOW);
+
+ efl_util_set_notification_window_level(win, EFL_UTIL_NOTIFICATION_LEVEL_MEDIUM);
+
+ Ecore_X_Window xwin = elm_win_xwindow_get(win);
+ if (xwin) {
+ ecore_x_netwm_window_type_set(xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION);
+ utilx_set_window_opaque_state(ecore_x_display_get(), xwin, UTILX_OPAQUE_STATE_ON);
+
+ Ecore_X_Atom ATOM_PANEL_SCROLLABLE_STATE = ecore_x_atom_get(STR_ATOM_PANEL_SCROLLABLE_STATE);
+ unsigned int val[3] = { 0, };
+
+ ecore_x_window_prop_card32_set(xwin, ATOM_PANEL_SCROLLABLE_STATE, val, 3);
+ }
+
+ return win;
+}