Fix coding conventions and style.
[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
55 efl_util_set_notification_window_level(Evas_Object *window, efl_util_notification_level_e level)
56 {
57    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
58    EINA_SAFETY_ON_FALSE_RETURN_VAL((level >= EFL_UTIL_NOTIFICATION_LEVEL_1) &&
59                                    (level <= EFL_UTIL_NOTIFICATION_LEVEL_3),
60                                    EFL_UTIL_ERROR_INVALID_PARAMETER);
61
62 #if X11
63    Ecore_X_Window xwin = elm_win_xwindow_get(window);
64    if (xwin)
65      {
66         Ecore_X_Window_Type window_type;
67         if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
68           {
69              // success to get window type
70              if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
71                {
72                   // given EFL window's type is not notification type.
73                   return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
74                }
75           }
76         else
77           return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
78
79         utilx_set_system_notification_level(ecore_x_display_get(), xwin,
80                                             level);
81         return EFL_UTIL_ERROR_NONE;
82      }
83 #endif
84
85 #if ECORE_WAYLAND_FOUND
86    Ecore_Wl_Window wl_win = elm_win_wl_window_get(window);
87    if (wl_win)
88      {
89         printf("not implemented for wayland yet\n");
90         return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
91      }
92 #endif
93
94    return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
95 }
96
97 int
98 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, EFL_UTIL_ERROR_INVALID_PARAMETER);
102    EINA_SAFETY_ON_NULL_RETURN_VAL(level, EFL_UTIL_ERROR_INVALID_PARAMETER);
103
104 #if X11
105    Ecore_X_Window_Type window_type;
106    Utilx_Notification_Level utilx_level;
107    Ecore_X_Window xwin = elm_win_xwindow_get(window);
108    if (xwin)
109      {
110         if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
111           {
112              // success to get window type
113              if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
114                {
115                   // given EFL window's type is not notification type.
116                   return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
117                }
118
119              utilx_level = utilx_get_system_notification_level (ecore_x_display_get(), xwin);
120
121              if(utilx_level == UTILX_NOTIFICATION_LEVEL_LOW)
122                {
123                   *level = EFL_UTIL_NOTIFICATION_LEVEL_1;
124                }
125              else if(utilx_level == UTILX_NOTIFICATION_LEVEL_NORMAL)
126                {
127                   *level = EFL_UTIL_NOTIFICATION_LEVEL_2;
128                }
129              else if(utilx_level == UTILX_NOTIFICATION_LEVEL_HIGH)
130                {
131                   *level = EFL_UTIL_NOTIFICATION_LEVEL_3;
132                }
133              else
134                {
135                   return EFL_UTIL_ERROR_INVALID_PARAMETER;
136                }
137
138           }
139         else
140           {
141              // fail to get window type
142              return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
143           }
144
145         return EFL_UTIL_ERROR_NONE;
146      }
147 #endif
148
149 #if ECORE_WAYLAND_FOUND
150    Ecore_Wl_Window wl_win = elm_win_wl_window_get(window);
151    if (wl_win)
152      {
153         printf("not implemented for wayland yet\n");
154         return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
155      }
156 #endif
157    return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
158 }
159
160 int
161 efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
162 {
163    Eina_Bool ret = EINA_FALSE;
164
165    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
166    EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EFL_UTIL_ERROR_INVALID_PARAMETER);
167
168    ret = _efl_util_notification_info_add(window, callback, user_data);
169    if (ret)
170      {
171 #if X11
172         if (!_noti_level_access_result_atom)
173           _noti_level_access_result_atom = ecore_x_atom_get("_E_NOTIFICATION_LEVEL_ACCESS_RESULT");
174
175         if (!_noti_level_access_result_handler)
176           _noti_level_access_result_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _efl_util_client_message, NULL);
177         _noti_handler_count++;
178
179         return EFL_UTIL_ERROR_NONE;
180 #endif
181
182 #if ECORE_WAYLAND_FOUND
183         printf("not implemented for wayland yet\n");
184         return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
185 #endif
186      }
187
188    return EFL_UTIL_ERROR_OUT_OF_MEMORY;
189 }
190
191 int
192 efl_util_unset_notification_window_level_error_cb(Evas_Object *window)
193 {
194    Eina_Bool ret = EINA_FALSE;
195
196    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
197
198    ret = _efl_util_notification_info_del(window);
199    if (ret)
200      {
201         _noti_handler_count--;
202         if (_noti_handler_count == 0)
203           {
204              if (_noti_level_access_result_handler)
205                {
206                   ecore_event_handler_del(_noti_level_access_result_handler);
207                   _noti_level_access_result_handler = NULL;
208                }
209           }
210         return EFL_UTIL_ERROR_NONE;
211      }
212
213    return EFL_UTIL_ERROR_INVALID_PARAMETER;
214 }
215
216 #if X11
217 static Eina_Bool
218 _efl_util_client_message(void *data, int type, void *event)
219 {
220    Ecore_X_Event_Client_Message *ev;
221
222    ev = event;
223    if (!ev) return ECORE_CALLBACK_PASS_ON;
224
225    if (ev->message_type == _noti_level_access_result_atom)
226      {
227         Ecore_X_Window xwin;
228         xwin = ev->win;
229
230         notification_error_cb_info *cb_info = NULL;
231         cb_info = _notification_error_cb_info_find_by_xwin(xwin);
232         if (cb_info)
233           {
234              int access = ev->data.l[1];
235              if (access == 0) // permission denied
236                {
237                   if (cb_info->err_cb)
238                     {
239                        cb_info->err_cb(cb_info->window, EFL_UTIL_ERROR_PERMISSION_DENIED, cb_info->user_data);
240                     }
241                }
242           }
243      }
244
245    return ECORE_CALLBACK_PASS_ON;
246 }
247
248 static notification_error_cb_info *
249 _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 *
272 _notification_error_cb_info_find(Evas_Object *window)
273 {
274    Eina_List *l;
275    notification_error_cb_info* temp;
276
277    EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
278      {
279         if (temp->window == window)
280           {
281              return temp;
282           }
283      }
284
285    return NULL;
286 }
287
288 static Eina_Bool
289 _efl_util_notification_info_add(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
290 {
291    notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
292
293    if (_err_info)
294      {
295         _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
296         free(_err_info);
297         _err_info = NULL;
298      }
299
300    _err_info = (notification_error_cb_info*)calloc(1, sizeof(notification_error_cb_info));
301    if (!_err_info)
302      {
303         return EINA_FALSE;
304      }
305    _err_info->window = window;
306    _err_info->err_cb = callback;
307    _err_info->user_data = user_data;
308
309    _g_notification_error_cb_info_list = eina_list_append(_g_notification_error_cb_info_list, _err_info);
310
311    return EINA_TRUE;
312 }
313
314 static Eina_Bool
315 _efl_util_notification_info_del(Evas_Object *window)
316 {
317    notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
318    if (!_err_info)
319      {
320         return EINA_FALSE;
321      }
322
323    _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
324    free(_err_info);
325
326    return EINA_TRUE;
327 }