Add Notification Level apis with wayland 70/40270/3
authorMun, Gwan-gyeong <kk.moon@samsung.com>
Mon, 1 Jun 2015 15:53:23 +0000 (00:53 +0900)
committerMun, Gwan-gyeong <kk.moon@samsung.com>
Tue, 2 Jun 2015 05:15:55 +0000 (14:15 +0900)
Change-Id: I2d4ee133ad508fc664d0bb0daa86e732903299be

CMakeLists.txt
src/efl_util.c
src/tizen_notification-client-protocol.h [new file with mode: 0644]
src/tizen_notification-protocol.c [new file with mode: 0644]

index fae5e44..8d7ef86 100644 (file)
@@ -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)
index 2b56db0..f472db4 100644 (file)
 #include <utilX.h>
 #endif
 
+#if WAYLAND
+#include <Ecore_Wayland.h>
+#include <wayland-client.h>
+#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 (file)
index 0000000..cfe16e8
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef TIZEN_NOTIFICATION_CLIENT_PROTOCOL_H
+#define TIZEN_NOTIFICATION_CLIENT_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#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 (file)
index 0000000..36c4475
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdlib.h>
+#include <stdint.h>
+#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,
+};
+