diff options
Diffstat (limited to 'mobile/src/xmonitor.c')
-rw-r--r-- | mobile/src/xmonitor.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/mobile/src/xmonitor.c b/mobile/src/xmonitor.c new file mode 100644 index 0000000..4c87285 --- /dev/null +++ b/mobile/src/xmonitor.c @@ -0,0 +1,296 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * 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 <ail.h> +#include <aul.h> +#include <dlog.h> +#include <Ecore.h> +#include <Ecore_X.h> +#include <Evas.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <sys/shm.h> +#include <vconf.h> + +#include "menu_daemon.h" +#include "util.h" +#include "starter-util.h" +#include "xmonitor.h" + + + +static struct info { + Ecore_Event_Handler *create_handler; + Ecore_Event_Handler *destroy_handler; + Ecore_Event_Handler *focus_in_handler; + Ecore_Event_Handler *focus_out_handler; + int is_top; +} xmonitor_info = { + .create_handler = NULL, + .destroy_handler = NULL, + .focus_in_handler = NULL, + .focus_out_handler = NULL, + .is_top = VCONFKEY_IDLE_SCREEN_TOP_FALSE, +}; + + + +int errno; + + + +static inline int _get_pid(Ecore_X_Window win) +{ + int pid; + Ecore_X_Atom atom; + unsigned char *in_pid = NULL; + int num; + + atom = ecore_x_atom_get("X_CLIENT_PID"); + if (ecore_x_window_prop_property_get(win, atom, ECORE_X_ATOM_CARDINAL, + sizeof(int), &in_pid, &num) == EINA_FALSE) { + if(in_pid != NULL) { + free(in_pid); + in_pid = NULL; + } + if (ecore_x_netwm_pid_get(win, &pid) == EINA_FALSE) { + _E("Failed to get PID from a window 0x%X", win); + return -EINVAL; + } + } else { + pid = *(int *)in_pid; + free(in_pid); + } + + return pid; +} + + + +bool _set_idlescreen_top(void) +{ + Ecore_X_Window win; + + int is_top; + int ret; + int focused_pid; + + win = ecore_x_window_focus_get(); + focused_pid = _get_pid(win); + retv_if(focused_pid <= 0, false); + + is_top = menu_daemon_is_homescreen(focused_pid)? + VCONFKEY_IDLE_SCREEN_TOP_TRUE : VCONFKEY_IDLE_SCREEN_TOP_FALSE; + + if (is_top != xmonitor_info.is_top) { + ret = vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, is_top); + retv_if(0 != ret, false); + xmonitor_info.is_top = is_top; + _D("set the key of idlescreen_is_top as %d", is_top); + } + + return true; +} + + + +static Eina_Bool _create_cb(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Create *info = event; + + _D("Create a window[%x]", info->win); + + ecore_x_window_client_sniff(info->win); + + return ECORE_CALLBACK_PASS_ON; +} + + + +static Eina_Bool _destroy_cb(void *data, int type, void *event) +{ + return ECORE_CALLBACK_PASS_ON; +} + + + +static Eina_Bool _focus_in_cb(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Focus_In *info = event; + + _D("Focus in a window[%x]", info->win); + + retv_if(false == _set_idlescreen_top(), ECORE_CALLBACK_PASS_ON); + + return ECORE_CALLBACK_PASS_ON; +} + + + +static Eina_Bool _focus_out_cb(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Focus_Out *info = event; + + _D("Focus out a window[%x]", info->win); + + return ECORE_CALLBACK_PASS_ON; +} + + + +static inline void _sniff_all_windows(void) +{ + Ecore_X_Window root; + Ecore_X_Window ret; + struct stack_item *new_item; + struct stack_item *item; + Eina_List *win_stack = NULL; + struct stack_item { + Ecore_X_Window *wins; + int nr_of_wins; + int i; + }; + + root = ecore_x_window_root_first_get(); + ecore_x_window_sniff(root); + + new_item = malloc(sizeof(*new_item)); + if (!new_item) { + _E("Error(%s)\n", strerror(errno)); + return; + } + + new_item->nr_of_wins = 0; + new_item->wins = + ecore_x_window_children_get(root, &new_item->nr_of_wins); + new_item->i = 0; + + if (new_item->wins) + win_stack = eina_list_append(win_stack, new_item); + else + free(new_item); + + while ((item = eina_list_nth(win_stack, 0))) { + win_stack = eina_list_remove(win_stack, item); + + if (!item->wins) { + free(item); + continue; + } + + while (item->i < item->nr_of_wins) { + ret = item->wins[item->i]; + + ecore_x_window_client_sniff(ret); + + new_item = malloc(sizeof(*new_item)); + if (!new_item) { + _E("Error %s\n", strerror(errno)); + item->i++; + continue; + } + + new_item->i = 0; + new_item->nr_of_wins = 0; + new_item->wins = + ecore_x_window_children_get(ret, + &new_item->nr_of_wins); + if (new_item->wins) { + win_stack = + eina_list_append(win_stack, new_item); + } else { + free(new_item); + } + + item->i++; + } + + free(item->wins); + free(item); + } + + return; +} + + + +int xmonitor_init(void) +{ + if (ecore_x_composite_query() == EINA_FALSE) + _D("====> COMPOSITOR IS NOT ENABLED"); + + xmonitor_info.create_handler = + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, _create_cb, NULL); + goto_if(NULL == xmonitor_info.create_handler, Error); + + xmonitor_info.destroy_handler = + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _destroy_cb, NULL); + goto_if(NULL == xmonitor_info.destroy_handler, Error); + + xmonitor_info.focus_in_handler = + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _focus_in_cb, NULL); + goto_if(NULL == xmonitor_info.focus_in_handler, Error); + + xmonitor_info.focus_out_handler = + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _focus_out_cb, NULL); + goto_if(NULL == xmonitor_info.focus_out_handler, Error); + + _sniff_all_windows(); + if (false == _set_idlescreen_top()) _E("cannot set idlescreen_is_top"); + + return 0; + +Error: + if (xmonitor_info.create_handler) { + ecore_event_handler_del(xmonitor_info.create_handler); + xmonitor_info.create_handler = NULL; + } else return -EFAULT; + + if (xmonitor_info.destroy_handler) { + ecore_event_handler_del(xmonitor_info.destroy_handler); + xmonitor_info.destroy_handler = NULL; + } else return -EFAULT; + + if (xmonitor_info.focus_in_handler) { + ecore_event_handler_del(xmonitor_info.focus_in_handler); + xmonitor_info.focus_in_handler = NULL; + } else return -EFAULT; + + if (xmonitor_info.focus_out_handler) { + ecore_event_handler_del(xmonitor_info.focus_out_handler); + xmonitor_info.focus_out_handler = NULL; + } else return -EFAULT; + + return -EFAULT; +} + +void xmonitor_fini(void) +{ + ecore_event_handler_del(xmonitor_info.create_handler); + xmonitor_info.create_handler = NULL; + + ecore_event_handler_del(xmonitor_info.destroy_handler); + xmonitor_info.destroy_handler = NULL; + + ecore_event_handler_del(xmonitor_info.focus_in_handler); + xmonitor_info.focus_in_handler = NULL; + + ecore_event_handler_del(xmonitor_info.focus_out_handler); + xmonitor_info.focus_out_handler = NULL; +} |