revert cd59af8f9aceab2b2cef52ac2fc122cb5e028702
[platform/core/api/efl-util.git] / src / efl_util.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
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 #define LOG_TAG "TIZEN_N_EFL_UTIL"
19
20 #include <efl_util.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <Elementary.h>
25
26 #if X11
27 #include <Ecore_X.h>
28 #include <utilX.h>
29 #endif
30
31 typedef struct _notification_error_cb_info
32 {
33         Evas_Object *window;
34         efl_util_notification_window_level_error_cb err_cb;
35         void *user_data;
36 } notification_error_cb_info;
37
38 Eina_List *_g_notification_error_cb_info_list;
39 static Ecore_Event_Handler* _noti_level_access_result_handler = NULL;
40 static int _noti_handler_count = 0;
41
42 static notification_error_cb_info *_notification_error_cb_info_find(Evas_Object *window);
43 static Eina_Bool _efl_util_notification_info_add(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data);
44 static Eina_Bool _efl_util_notification_info_del(Evas_Object *window);
45
46 #if X11
47 static unsigned int _noti_level_access_result_atom = 0;
48
49 static Eina_Bool _efl_util_client_message(void *data, int type, void *event);
50 static notification_error_cb_info *_notification_error_cb_info_find_by_xwin(unsigned int xwin);
51 #endif
52
53
54 int efl_util_set_notification_window_level (Evas_Object* window, efl_util_notification_level_e level)
55 {
56         EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
57         EINA_SAFETY_ON_FALSE_RETURN_VAL(level >= EFL_UTIL_NOTIFICATION_LEVEL_1 &&
58                                         level <= EFL_UTIL_NOTIFICATION_LEVEL_3,
59                                         EFL_UTIL_ERROR_INVALID_PARAMETER);
60
61 #if X11
62         Ecore_X_Window xwin = elm_win_xwindow_get(window);
63         if (xwin)
64         {
65                 Ecore_X_Window_Type window_type;
66                 if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
67                 {
68                         // success to get window type
69                         if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
70                         {
71                                 // given EFL window's type is not notification type.
72                                 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
73                         }
74                 }
75                 else
76                         return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
77
78                 utilx_set_system_notification_level(ecore_x_display_get(), xwin,
79                                                     level);
80                 return EFL_UTIL_ERROR_NONE;
81         }
82 #endif
83
84 #if ECORE_WAYLAND_FOUND
85         Ecore_Wl_Window wl_win = elm_win_wl_window_get(window);
86         if (wl_win)
87         {
88                 printf("not implemented for wayland yet\n");
89                 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
90         }
91 #endif
92
93        return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
94 }
95
96
97
98 int efl_util_get_notification_window_level (Evas_Object* window, efl_util_notification_level_e* level)
99 {
100         
101         EINA_SAFETY_ON_NULL_RETURN_VAL(window,
102                                        EFL_UTIL_ERROR_INVALID_PARAMETER);
103         EINA_SAFETY_ON_NULL_RETURN_VAL(level,
104                                        EFL_UTIL_ERROR_INVALID_PARAMETER);
105
106 #if X11
107         Ecore_X_Window_Type window_type;
108         Utilx_Notification_Level utilx_level;
109         Ecore_X_Window xwin = elm_win_xwindow_get(window);
110         if (xwin)
111         {
112                 if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
113                 {
114                         // success to get window type
115                         if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
116                         {
117                                 // given EFL window's type is not notification type.
118                                 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
119                         }
120                 
121                         utilx_level = utilx_get_system_notification_level (ecore_x_display_get(), xwin);
122
123                         if(utilx_level == UTILX_NOTIFICATION_LEVEL_LOW)
124                         {
125                                 *level = EFL_UTIL_NOTIFICATION_LEVEL_1;
126                         }
127                         else if(utilx_level == UTILX_NOTIFICATION_LEVEL_NORMAL)
128                         {
129                                 *level = EFL_UTIL_NOTIFICATION_LEVEL_2;
130                         }
131                         else if(utilx_level == UTILX_NOTIFICATION_LEVEL_HIGH)
132                         {
133                                 *level = EFL_UTIL_NOTIFICATION_LEVEL_3;
134                         }
135                         else
136                         {
137                                 return EFL_UTIL_ERROR_INVALID_PARAMETER;
138                         }
139                 
140                 }
141                 else
142                 {
143                         // fail to get window type
144                         return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
145                 }
146         
147                 return EFL_UTIL_ERROR_NONE;
148         }
149 #endif
150
151 #if ECORE_WAYLAND_FOUND
152         Ecore_Wl_Window wl_win = elm_win_wl_window_get(window);
153         if (wl_win)
154         {
155                 printf("not implemented for wayland yet\n");
156                 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
157         }
158 #endif
159         return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
160 }
161
162 int efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
163 {
164         Eina_Bool ret = EINA_FALSE;
165
166         EINA_SAFETY_ON_NULL_RETURN_VAL(window,
167                                        EFL_UTIL_ERROR_INVALID_PARAMETER);
168         EINA_SAFETY_ON_NULL_RETURN_VAL(callback,
169                                        EFL_UTIL_ERROR_INVALID_PARAMETER);
170
171         ret = _efl_util_notification_info_add(window, callback, user_data);
172         if (ret)
173         {
174 #if X11
175                 if (!_noti_level_access_result_atom)
176                         _noti_level_access_result_atom = ecore_x_atom_get("_E_NOTIFICATION_LEVEL_ACCESS_RESULT");
177
178                 if (!_noti_level_access_result_handler)
179                         _noti_level_access_result_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _efl_util_client_message, NULL);
180                 _noti_handler_count++;
181
182                 return EFL_UTIL_ERROR_NONE;
183 #endif
184
185 #if ECORE_WAYLAND_FOUND
186                 printf("not implemented for wayland yet\n");
187                 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
188 #endif
189         }
190
191         return EFL_UTIL_ERROR_OUT_OF_MEMORY;
192 }
193
194 int efl_util_unset_notification_window_level_error_cb(Evas_Object *window)
195 {
196         Eina_Bool ret = EINA_FALSE;
197
198         EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
199
200         ret = _efl_util_notification_info_del(window);
201         if (ret)
202         {
203                 _noti_handler_count--;
204                 if (_noti_handler_count == 0)
205                 {
206                         if (_noti_level_access_result_handler)
207                         {
208                                 ecore_event_handler_del(_noti_level_access_result_handler);
209                                 _noti_level_access_result_handler = NULL;
210                         }
211                 }
212                 return EFL_UTIL_ERROR_NONE;
213         }
214
215         return EFL_UTIL_ERROR_INVALID_PARAMETER;
216 }
217
218 #if X11
219 static Eina_Bool _efl_util_client_message(void *data, int type, void *event)
220 {
221         Ecore_X_Event_Client_Message *ev;
222
223         ev = event;
224         if (!ev) return ECORE_CALLBACK_PASS_ON;
225
226         if (ev->message_type == _noti_level_access_result_atom)
227         {
228                 Ecore_X_Window xwin;
229                 xwin = ev->win;
230
231                 notification_error_cb_info *cb_info = NULL;
232                 cb_info = _notification_error_cb_info_find_by_xwin(xwin);
233                 if (cb_info)
234                 {
235                         int access = ev->data.l[1];
236                         if (access == 0) // permission denied
237                         {
238                                 if (cb_info->err_cb)
239                                 {
240                                         cb_info->err_cb(cb_info->window, EFL_UTIL_ERROR_PERMISSION_DENIED, cb_info->user_data);
241                                 }
242                         }
243                 }
244         }
245
246         return ECORE_CALLBACK_PASS_ON;
247 }
248
249 static notification_error_cb_info *_notification_error_cb_info_find_by_xwin(unsigned int xwin)
250 {
251         Eina_List *l;
252         notification_error_cb_info* temp;
253         unsigned int temp_xwin;
254
255         EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
256         {
257                 if (temp->window)
258                 {
259                         temp_xwin = elm_win_xwindow_get(temp->window);
260                         if (xwin == temp_xwin)
261                         {
262                                 return temp;
263                         }
264                 }
265         }
266
267         return NULL;
268 }
269 #endif
270
271 static notification_error_cb_info *_notification_error_cb_info_find(Evas_Object *window)
272 {
273         Eina_List *l;
274         notification_error_cb_info* temp;
275
276         EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
277         {
278                 if (temp->window == window)
279                 {
280                         return temp;
281                 }
282         }
283
284         return NULL;
285 }
286
287 static Eina_Bool _efl_util_notification_info_add(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
288 {
289         notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
290
291         if (_err_info)
292         {
293                 _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
294                 free(_err_info);
295                 _err_info = NULL;
296         }
297
298         _err_info = (notification_error_cb_info*)calloc(1, sizeof(notification_error_cb_info));
299         if (!_err_info)
300         {
301                 return EINA_FALSE;
302         }
303         _err_info->window = window;
304         _err_info->err_cb = callback;
305         _err_info->user_data = user_data;
306
307         _g_notification_error_cb_info_list = eina_list_append(_g_notification_error_cb_info_list, _err_info);
308
309         return EINA_TRUE;
310 }
311
312 static Eina_Bool _efl_util_notification_info_del(Evas_Object *window)
313 {
314         notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
315         if (!_err_info)
316         {
317                 return EINA_FALSE;
318         }
319
320         _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
321         free(_err_info);
322
323         return EINA_TRUE;
324 }