From: Mun, Gwan-gyeong Date: Mon, 1 Jun 2015 15:53:23 +0000 (+0900) Subject: Add Notification Level apis with wayland X-Git-Tag: submit/tizen/20150612.014854~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b5280eb05a1bc99cc338ab65973fb92271a6896a;p=platform%2Fcore%2Fapi%2Fefl-util.git Add Notification Level apis with wayland Change-Id: I2d4ee133ad508fc664d0bb0daa86e732903299be --- diff --git a/CMakeLists.txt b/CMakeLists.txt index fae5e44..8d7ef86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ ENDIF (WITH_X11) IF (WITH_WAYLAND) ADD_DEFINITIONS("-DWAYLAND") + SET(dependents "${dependents} ecore-wayland wayland-client") ENDIF (WITH_WAYLAND) INCLUDE(FindPkgConfig) diff --git a/src/efl_util.c b/src/efl_util.c index 2b56db0..f472db4 100644 --- a/src/efl_util.c +++ b/src/efl_util.c @@ -28,6 +28,12 @@ #include #endif +#if WAYLAND +#include +#include +#include "tizen_notification-client-protocol.h" +#endif + typedef struct _notification_error_cb_info { Evas_Object *window; @@ -50,6 +56,130 @@ static Eina_Bool _efl_util_client_message(void *data, int type, void *event); static notification_error_cb_info *_notification_error_cb_info_find_by_xwin(unsigned int xwin); #endif +#if WAYLAND +typedef struct _Surface_Level +{ + struct wl_surface *surface; + uint32_t level; +} Surface_Level; + +static void _cb_handle_registry_global(void *data, struct wl_registry *registry, unsigned int name, const char *interface, unsigned int version); +static void _cb_handle_registry_global_remove(void *data, struct wl_registry *registry, unsigned int name); +static void _notification_set_level_done(void *data, struct tizen_notification *tizen_notification, struct wl_surface *surface, uint32_t level, uint32_t error_state); +static notification_error_cb_info *_notification_error_cb_info_find_by_wl_surface(struct wl_surface *surface); + +static const struct wl_registry_listener _registry_listener = +{ + _cb_handle_registry_global, + _cb_handle_registry_global_remove +}; + +struct tizen_notification_listener _tizen_notification_listener = +{ + _notification_set_level_done, +}; + +static struct tizen_notification *_tizen_notification = NULL; +static Eina_Bool _efl_util_init_done = EINA_FALSE; +static Eina_Hash *hash_surface_levels = NULL; + +static void +_cb_handle_registry_global(void *data, struct wl_registry *registry, unsigned int name, const char *interface, unsigned int version) +{ + if (!strcmp(interface, "tizen_notification")) + { + _tizen_notification = wl_registry_bind(registry, name, &tizen_notification_interface, 1); + if (!_tizen_notification) return; + tizen_notification_add_listener(_tizen_notification, &_tizen_notification_listener, NULL); + _efl_util_init_done = EINA_TRUE; + hash_surface_levels = eina_hash_pointer_new(free); + } +} + +# define _FREE_FUNC(_h, _fn) do { if (_h) { _fn((void*)_h); _h = NULL; } } while (0) +static void +_cb_handle_registry_global_remove(void *data, struct wl_registry *registry, unsigned int name) +{ + _tizen_notification = NULL; + _efl_util_init_done = EINA_FALSE; + _FREE_FUNC(hash_surface_levels, eina_hash_free); + /* no-op */ +} + +static void +_notification_set_level_done(void *data, + struct tizen_notification *tizen_notification, + struct wl_surface *surface, + uint32_t level, + uint32_t error_state) +{ + Surface_Level *sl; + notification_error_cb_info *cb_info = NULL; + efl_util_error_e error_cb_state = EFL_UTIL_ERROR_NONE; + + if (error_state == TIZEN_NOTIFICATION_ERROR_STATE_NONE) + { + if (hash_surface_levels) + { + sl = eina_hash_find(hash_surface_levels, &surface); + if (!sl) + { + sl = calloc(1, sizeof(Surface_Level)); + if (sl) + { + sl->surface = surface; + sl->level = level; + eina_hash_add(hash_surface_levels, &surface, sl); + } + } + else + { + sl->level = level; + } + } + } + + cb_info = _notification_error_cb_info_find_by_wl_surface(surface); + if (cb_info) + { + switch (error_state) + { + case TIZEN_NOTIFICATION_ERROR_STATE_NONE: + error_cb_state = EFL_UTIL_ERROR_NONE; + break; + case TIZEN_NOTIFICATION_ERROR_STATE_INVALID_PARAMETER: + error_cb_state = EFL_UTIL_ERROR_INVALID_PARAMETER; + break; + case TIZEN_NOTIFICATION_ERROR_STATE_OUT_OF_MEMORY: + error_cb_state = EFL_UTIL_ERROR_OUT_OF_MEMORY; + break; + case TIZEN_NOTIFICATION_ERROR_STATE_PERMISSION_DENIED: + error_cb_state = EFL_UTIL_ERROR_PERMISSION_DENIED; + break; + case EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE: + default: + error_cb_state = TIZEN_NOTIFICATION_ERROR_STATE_NOT_SUPPORTED_WINDOW_TYPE; + break; + } + if (cb_info->err_cb) + cb_info->err_cb(cb_info->window, error_cb_state , cb_info->user_data); + } +} + +static void +_efl_util_wl_init(void) +{ + static Eina_Bool init = EINA_FALSE; + if (!init) + { + wl_registry_add_listener(wl_display_get_registry(ecore_wl_display_get()), + &_registry_listener, NULL); + init = EINA_TRUE; + } + while (!_efl_util_init_done) + wl_display_dispatch(ecore_wl_display_get()); +} +#endif int efl_util_set_notification_window_level(Evas_Object *window, efl_util_notification_level_e level) @@ -82,12 +212,16 @@ efl_util_set_notification_window_level(Evas_Object *window, efl_util_notificatio } #endif -#if ECORE_WAYLAND_FOUND - Ecore_Wl_Window wl_win = elm_win_wl_window_get(window); +#if WAYLAND + Ecore_Wl_Window *wl_win = elm_win_wl_window_get(window); if (wl_win) { - printf("not implemented for wayland yet\n"); - return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE; + _efl_util_wl_init(); + //Add notification window type check + tizen_notification_set_level(_tizen_notification, + ecore_wl_window_surface_get(wl_win), + level); + return EFL_UTIL_ERROR_NONE; } #endif @@ -146,12 +280,31 @@ efl_util_get_notification_window_level(Evas_Object *window, efl_util_notificatio } #endif -#if ECORE_WAYLAND_FOUND - Ecore_Wl_Window wl_win = elm_win_wl_window_get(window); +#if WAYLAND + Ecore_Wl_Window *wl_win = elm_win_wl_window_get(window); if (wl_win) { - printf("not implemented for wayland yet\n"); - return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE; + Surface_Level *sl; + struct wl_surface *surface = ecore_wl_window_surface_get(wl_win); + sl = eina_hash_find(hash_surface_levels, &surface); + if (sl) + { + switch (sl->level) + { + case TIZEN_NOTIFICATION_LEVEL_1: + *level = EFL_UTIL_NOTIFICATION_LEVEL_1; + break; + case TIZEN_NOTIFICATION_LEVEL_2: + *level = EFL_UTIL_NOTIFICATION_LEVEL_2; + break; + case TIZEN_NOTIFICATION_LEVEL_3: + *level = EFL_UTIL_NOTIFICATION_LEVEL_3; + break; + default: + return EFL_UTIL_ERROR_INVALID_PARAMETER; + } + return EFL_UTIL_ERROR_NONE; + } } #endif return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE; @@ -179,12 +332,10 @@ efl_util_set_notification_window_level_error_cb(Evas_Object *window, efl_util_no return EFL_UTIL_ERROR_NONE; #endif -#if ECORE_WAYLAND_FOUND - printf("not implemented for wayland yet\n"); - return EFL_UTIL_ERROR_NOT_SUPPORTED_WINDOW_TYPE; +#if WAYLAND + return EFL_UTIL_ERROR_NONE; #endif } - return EFL_UTIL_ERROR_OUT_OF_MEMORY; } @@ -268,6 +419,30 @@ _notification_error_cb_info_find_by_xwin(unsigned int xwin) } #endif +#if WAYLAND +static notification_error_cb_info * +_notification_error_cb_info_find_by_wl_surface(struct wl_surface *surface) +{ + Eina_List *l; + notification_error_cb_info* temp; + struct wl_surface *temp_surface; + + EINA_LIST_FOREACH(_g_notification_error_cb_info_list, l, temp) + { + if (temp->window) + { + temp_surface = ecore_wl_window_surface_get(elm_win_wl_window_get(temp->window)); + if (surface == temp_surface) + { + return temp; + } + } + } + + return NULL; +} +#endif + static notification_error_cb_info * _notification_error_cb_info_find(Evas_Object *window) { diff --git a/src/tizen_notification-client-protocol.h b/src/tizen_notification-client-protocol.h new file mode 100644 index 0000000..cfe16e8 --- /dev/null +++ b/src/tizen_notification-client-protocol.h @@ -0,0 +1,92 @@ +#ifndef TIZEN_NOTIFICATION_CLIENT_PROTOCOL_H +#define TIZEN_NOTIFICATION_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-client.h" + +struct wl_client; +struct wl_resource; + +struct tizen_notification; + +extern const struct wl_interface tizen_notification_interface; + +#ifndef TIZEN_NOTIFICATION_LEVEL_ENUM +#define TIZEN_NOTIFICATION_LEVEL_ENUM +enum tizen_notification_level { + TIZEN_NOTIFICATION_LEVEL_1 = 0, + TIZEN_NOTIFICATION_LEVEL_2 = 1, + TIZEN_NOTIFICATION_LEVEL_3 = 2, +}; +#endif /* TIZEN_NOTIFICATION_LEVEL_ENUM */ + +#ifndef TIZEN_NOTIFICATION_ERROR_STATE_ENUM +#define TIZEN_NOTIFICATION_ERROR_STATE_ENUM +enum tizen_notification_error_state { + TIZEN_NOTIFICATION_ERROR_STATE_NONE = 0, + TIZEN_NOTIFICATION_ERROR_STATE_INVALID_PARAMETER = 1, + TIZEN_NOTIFICATION_ERROR_STATE_OUT_OF_MEMORY = 2, + TIZEN_NOTIFICATION_ERROR_STATE_PERMISSION_DENIED = 3, + TIZEN_NOTIFICATION_ERROR_STATE_NOT_SUPPORTED_WINDOW_TYPE = 4, +}; +#endif /* TIZEN_NOTIFICATION_ERROR_STATE_ENUM */ + +struct tizen_notification_listener { + /** + * done - (none) + * @surface: (none) + * @level: (none) + * @error_state: (none) + */ + void (*done)(void *data, + struct tizen_notification *tizen_notification, + struct wl_surface *surface, + uint32_t level, + uint32_t error_state); +}; + +static inline int +tizen_notification_add_listener(struct tizen_notification *tizen_notification, + const struct tizen_notification_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) tizen_notification, + (void (**)(void)) listener, data); +} + +#define TIZEN_NOTIFICATION_SET_LEVEL 0 + +static inline void +tizen_notification_set_user_data(struct tizen_notification *tizen_notification, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) tizen_notification, user_data); +} + +static inline void * +tizen_notification_get_user_data(struct tizen_notification *tizen_notification) +{ + return wl_proxy_get_user_data((struct wl_proxy *) tizen_notification); +} + +static inline void +tizen_notification_destroy(struct tizen_notification *tizen_notification) +{ + wl_proxy_destroy((struct wl_proxy *) tizen_notification); +} + +static inline void +tizen_notification_set_level(struct tizen_notification *tizen_notification, struct wl_surface *surface, uint32_t level) +{ + wl_proxy_marshal((struct wl_proxy *) tizen_notification, + TIZEN_NOTIFICATION_SET_LEVEL, surface, level); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/tizen_notification-protocol.c b/src/tizen_notification-protocol.c new file mode 100644 index 0000000..36c4475 --- /dev/null +++ b/src/tizen_notification-protocol.c @@ -0,0 +1,28 @@ +#include +#include +#include "wayland-util.h" + +extern const struct wl_interface wl_surface_interface; + +static const struct wl_interface *types[] = { + &wl_surface_interface, + NULL, + &wl_surface_interface, + NULL, + NULL, +}; + +static const struct wl_message tizen_notification_requests[] = { + { "set_level", "ou", types + 0 }, +}; + +static const struct wl_message tizen_notification_events[] = { + { "done", "ouu", types + 2 }, +}; + +WL_EXPORT const struct wl_interface tizen_notification_interface = { + "tizen_notification", 1, + 1, tizen_notification_requests, + 1, tizen_notification_events, +}; +