2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #define LOG_TAG "TIZEN_N_EFL_UTIL"
24 #include <Elementary.h>
32 #include <Ecore_Wayland.h>
33 #include <wayland-client.h>
34 #include "tizen_notification-client-protocol.h"
37 typedef struct _notification_error_cb_info
40 efl_util_notification_window_level_error_cb err_cb;
42 } notification_error_cb_info;
44 Eina_List *_g_notification_error_cb_info_list;
45 static Ecore_Event_Handler* _noti_level_access_result_handler = NULL;
46 static int _noti_handler_count = 0;
48 static notification_error_cb_info *_notification_error_cb_info_find(Evas_Object *window);
49 static Eina_Bool _efl_util_notification_info_add(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data);
50 static Eina_Bool _efl_util_notification_info_del(Evas_Object *window);
53 static unsigned int _noti_level_access_result_atom = 0;
55 static Eina_Bool _efl_util_client_message(void *data, int type, void *event);
56 static notification_error_cb_info *_notification_error_cb_info_find_by_xwin(unsigned int xwin);
60 typedef struct _Surface_Level
62 struct wl_surface *surface;
66 static void _cb_handle_registry_global(void *data, struct wl_registry *registry, unsigned int name, const char *interface, unsigned int version);
67 static void _cb_handle_registry_global_remove(void *data, struct wl_registry *registry, unsigned int name);
68 static void _notification_set_level_done(void *data, struct tizen_notification *tizen_notification, struct wl_surface *surface, uint32_t level, uint32_t error_state);
69 static notification_error_cb_info *_notification_error_cb_info_find_by_wl_surface(struct wl_surface *surface);
71 static const struct wl_registry_listener _registry_listener =
73 _cb_handle_registry_global,
74 _cb_handle_registry_global_remove
77 struct tizen_notification_listener _tizen_notification_listener =
79 _notification_set_level_done,
82 static struct tizen_notification *_tizen_notification = NULL;
83 static Eina_Bool _efl_util_init_done = EINA_FALSE;
84 static Eina_Hash *hash_surface_levels = NULL;
87 _cb_handle_registry_global(void *data, struct wl_registry *registry, unsigned int name, const char *interface, unsigned int version)
89 if (!strcmp(interface, "tizen_notification"))
91 _tizen_notification = wl_registry_bind(registry, name, &tizen_notification_interface, 1);
92 if (!_tizen_notification) return;
93 tizen_notification_add_listener(_tizen_notification, &_tizen_notification_listener, NULL);
94 _efl_util_init_done = EINA_TRUE;
95 hash_surface_levels = eina_hash_pointer_new(free);
99 # define _FREE_FUNC(_h, _fn) do { if (_h) { _fn((void*)_h); _h = NULL; } } while (0)
101 _cb_handle_registry_global_remove(void *data, struct wl_registry *registry, unsigned int name)
103 _tizen_notification = NULL;
104 _efl_util_init_done = EINA_FALSE;
105 _FREE_FUNC(hash_surface_levels, eina_hash_free);
110 _notification_set_level_done(void *data,
111 struct tizen_notification *tizen_notification,
112 struct wl_surface *surface,
114 uint32_t error_state)
117 notification_error_cb_info *cb_info = NULL;
118 efl_util_error_e error_cb_state = EFL_UTIL_ERROR_NONE;
120 if (error_state == TIZEN_NOTIFICATION_ERROR_STATE_NONE)
122 if (hash_surface_levels)
124 sl = eina_hash_find(hash_surface_levels, &surface);
127 sl = calloc(1, sizeof(Surface_Level));
130 sl->surface = surface;
132 eina_hash_add(hash_surface_levels, &surface, sl);
142 cb_info = _notification_error_cb_info_find_by_wl_surface(surface);
147 case TIZEN_NOTIFICATION_ERROR_STATE_NONE:
148 error_cb_state = EFL_UTIL_ERROR_NONE;
150 case TIZEN_NOTIFICATION_ERROR_STATE_INVALID_PARAMETER:
151 error_cb_state = EFL_UTIL_ERROR_INVALID_PARAMETER;
153 case TIZEN_NOTIFICATION_ERROR_STATE_OUT_OF_MEMORY:
154 error_cb_state = EFL_UTIL_ERROR_OUT_OF_MEMORY;
156 case TIZEN_NOTIFICATION_ERROR_STATE_PERMISSION_DENIED:
157 error_cb_state = EFL_UTIL_ERROR_PERMISSION_DENIED;
159 case EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE:
161 error_cb_state = TIZEN_NOTIFICATION_ERROR_STATE_NOT_SUPPORTED_WINDOW_TYPE;
165 cb_info->err_cb(cb_info->window, error_cb_state , cb_info->user_data);
170 _efl_util_wl_init(void)
172 static Eina_Bool init = EINA_FALSE;
175 wl_registry_add_listener(wl_display_get_registry(ecore_wl_display_get()),
176 &_registry_listener, NULL);
179 while (!_efl_util_init_done)
180 wl_display_dispatch(ecore_wl_display_get());
185 efl_util_set_notification_window_level(Evas_Object *window, efl_util_notification_level_e level)
187 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
188 EINA_SAFETY_ON_FALSE_RETURN_VAL((level >= EFL_UTIL_NOTIFICATION_LEVEL_1) &&
189 (level <= EFL_UTIL_NOTIFICATION_LEVEL_3),
190 EFL_UTIL_ERROR_INVALID_PARAMETER);
193 Ecore_X_Window xwin = elm_win_xwindow_get(window);
196 Ecore_X_Window_Type window_type;
197 if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
199 // success to get window type
200 if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
202 // given EFL window's type is not notification type.
203 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
207 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
209 utilx_set_system_notification_level(ecore_x_display_get(), xwin,
211 return EFL_UTIL_ERROR_NONE;
216 Ecore_Wl_Window *wl_win = elm_win_wl_window_get(window);
220 //Add notification window type check
221 tizen_notification_set_level(_tizen_notification,
222 ecore_wl_window_surface_get(wl_win),
224 return EFL_UTIL_ERROR_NONE;
228 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
232 efl_util_get_notification_window_level(Evas_Object *window, efl_util_notification_level_e *level)
235 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
236 EINA_SAFETY_ON_NULL_RETURN_VAL(level, EFL_UTIL_ERROR_INVALID_PARAMETER);
239 Ecore_X_Window_Type window_type;
240 Utilx_Notification_Level utilx_level;
241 Ecore_X_Window xwin = elm_win_xwindow_get(window);
244 if(ecore_x_netwm_window_type_get(xwin, &window_type) == EINA_TRUE)
246 // success to get window type
247 if(window_type != ECORE_X_WINDOW_TYPE_NOTIFICATION)
249 // given EFL window's type is not notification type.
250 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
253 utilx_level = utilx_get_system_notification_level (ecore_x_display_get(), xwin);
255 if(utilx_level == UTILX_NOTIFICATION_LEVEL_LOW)
257 *level = EFL_UTIL_NOTIFICATION_LEVEL_1;
259 else if(utilx_level == UTILX_NOTIFICATION_LEVEL_NORMAL)
261 *level = EFL_UTIL_NOTIFICATION_LEVEL_2;
263 else if(utilx_level == UTILX_NOTIFICATION_LEVEL_HIGH)
265 *level = EFL_UTIL_NOTIFICATION_LEVEL_3;
269 return EFL_UTIL_ERROR_INVALID_PARAMETER;
275 // fail to get window type
276 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
279 return EFL_UTIL_ERROR_NONE;
284 Ecore_Wl_Window *wl_win = elm_win_wl_window_get(window);
288 struct wl_surface *surface = ecore_wl_window_surface_get(wl_win);
289 sl = eina_hash_find(hash_surface_levels, &surface);
294 case TIZEN_NOTIFICATION_LEVEL_1:
295 *level = EFL_UTIL_NOTIFICATION_LEVEL_1;
297 case TIZEN_NOTIFICATION_LEVEL_2:
298 *level = EFL_UTIL_NOTIFICATION_LEVEL_2;
300 case TIZEN_NOTIFICATION_LEVEL_3:
301 *level = EFL_UTIL_NOTIFICATION_LEVEL_3;
304 return EFL_UTIL_ERROR_INVALID_PARAMETER;
306 return EFL_UTIL_ERROR_NONE;
310 return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE;
314 efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
316 Eina_Bool ret = EINA_FALSE;
318 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
319 EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EFL_UTIL_ERROR_INVALID_PARAMETER);
321 ret = _efl_util_notification_info_add(window, callback, user_data);
325 if (!_noti_level_access_result_atom)
326 _noti_level_access_result_atom = ecore_x_atom_get("_E_NOTIFICATION_LEVEL_ACCESS_RESULT");
328 if (!_noti_level_access_result_handler)
329 _noti_level_access_result_handler = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _efl_util_client_message, NULL);
330 _noti_handler_count++;
332 return EFL_UTIL_ERROR_NONE;
336 return EFL_UTIL_ERROR_NONE;
339 return EFL_UTIL_ERROR_OUT_OF_MEMORY;
343 efl_util_unset_notification_window_level_error_cb(Evas_Object *window)
345 Eina_Bool ret = EINA_FALSE;
347 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EFL_UTIL_ERROR_INVALID_PARAMETER);
349 ret = _efl_util_notification_info_del(window);
352 _noti_handler_count--;
353 if (_noti_handler_count == 0)
355 if (_noti_level_access_result_handler)
357 ecore_event_handler_del(_noti_level_access_result_handler);
358 _noti_level_access_result_handler = NULL;
361 return EFL_UTIL_ERROR_NONE;
364 return EFL_UTIL_ERROR_INVALID_PARAMETER;
369 _efl_util_client_message(void *data, int type, void *event)
371 Ecore_X_Event_Client_Message *ev;
374 if (!ev) return ECORE_CALLBACK_PASS_ON;
376 if (ev->message_type == _noti_level_access_result_atom)
381 notification_error_cb_info *cb_info = NULL;
382 cb_info = _notification_error_cb_info_find_by_xwin(xwin);
385 int access = ev->data.l[1];
386 if (access == 0) // permission denied
390 cb_info->err_cb(cb_info->window, EFL_UTIL_ERROR_PERMISSION_DENIED, cb_info->user_data);
396 return ECORE_CALLBACK_PASS_ON;
399 static notification_error_cb_info *
400 _notification_error_cb_info_find_by_xwin(unsigned int xwin)
403 notification_error_cb_info* temp;
404 unsigned int temp_xwin;
406 EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
410 temp_xwin = elm_win_xwindow_get(temp->window);
411 if (xwin == temp_xwin)
423 static notification_error_cb_info *
424 _notification_error_cb_info_find_by_wl_surface(struct wl_surface *surface)
427 notification_error_cb_info* temp;
428 struct wl_surface *temp_surface;
430 EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
434 temp_surface = ecore_wl_window_surface_get(elm_win_wl_window_get(temp->window));
435 if (surface == temp_surface)
446 static notification_error_cb_info *
447 _notification_error_cb_info_find(Evas_Object *window)
450 notification_error_cb_info* temp;
452 EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp)
454 if (temp->window == window)
464 _efl_util_notification_info_add(Evas_Object *window, efl_util_notification_window_level_error_cb callback, void *user_data)
466 notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
470 _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);
475 _err_info = (notification_error_cb_info*)calloc(1, sizeof(notification_error_cb_info));
480 _err_info->window = window;
481 _err_info->err_cb = callback;
482 _err_info->user_data = user_data;
484 _g_notification_error_cb_info_list = eina_list_append(_g_notification_error_cb_info_list, _err_info);
490 _efl_util_notification_info_del(Evas_Object *window)
492 notification_error_cb_info* _err_info = _notification_error_cb_info_find(window);
498 _g_notification_error_cb_info_list = eina_list_remove(_g_notification_error_cb_info_list, _err_info);