Apply smack rule.
[apps/native/starter.git] / src / xmonitor.c
1  /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.1 (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://floralicense.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
18
19 #include <ail.h>
20 #include <aul.h>
21 #include <dlog.h>
22 #include <Ecore.h>
23 #include <Ecore_X.h>
24 #include <Evas.h>
25 #include <errno.h>
26 #include <stdbool.h>
27 #include <stdio.h>
28 #include <sys/shm.h>
29 #include <vconf.h>
30
31 #include "menu_daemon.h"
32 #include "util.h"
33 #include "starter-util.h"
34 #include "xmonitor.h"
35
36
37
38 static struct info {
39         Ecore_Event_Handler *create_handler;
40         Ecore_Event_Handler *destroy_handler;
41         Ecore_Event_Handler *focus_in_handler;
42         Ecore_Event_Handler *focus_out_handler;
43         int is_top;
44 } xmonitor_info = {
45         .create_handler = NULL,
46         .destroy_handler = NULL,
47         .focus_in_handler = NULL,
48         .focus_out_handler = NULL,
49         .is_top = VCONFKEY_IDLE_SCREEN_TOP_FALSE,
50 };
51
52
53
54 int errno;
55
56
57
58 static inline int _get_pid(Ecore_X_Window win)
59 {
60         int pid;
61         Ecore_X_Atom atom;
62         unsigned char *in_pid = NULL;
63         int num;
64
65         atom = ecore_x_atom_get("X_CLIENT_PID");
66         if (ecore_x_window_prop_property_get(win, atom, ECORE_X_ATOM_CARDINAL,
67                                 sizeof(int), &in_pid, &num) == EINA_FALSE) {
68                 if(in_pid != NULL) {
69                         free(in_pid);
70                         in_pid = NULL;
71                 }
72                 if (ecore_x_netwm_pid_get(win, &pid) == EINA_FALSE) {
73                         _E("Failed to get PID from a window 0x%X", win);
74                         return -EINVAL;
75                 }
76         } else {
77                 pid = *(int *)in_pid;
78                 free(in_pid);
79         }
80
81         return pid;
82 }
83
84
85
86 bool _set_idlescreen_top(void)
87 {
88         Ecore_X_Window win;
89
90         int is_top;
91         int ret;
92         int focused_pid;
93
94         win = ecore_x_window_focus_get();
95         focused_pid = _get_pid(win);
96         retv_if(focused_pid <= 0, false);
97
98         is_top = menu_daemon_is_homescreen(focused_pid)?
99                         VCONFKEY_IDLE_SCREEN_TOP_TRUE : VCONFKEY_IDLE_SCREEN_TOP_FALSE;
100
101         if (is_top != xmonitor_info.is_top) {
102                 ret = vconf_set_int(VCONFKEY_IDLE_SCREEN_TOP, is_top);
103                 retv_if(0 != ret, false);
104                 xmonitor_info.is_top = is_top;
105                 _D("set the key of idlescreen_is_top as %d", is_top);
106         }
107
108         return true;
109 }
110
111
112
113 static Eina_Bool _create_cb(void *data, int type, void *event)
114 {
115         Ecore_X_Event_Window_Create *info = event;
116
117         _D("Create a window[%x]", info->win);
118
119         ecore_x_window_client_sniff(info->win);
120
121         return ECORE_CALLBACK_PASS_ON;
122 }
123
124
125
126 static Eina_Bool _destroy_cb(void *data, int type, void *event)
127 {
128         return ECORE_CALLBACK_PASS_ON;
129 }
130
131
132
133 static Eina_Bool _focus_in_cb(void *data, int type, void *event)
134 {
135         Ecore_X_Event_Window_Focus_In *info = event;
136
137         _D("Focus in a window[%x]", info->win);
138
139         retv_if(false == _set_idlescreen_top(), ECORE_CALLBACK_PASS_ON);
140
141         return ECORE_CALLBACK_PASS_ON;
142 }
143
144
145
146 static Eina_Bool _focus_out_cb(void *data, int type, void *event)
147 {
148         Ecore_X_Event_Window_Focus_Out *info = event;
149
150         _D("Focus out a window[%x]", info->win);
151
152         return ECORE_CALLBACK_PASS_ON;
153 }
154
155
156
157 static inline void _sniff_all_windows(void)
158 {
159         Ecore_X_Window root;
160         Ecore_X_Window ret;
161         struct stack_item *new_item;
162         struct stack_item *item;
163         Eina_List *win_stack = NULL;
164         struct stack_item {
165                 Ecore_X_Window *wins;
166                 int nr_of_wins;
167                 int i;
168         };
169
170         root = ecore_x_window_root_first_get();
171         ecore_x_window_sniff(root);
172
173         new_item = malloc(sizeof(*new_item));
174         if (!new_item) {
175                 _E("Error(%s)\n", strerror(errno));
176                 return;
177         }
178
179         new_item->nr_of_wins = 0;
180         new_item->wins =
181                 ecore_x_window_children_get(root, &new_item->nr_of_wins);
182         new_item->i = 0;
183
184         if (new_item->wins)
185                 win_stack = eina_list_append(win_stack, new_item);
186         else
187                 free(new_item);
188
189         while ((item = eina_list_nth(win_stack, 0))) {
190                 win_stack = eina_list_remove(win_stack, item);
191
192                 if (!item->wins) {
193                         free(item);
194                         continue;
195                 }
196
197                 while (item->i < item->nr_of_wins) {
198                         ret = item->wins[item->i];
199
200                         ecore_x_window_client_sniff(ret);
201
202                         new_item = malloc(sizeof(*new_item));
203                         if (!new_item) {
204                                 _E("Error %s\n", strerror(errno));
205                                 item->i++;
206                                 continue;
207                         }
208
209                         new_item->i = 0;
210                         new_item->nr_of_wins = 0;
211                         new_item->wins =
212                                 ecore_x_window_children_get(ret,
213                                                         &new_item->nr_of_wins);
214                         if (new_item->wins) {
215                                 win_stack =
216                                         eina_list_append(win_stack, new_item);
217                         } else {
218                                 free(new_item);
219                         }
220
221                         item->i++;
222                 }
223
224                 free(item->wins);
225                 free(item);
226         }
227
228         return;
229 }
230
231
232
233 int xmonitor_init(void)
234 {
235         if (ecore_x_composite_query() == EINA_FALSE)
236                 _D("====> COMPOSITOR IS NOT ENABLED");
237
238         xmonitor_info.create_handler =
239                 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE, _create_cb, NULL);
240         goto_if(NULL == xmonitor_info.create_handler, Error);
241
242         xmonitor_info.destroy_handler =
243                 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _destroy_cb, NULL);
244         goto_if(NULL == xmonitor_info.destroy_handler, Error);
245
246         xmonitor_info.focus_in_handler =
247                 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _focus_in_cb, NULL);
248         goto_if(NULL == xmonitor_info.focus_in_handler, Error);
249
250         xmonitor_info.focus_out_handler =
251                 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _focus_out_cb, NULL);
252         goto_if(NULL == xmonitor_info.focus_out_handler, Error);
253
254         _sniff_all_windows();
255         if (false == _set_idlescreen_top()) _E("cannot set idlescreen_is_top");
256
257         return 0;
258
259 Error:
260         if (xmonitor_info.create_handler) {
261                 ecore_event_handler_del(xmonitor_info.create_handler);
262                 xmonitor_info.create_handler = NULL;
263         } else return -EFAULT;
264
265         if (xmonitor_info.destroy_handler) {
266                 ecore_event_handler_del(xmonitor_info.destroy_handler);
267                 xmonitor_info.destroy_handler = NULL;
268         } else return -EFAULT;
269
270         if (xmonitor_info.focus_in_handler) {
271                 ecore_event_handler_del(xmonitor_info.focus_in_handler);
272                 xmonitor_info.focus_in_handler = NULL;
273         } else return -EFAULT;
274
275         if (xmonitor_info.focus_out_handler) {
276                 ecore_event_handler_del(xmonitor_info.focus_out_handler);
277                 xmonitor_info.focus_out_handler = NULL;
278         } else return -EFAULT;
279
280         return -EFAULT;
281 }
282
283 void xmonitor_fini(void)
284 {
285         ecore_event_handler_del(xmonitor_info.create_handler);
286         xmonitor_info.create_handler = NULL;
287
288         ecore_event_handler_del(xmonitor_info.destroy_handler);
289         xmonitor_info.destroy_handler = NULL;
290
291         ecore_event_handler_del(xmonitor_info.focus_in_handler);
292         xmonitor_info.focus_in_handler = NULL;
293
294         ecore_event_handler_del(xmonitor_info.focus_out_handler);
295         xmonitor_info.focus_out_handler = NULL;
296 }