renew pui prototype again 49/220649/1
authorSung-Jin Park <sj76.park@samsung.com>
Wed, 7 Aug 2019 11:54:07 +0000 (20:54 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Fri, 20 Dec 2019 06:54:19 +0000 (15:54 +0900)
Change-Id: I0240934656a3e275ce702f4b3aa9c4b7f745137e
Signed-off-by: Sung-Jin Park <sj76.park@samsung.com>
20 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
backends/Makefile.am [new file with mode: 0644]
backends/default_backend.c
configure.ac [new file with mode: 0644]
include/PUI.h
include/PUI_backend.h
packaging/libpui.manifest [new file with mode: 0644]
packaging/libpui.spec [new file with mode: 0644]
pkgconfig/libpui.pc.in [new file with mode: 0644]
samples/Makefile.am [new file with mode: 0644]
samples/PUI_sample.c
src/Makefile.am [new file with mode: 0644]
src/PUI.c
src/PUI_ani.c
src/PUI_backend.c
src/PUI_common.h [new file with mode: 0644]
src/PUI_internal.h [moved from include/PUI_internal.h with 53% similarity]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..35ed634
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Sungjin   Park sj76.park@samsung.com
+Jeonghyun Kang jhyuni.kang@samsung.com
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..f1ad2a6
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,26 @@
+Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+---
+
+The above is the version of the MIT "Expat" License used by X.org:
+
+    http://cgit.freedesktop.org/xorg/xserver/tree/COPYING
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..bfabf5d
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS = src backends samples
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = pkgconfig/libpui.pc
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..916169a
--- /dev/null
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+test -n "$srcdir" || srcdir=`dirname "$0"`
+test -n "$srcdir" || srcdir=.
+(
+  cd "$srcdir" &&
+  autoreconf --force -v --install
+) || exit
+test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"
diff --git a/backends/Makefile.am b/backends/Makefile.am
new file mode 100644 (file)
index 0000000..00db99b
--- /dev/null
@@ -0,0 +1,15 @@
+lib_LTLIBRARIES = libpui-default-backend.la
+
+AM_CFLAGS = \
+        $(GCC_CFLAGS) \
+        -I$(top_srcdir)/include \
+        -I$(top_srcdir)/src
+
+libpui_default_backend_includedir=$(includedir)
+libpui_default_backend_include_HEADERS =
+
+libpui_default_backend_la_CFLAGS = $(AM_CFLAGS) $(LIBPUI_BACKEND_CFLAGS)
+libpui_default_backend_la_LIBADD = $(LIBPUI_BACKEND_LIBS)
+
+libpui_default_backend_la_SOURCES = \
+        default_backend.c
index f0ca99d..ab13717 100644 (file)
@@ -1,9 +1,9 @@
-#include <PUI.h>
+//#include <PUI.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <PUI_backend.h>
 
-pui_backend_ani_func *ani_func = NULL;
-
-enum
+typedef enum
 {
        None,
        Linear,
@@ -13,8 +13,8 @@ enum
        EaseOutQuart
 } pui_effect_func;
 
-typedef struct _default_ani_data default_ani_data;
-struct _default_ani_data
+typedef struct _default_ani_info default_ani_info;
+struct _default_ani_info
 {
        pui_id id;
        pui_ani_status status;
@@ -25,33 +25,26 @@ struct _default_ani_data
        unsigned int num_key_frames;
        double interval;
        pui_effect_func effect_func;
-
-       Eina_Bool (*frame_cb)(void *data);
-
-/*
-       void *frame_cb_data;
-       double expire;
-       Ecore_Timer *frame_cb_timer;
-*/
 };
 
-static void
-_start_frame(pui_ani_mgr *ani_mgr)
-{
-       //TODO
-}
+pui_backend_ani_data *g_ani_data = NULL;
 
-static Eina_Bool
-_frame_cb(void *data)
+static pui_bool
+_frame_cb(void *data, int serial)
 {
+       pui_ani_t *ani = (pui_ani_t *)data;
+
        //TODO
+       (void) ani;
        //_get_next_frame();
        //pui_backend_ani_get_buffer();
        //pui_backend_ani_update();
+
+       return (pui_bool)1;
 }
 
 pui_int_error
-get_ani_data_from_collection(default_ani_data *data, pui_id id)
+get_ani_info_from_ani_collection(default_ani_info *info, pui_id id)
 {
        pui_int_error e = PUI_INT_ERROR_NONE;
 
@@ -62,58 +55,38 @@ get_ani_data_from_collection(default_ani_data *data, pui_id id)
        return e;
 }
 
-pui_backend_ani_data *
-_ani_create(pui_ani_mgr *ani_mgr, pui_id id)
-{
-       pui_int_error e = PUI_INT_ERROR_NONE; 
-       default_ani_data *data = (default_ani_data *)calloc(1, sizeof(default_ani_data));
-
-       if (!data)
-       {
-               pui_err("Failed to allocate memory !\n");
-               return NULL;
-       }
-
-       e = get_ani_data_from_collection(data, id);
-
-       if (PUI_INT_ERROR_NONE != e)
-       {
-               pui_err("Failed to get ani data from collection !\n");
-               goto err;
-       }
-       
-       return (pui_backend_ani_data *)default_ani_data;
-
-err:
-       if (data)
-               free(data);
-
-       return NULL;
-}
-
 pui_error
-_ani_start(pui_ani_mgr *ani_mgr, int repeat)
+_ani_start(pui_ani_t *ani, int repeat)
 {
        pui_int_error e = PUI_INT_ERROR_NONE;
+       pui_backend_ani_data *ani_data = NULL;
 
-       default_ani_data *data = (default_ani_data *)ani_mgr->ani_data;
+       ani_data = pui_backend_ani_get_ani_data(ani);
+       default_ani_info *info = (default_ani_info *)ani_data->ani_info;
 
        //TODO
-       //start_frame(ani_mgr);
-       //pui_backend_ani_add_frame_cb(data->frame_cb);
+       (void) info;
+
+       pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STARTED);
+       pui_backend_ani_add_frame_cb(ani, _frame_cb, 0.1);
 
        return e;
 }
 
 pui_error
-_ani_stop(pui_ani_mgr *ani_mgr)
+_ani_stop(pui_ani_t *ani)
 {
        pui_int_error e = PUI_INT_ERROR_NONE;
+       pui_backend_ani_data *ani_data = NULL;
 
-       default_ani_data *data = (default_ani_data *)ani_mgr->ani_data;
+       ani_data = pui_backend_ani_get_ani_data(ani);
+       default_ani_info *info = (default_ani_info *)ani_data->ani_info;
 
        //TODO
-       //pui_backend_ani_remove_frame_cb(data->frame_cb);
+       (void) info;
+
+       pui_backend_ani_remove_frame_cb(ani);
+       pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STOPPED);
 
        return e;
 }
@@ -139,22 +112,29 @@ _is_ani_supported(pui_id id)
        return e;
 }
 
-pui_backend_ani_func *
-_get_ani_func(pui_id id)
+pui_backend_ani_data *
+_ani_create(pui_id id)
 {
-       if (ani_func)
-               return ani_func;
+       pui_int_error e = PUI_INT_ERROR_NONE;
+
+       pui_backend_ani_data *ani_data = NULL;
+       pui_backend_ani_func *ani_func = NULL;
+
+       /* backend's animation specific info */
+       default_ani_info *ani_info = NULL;
+
+       //TODO : return NULL if the animation correspond to the given id dones't exist.
 
+       /* allocation of the structure of function pointers that will be called from pui_ani_control() */
        ani_func = pui_backend_ani_alloc_ani_func();
 
        if (!ani_func)
        {
-               pui_err("Failed to allocate memory !\n");
+               pui_err("Failed to allocate memory ! (pui backend ani func)\n");
                return NULL;
        }
 
-       /* Assign each function pointer that corresponds to the given id */
-       ani_func->ani_create = _ani_create;
+       /* Assign each function pointer that corresponds to the given id if needed. */
        ani_func->ani_start = _ani_start;
        ani_func->ani_stop = _ani_stop;
 
@@ -169,7 +149,72 @@ _get_ani_func(pui_id id)
        ani_func->reserved9 = NULL;
        ani_func->reserved10 = NULL;
 
-       return ani_func;
+       /* backend's animation specific info */
+       ani_info = (default_ani_info *)calloc(1, sizeof(default_ani_info));
+
+       if (!ani_info)
+       {
+               pui_err("Failed to allocate memory ! (backend's ani specific info)\n");
+               goto err;
+       }
+
+       /* fill animation info associate with the given id from animation collection */
+       e = get_ani_info_from_ani_collection(ani_info, id);
+       
+       if (PUI_INT_ERROR_NONE != e)
+       {
+               pui_err("Failed to get ani info from animation collection !\n");
+               goto err;
+       }
+
+       /* allocate backend ani_data and return it to pui ani core */
+       ani_data = (pui_backend_ani_data *)calloc(1, sizeof(pui_backend_ani_data));
+       
+       if (!ani_data)
+       {
+               pui_err("Failed to allocate memory for pui backend ani data !\n");
+               goto err;
+       }
+       
+       ani_data->ani_func = ani_func;
+       ani_data->ani_info = (pui_backend_ani_info *)ani_info;
+
+       g_ani_data = ani_data;
+
+       return ani_data;
+
+err:
+       if (ani_func)
+       {
+               pui_backend_ani_free_ani_func(ani_func);
+               ani_func = NULL;
+       }
+
+       if (ani_info)
+       {
+               //TODO : free if anything needs to be done with ani_info
+
+               free(ani_info);
+       }
+
+       return NULL;
+}
+
+void
+_ani_destroy(pui_backend_ani_data *ani_data)
+{
+       if (!ani_data)
+               return;
+
+       pui_backend_ani_free_ani_func(ani_data->ani_func);
+
+       //TODO : free if anything needs to be done with ani_info
+       free(ani_data->ani_info);
+
+       ani_data->ani_func = NULL;
+       ani_data->ani_info = NULL;
+
+       g_ani_data = NULL;
 }
 
 static pui_backend_module_data *
@@ -185,27 +230,14 @@ pui_default_backend_init(void)
                return NULL;
        }
 
+       backend_data->create_ani_collection = _create_ani_collection;
+       backend_data->ani_create = _ani_create;
+       backend_data->ani_destroy = _ani_destroy;
+
        /* Allocate backend specific data if needed. Now it will be empty. */
        backend_data->data = NULL;
 
-       backend_data->create_ani_collection = _create_ani_collection;
-       backend_data->is_ani_supported = _is_ani_supported;
-       backend_data->get_ani_func = _get_ani_func;
-
        return backend_data;
-
-err:
-       if (backend_data)
-       {
-               if (backend_data->data)
-               {
-                       free(backend_data->data);
-               }
-
-               free(backend_data);
-       }
-
-       return NULL;
 }
 
 static void
@@ -221,22 +253,32 @@ pui_default_backend_deinit(pui_backend_module_data *backend_data)
                free(backend_data->data);
        }
 
-       if (backend_data->get_ani_func && ani_func)
+       if (g_ani_data)
        {
-               pui_backend_ani_free_ani_func(ani_func);
-               ani_func = NULL;
+               if (g_ani_data->ani_func)
+               {
+                       pui_backend_ani_free_ani_func(g_ani_data->ani_func);
+                       g_ani_data->ani_func = NULL;
+               }
+
+               if (g_ani_data->ani_info)
+               {
+                       //TODO : free if anything needs to be done with ani_info
+                       free(g_ani_data->ani_info);
+                       g_ani_data->ani_info = NULL;
+               }
        }
 
-       backend_data->get_ani_func = NULL;
        backend_data->create_ani_collection = NULL;
-       backend_data->is_ani_supported = NULL;
+       backend_data->ani_create = NULL;
+       backend_data->ani_destroy = NULL;
 
        free(backend_data);
        backend_data = NULL;
 }
 
 pui_backend_module pui_backend_module_info = {
-       "tizen_ref_speaker",
+       "Tizen Reference Speaker Backend",
        "Samsung",
        PUI_BACKEND_SET_ABI_VERSION(1, 0),
        pui_default_backend_init,
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..764b8f0
--- /dev/null
@@ -0,0 +1,77 @@
+m4_define([libpui_major], 0)
+m4_define([libpui_minor], 0)
+m4_define([libpui_micro], 1)
+
+m4_define([libpui_version], [libpui_major.libpui_minor.libpui_micro])
+
+AC_PREREQ([2.64])
+AC_INIT([libpui], [libpui_version], [sj76.park@samsung.com])
+
+AC_SUBST([LIBPUI_VERSION_MAJOR], [libpui_major_version])
+AC_SUBST([LIBPUI_VERSION_MINOR], [libpui_minor_version])
+AC_SUBST([LIBPUI_VERSION_MICRO], [libpui_micro_version])
+AC_SUBST([LIBPUI_VERSION], [libpui_version])
+
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz subdir-objects])
+AM_SILENT_RULES([yes])
+
+AC_PROG_CC
+
+LT_PREREQ([2.2])
+LT_INIT([disable-static])
+
+# backend-dir : get directory information
+AC_ARG_WITH([backend-dir],
+    [AS_HELP_STRING([--with-backend-dir=<path>],
+        [Set backend lookup dir (default: $libdir)])],
+    [BACKEND_DIR="$withval"],
+    [BACKEND_DIR="$libdir"])
+AC_SUBST([BACKEND_DIR])
+
+# anidata-dir : get directory information
+AC_ARG_WITH([anidata-dir],
+    [AS_HELP_STRING([--with-anidata-dir=<path>],
+        [Set anidata lookup dir (default: $datadir/pui)])],
+    [ANIDATA_DIR="$withval"],
+    [ANIDATA_DIR="$datadir/pui"])
+AC_SUBST([ANIDATA_DIR])
+
+# libpui
+LIBPUI_DIR="-I\$(top_srcdir)/include"
+LIBPUI_LIB="\$(top_srcdir)/src/libpui.la"
+
+LIBPUI_REQUIRES="ecore eina ecore-wl2 wayland-tbm-client"
+PKG_CHECK_MODULES(LIBPUI, $[LIBPUI_REQUIRES])
+
+LIBPUI_CFLAGS+=" -DBACKEND_DIR=$BACKEND_DIR -DANIDATA_DIR=$ANIDATA_DIR "
+
+AC_SUBST(LIBPUI_CFLAGS)
+AC_SUBST(LIBPUI_LIBS)
+
+# libpui default backend
+DEFAULT_BACKEND_REQUIRES=""
+DEFAULT_BACKEND_CFLAGS="$LIBPUI_DIR "
+#DEFAULT_BACKEND_CFLAGS="$DEFAULT_BACKEND_CFLAGS $LIBPUI_CFLAGS "
+DEFAULT_BACKEND_LIBS="$LIBPUI_LIB "
+
+AC_SUBST(DEFAULT_BACKEND_CFLAGS)
+AC_SUBST(DEFAULT_BACKEND_LIBS)
+
+# samples
+SAMPLES_REQUIRES="ecore-wl2 ecore-input"
+PKG_CHECK_MODULES(SAMPLES, $[SAMPLES_REQUIRES])
+
+SAMPLES_CFLAGS="$LIBPUI_DIR $SAMPLES_CFLAGS "
+SAMPLES_LIBS="$LIBPUI_LIB $SAMPLES_LIBS "
+
+# Output files
+AC_CONFIG_FILES([
+Makefile
+src/Makefile
+samples/Makefile
+backends/Makefile
+pkgconfig/libpui.pc
+])
+
+AC_OUTPUT
index 42cafab..16275c2 100644 (file)
@@ -1,59 +1,26 @@
 #ifndef _LIBPUI_H_
 #define _LIBPUI_H_
 
-#include "PUI_internal.h"
-#include <Ecore_Wl2.h>
-#include <wayland-tbm-client.h>
-#include <tbm_surface_internal.h>
+#include "PUI_common.h"
 
 #define EFL_BETA_API_SUPPORT
-#define PUI_API __attribute__ ((visibility("default"))
-
-EAPI extern int PUI_EVENT_ANI_STARTED = 0;
-EAPI extern int PUI_EVENT_ANI_STOPPED = 0;
-EAPI extern int PUI_EVENT_ANI_PAUSED = 0;
-EAPI extern int PUI_EVENT_ANI_READY_TO_START = 0;
-EAPI extern int PUI_EVENT_ANI_READY_TO_RESUME = 0;
-EAPI extern int PUI_EVENT_ANI_FRAME_DONE = 0;
-EAPI extern int PUI_EVENT_ANI_BUFFER_RELEASED = 0;
-
-enum {
-       PUI_ERROR_NONE,
-       PUI_ERROR_INVALID_ANI_HANDLE,
-       PUI_ERROR_INVALID_ANI_CMD,
-       PUI_ERROR_INVALID_ANI_OPT,
-       PUI_ERROR_INTERNAL,
-} pui_error;
-
-enum {
-       PUI_ANI_STATUS_INITIAL,
-       PUI_ANI_STATUS_RUNNING,
-       PUI_ANI_STATUS_PAUSED,
-       PUI_ANI_STATUS_STOPPED,
-       PUI_ANI_STATUS_FORCE_STOPPED,
-} pui_ani_status;
-
-enum {
-       PUI_ANI_CMD_NONE,
-       PUI_ANI_CMD_START,
-       PUI_ANI_CMD_STOP,
-       PUI_ANI_CMD_LAST
-} pui_ani_cmd;
-
-enum {
-       PUI_ANI_OPT_NONE,
-       PUI_ANI_OPT_ONCE,
-       PUI_ANI_OPT_REPEAT,
-       PUI_ANI_OPT_LAST
-} pui_ani_opt;
-
-typedef char* pui_id;
-typedef char* pui_error_string;
-typedef struct _pui * pui_h;
-typedef struct _pui_ani * pui_ani_h;
-typedef struct _pui_module_data pui_module_data;
-
-typedef struct _PUI_Event_Animation_Status PUI_Event_Animation_Status;
+#include <Ecore_Wl2.h>
+
+#define PUI_API __attribute__ ((visibility("default")))
+
+extern PUI_API int PUI_EVENT_ANI_STARTED;
+extern PUI_API int PUI_EVENT_ANI_STOPPED;
+extern PUI_API int PUI_EVENT_ANI_PAUSED;
+extern PUI_API int PUI_EVENT_ANI_READY_TO_START;
+extern PUI_API int PUI_EVENT_ANI_READY_TO_RESUME;
+extern PUI_API int PUI_EVENT_ANI_FRAME_DONE;
+extern PUI_API int PUI_EVENT_ANI_BUFFER_RELEASED;
+
+struct _PUI_Event_Animation_Status
+{
+   unsigned int win;
+   pui_ani_status status;
+};
 
 #ifdef __cplusplus
 extern "C" {
@@ -71,26 +38,26 @@ pui_create(Ecore_Wl2_Window *win);
 PUI_API void
 pui_destroy(pui_h handle);
 
-PUI_API const pui_error_string
+PUI_API pui_error_string
 pui_error_to_string(pui_error e);
 
 PUI_API pui_ani_h
 pui_ani_create(pui_h handle, pui_id id);
 
 PUI_API pui_error
-pui_ani_control(pui_ani_h handle, pui_ani_cmd cmd, pui_ani_opt opt);
+pui_ani_control(pui_ani_h handle, pui_ani_cmd cmd, int repeat);
 
 PUI_API void
-pui_ani_destroy(pui_ani_h handle);
+pui_ani_destroy(pui_ani_h ani_h);
 
 PUI_API pui_id
-pui_ani_get_id(pui_ani_h handle);
+pui_ani_get_id(pui_ani_h ani_h);
 
 PUI_API pui_ani_cmd
-pui_ani_get_cmd(pui_ani_h handle);
+pui_ani_get_cmd(pui_ani_h ani_h);
 
-PUI_API pui_ani_opt
-pui_ani_get_opt(pui_ani_h handle);
+PUI_API int
+pui_ani_get_repeat(pui_ani_h ani_h);
 
 #ifdef __cplusplus
 }
index 147066a..a39f197 100644 (file)
@@ -1,13 +1,12 @@
 #ifndef _LIBPUI_BACKEND_H_
 #define _LIBPUI_BACKEND_H_
 
-#include "PUI.h"
-#include "PUI_internal.h"
+#include "PUI_common.h"
 
 #define PUI_BACKEND_ABI_MAJOR_MASK     0xFFFF0000
 #define PUI_BACKEND_ABI_MINOR_MASK     0x0000FFFF
 
-#define PUI_BACKEND_GET_ABI_MAJOR(m)   ((m) & PUI_BACKEND_ABI_MAJOR_MASK) >> 16)
+#define PUI_BACKEND_GET_ABI_MAJOR(m)   (((m) & PUI_BACKEND_ABI_MAJOR_MASK) >> 16)
 #define PUI_BACKEND_GET_ABI_MINOR(m)   ((m) & PUI_BACKEND_ABI_MINOR_MASK)
 
 #define PUI_BACKEND_SET_ABI_VERSION(major, minor)      \
 #define PUI_BACKEND_ABI_VERSION_1_0            PUI_BACKEND_SET_ABI_VERSION(1, 0)
 #define PUI_BACKEND_AB_VERSION_LAST    PUI_BACKEND_ABI_VERSION_1_0
 
-typedef struct _pui_ani_control_buffer pui_ani_control_buffer;
-typedef struct _pui_ani_mgr pui_ani_mgr;
-
 typedef struct _pui_backend_ani_func pui_backend_ani_func;
 struct _pui_backend_ani_func
 {
-       pui_error (*ani_create)(pui_ani_mgr *ani_mgr, pui_id id);
-       pui_error (*ani_start)(pui_ani_mgr *ani_mgr, int repeat);
-       pui_error (*ani_stop)(pui_ani_mgr *ani_mgr);
+       pui_error (*ani_start)(pui_ani_t *ani, int repeat);
+       pui_error (*ani_stop)(pui_ani_t *ani);
 
        void (*reserved1)(void);
        void (*reserved2)(void);
@@ -38,18 +33,24 @@ struct _pui_backend_ani_func
        void (*reserved10)(void);
 };
 
-typedef struct _pui_backend_module_data pui_backend_module_data;
+typedef void pui_backend_ani_info;
+
+struct _pui_backend_ani_data
+{
+       pui_backend_ani_func *ani_func;
+       pui_backend_ani_info *ani_info;
+};
+
 struct _pui_backend_module_data
 {
        void *data;
 
        pui_int_error (*create_ani_collection)(void);
-       pui_int_error (*is_ani_supported)(pui_id id);
-       pui_backend_ani_func *(*get_ani_func)(pui_id id);
+       pui_backend_ani_data *(*ani_create)(pui_id id);
+       void (*ani_destroy)(pui_backend_ani_data *ani_data);
 };
 
-typedef struct _pui_backend_module pui_backend_module;
-typedef struct _pui_backend_module
+struct _pui_backend_module
 {
        const char *name;                       /**< The name of a backend module */
        const char *vendor;             /**< The vendor name of a backend module */
@@ -59,26 +60,27 @@ typedef struct _pui_backend_module
        void (*backend_deinit)(pui_backend_module_data *backend_data);
 };
 
-typedef void pui_backend_ani_data;
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 pui_ani_control_buffer *
-pui_backend_ani_get_buffer(pui_ani_mgr *ani_mgr);
+pui_backend_ani_get_buffer(pui_ani_t *ani);
 
 pui_int_error
-pui_backend_ani_set_buffer(pui_ani_mgr *ani_mgr, pui_ani_control_buffer *buffer);
+pui_backend_ani_set_buffer(pui_ani_t *ani, pui_ani_control_buffer *buffer);
 
 pui_int_error
-pui_backend_ani_update(pui_ani_mgr *ani_mgr);
+pui_backend_ani_update(pui_ani_t *ani);
+
+void
+pui_backend_ani_add_frame_cb(pui_ani_t *ani, pui_bool (*frame_cb)(void *data, int serial), double frame_interval);
 
 void
-pui_backend_ani_add_frame_cb(pui_ani_mgr *ani_mgr, Eina_Bool (*frame_cb)(void *data), double expire, void *data)\r;
+pui_backend_ani_remove_frame_cb(pui_ani_t *ani);
 
 void
-pui_backend_ani_remove_frame_cb(pui_ani_mgr *ani_mgr, void *data);
+pui_backend_ani_status_update(pui_ani_t *ani, pui_ani_status status);
 
 pui_backend_ani_func *
 pui_backend_ani_alloc_ani_func(void);
@@ -86,6 +88,9 @@ pui_backend_ani_alloc_ani_func(void);
 void
 pui_backend_ani_free_ani_func(pui_backend_ani_func *func);
 
+pui_backend_ani_data *
+pui_backend_ani_get_ani_data(pui_ani_t *ani);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/packaging/libpui.manifest b/packaging/libpui.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/libpui.spec b/packaging/libpui.spec
new file mode 100644 (file)
index 0000000..9052ecc
--- /dev/null
@@ -0,0 +1,90 @@
+Name:          libpui
+Version:       0.0.1
+Release:       0
+Summary:       Tizen Headless Platform User Interaction Library
+License:       MIT
+Group:         Graphics & UI Framework/Wayland Window System
+
+Source:                %{name}-%{version}.tar.xz
+source1001:     %name.manifest
+
+BuildRequires: autoconf > 2.64
+BuildRequires: automake >= 1.11
+BuildRequires: libtool >= 2.2
+BuildRequires: pkgconfig
+BuildRequires: xz
+BuildRequires:  pkgconfig(wayland-tbm-client)
+BuildRequires:  pkgconfig(ecore-wl2)
+#BuildRequires:  pkgconfig(dlog)
+
+%{!?TZ_SYS_LIB: %global TZ_SYS_LIB /usr/lib}
+%{!?TZ_SYS_RO_SHARE: %global TZ_SYS_RO_SHARE /usr/share}
+
+%description
+Tizen Headless Platform User Interaction Library
+
+###### libpui-devel
+%package devel
+Summary: Development module for libpui package
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+This package includes developer files common to all packages.
+
+###### libpui default backend
+%package default-backend
+Summary: Default backend module for libpui package
+Requires: %{name} = %{version}-%{release}
+
+%description default-backend
+Default Backend of Tizen Headless Platform User Interaction Library
+
+###### samples
+%package samples
+Summary: samples for libpui package
+Requires: %{name} = %{version}-%{release}
+
+%description samples
+This package includes samples files.
+
+###### executing
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+%autogen \
+       --with-backend-dir=%{TZ_SYS_LIB} \
+       --with-anidata-dir=%{TZ_SYS_RO_SHARE}
+
+make %{?_smp_mflags}
+
+%install
+%make_install
+
+%post -n %{name} -p /sbin/ldconfig
+%postun -n %{name} -p /sbin/ldconfig
+
+%files -n %{name}
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license COPYING
+%{_libdir}/libpui.so.*
+
+%files devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_includedir}/*.h
+%{_libdir}/pkgconfig/libpui.pc
+%{_libdir}/libpui.so
+
+%files default-backend
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%license COPYING
+%{_libdir}/*default*.so*
+
+%files samples
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_bindir}/pui_sample*
diff --git a/pkgconfig/libpui.pc.in b/pkgconfig/libpui.pc.in
new file mode 100644 (file)
index 0000000..0b9ba3a
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libpui
+Description: Tizen Headless Platform User Interaction Library
+Version: @LIBPUI_VERSION@
+Requires: libpui
+Libs: -L${libdir} -lpui
+Cflags: -I${includedir}
diff --git a/samples/Makefile.am b/samples/Makefile.am
new file mode 100644 (file)
index 0000000..d8170e8
--- /dev/null
@@ -0,0 +1,9 @@
+bin_PROGRAMS = pui_sample
+
+AM_CPPFLAGS = $(GCC_CFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/include
+pui_sample_ldadd = $(top_builddir)/src/libpui.la
+
+pui_sample_CFLAGS = $(AM_CFLAGS) $(SAMPLES_CFLAGS)
+pui_sample_LDADD = $(SAMPLES_LIBS) $(pui_sample_ldadd)
+
+pui_sample_SOURCES = PUI_sample.c
index cc4744d..359fd8e 100644 (file)
@@ -1,7 +1,10 @@
 #include <stdio.h>
-#include <PUI.h>
-
 #define NUM_ECORE_EVENT_HANDLERS 4
+#define EFL_BETA_API_SUPPORT
+
+#include <Ecore_Wl2.h>
+#include <Ecore_Input.h>
+#include <PUI.h>
 
 #define debug_error(msg, ...)                                                                                  \
        do {                                                                                                                            \
@@ -18,7 +21,7 @@ struct _animation
 {
        pui_id id;
        pui_ani_cmd cmd;
-       pui_ani_opt opt;
+       int repeat;
 };
 
 typedef struct app_data app_data_t;
@@ -33,56 +36,29 @@ struct app_data
 
 static Eina_Array *_ecore_event_hdls = NULL;
 static animation_t ani_collection[] = {
-       { "bixby_listening", PUI_ANI_CMD_START, PUI_ANI_OPT_ONCE },
-       { "bixby_processing", PUI_ANI_CMD_START, PUI_ANI_OPT_REPEAT },
-       { "bixby_speaking", PUI_ANI_CMD_START, PUI_ANI_OPT_REPEAT },
-       { "bixby_error", PUI_ANI_CMD_START, PUI_ANI_OPT_ONCE },
-       { "alarm", PUI_ANI_CMD_START, PUI_ANI_OPT_REPEAT },
-       { "notification", PUI_ANI_CMD_START, PUI_ANI_OPT_REPEAT },
+       { "bixby_listening", PUI_ANI_CMD_START, 1 },
+       { "bixby_processing", PUI_ANI_CMD_START, -1 },
+       { "bixby_speaking", PUI_ANI_CMD_START, -1 },
+       { "bixby_error", PUI_ANI_CMD_START, 1 },
+       { "alarm", PUI_ANI_CMD_START, -1 },
+       { "notification", PUI_ANI_CMD_START, -1 },
 };
 
 static void
-ani_play(app_data_t *app, pui_ani_opt opt)
-{
-       pui_error e;
-
-       if (!app || !app->ani_h)
-       {
-               debug_error("Invalid app data or pui animation handle !\n");
-               return;
-       }
-
-       e = pui_ani_control(app->ani_h, PUI_ANI_CMD_START, opt);
-
-       if (PUI_ERROR_NONE != e)
-       {
-               debug_error("Failed on playing an animation ! (cmd:%d, opt:%d)\n", PUI_ANI_CMD_START, opt);
-               return;
-       }
-
-       debug_info("Animation(%s) will be started !\n", pui_ani_get_id(ani_h));
-}
-
-static void
 ani_stop(app_data_t *app)
 {
-       pui_error e;
-
-       if (!app || !app->ani_h)
-       {
-               debug_error("Invalid app data or pui animation handle !\n");
-               return;
-       }
+       pui_error e = PUI_ERROR_NONE;
 
-       e = pui_ani_control(app->ani_h, PUI_ANI_CMD_STOP, PUI_ANI_OPT_ONCE);
+       /* stop animation running already */
+       e = pui_ani_control(app->ani_h, PUI_ANI_CMD_STOP, 0);
 
        if (PUI_ERROR_NONE != e)
        {
-               debug_error("Failed on stopping an animation !(cmd:%d, opt:%d)\n", PUI_ANI_CMD_STOP, PUI_ANI_OPT_ONCE);
+               debug_error("Failed on stopping an animation !(cmd:%d, repeat:%d)\n", PUI_ANI_CMD_STOP, 0);
                return;
        }
 
-       debug_info("Animation(%s) will be stopped !\n", pui_ani_get_id(ani_h));
+       debug_info("Animation(%s) will be stopped !\n", pui_ani_get_id(app->ani_h));
 }
 
 static void
@@ -93,7 +69,7 @@ ani_collection_play(app_data_t *app)
        pui_ani_h ani_h = NULL;
        pui_error e = PUI_ERROR_NONE;
 
-       n_animation = ani_collection / sizeof(animation_t);
+       n_animation = sizeof(ani_collection) / sizeof(animation_t);
 
        if (n_animation < 0)
        {
@@ -117,24 +93,37 @@ ani_collection_play(app_data_t *app)
 
        if (app->ani_h)
        {
-               ani_stop(app);
+               /* stop animation running already */
+               e = pui_ani_control(app->ani_h, PUI_ANI_CMD_STOP, 0);
+
+               if (PUI_ERROR_NONE != e)
+               {
+                       debug_error("Failed on stopping an animation !(cmd:%d, repeat:%d)\n", PUI_ANI_CMD_STOP, 0);
+                       return;
+               }
+
+               debug_info("Animation(%s) will be stopped !\n", pui_ani_get_id(ani_h));
+
                app->ani_h = NULL;
        }
 
        app->ani_h = ani_h;
-       ani_play(app, ani_collection[ani_idx].opt);
+
+       /* play animation */
+       e = pui_ani_control(app->ani_h, PUI_ANI_CMD_START, ani_collection[ani_idx].repeat);
+
+       if (PUI_ERROR_NONE != e)
+       {
+               debug_error("Failed on playing an animation ! (cmd:%d, repeat:%d)\n", PUI_ANI_CMD_START, ani_collection[ani_idx].repeat);
+               return;
+       }
+
+       debug_info("Animation(%s) will be started !\n", pui_ani_get_id(app->ani_h));
 
        if (++ani_idx >= n_animation)
                ani_idx = 0;
 
        return;
-
-err:
-       if (ani_h)
-       {
-               pui_ani_control(ani_h, PUI_ANI_CMD_STOP, PUI_ANI_OPT_NONE);
-               pui_ani_destroy(ani_h);
-       }
 }
 
 static Eina_Bool
@@ -287,7 +276,7 @@ int main()
        ecore_main_loop_begin();
 err:
        if (app->ani_h)
-               pui_ani_destroy(app->ani_h)
+               pui_ani_destroy(app->ani_h);
        if (app->ph)
                pui_destroy(app->ph);
 
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..346e0c9
--- /dev/null
@@ -0,0 +1,19 @@
+lib_LTLIBRARIES = libpui.la
+
+AM_CFLAGS = \
+        $(GCC_CFLAGS) \
+        -I$(top_srcdir)/include \
+        -I$(top_srcdir)/src
+
+libpui_includedir=$(includedir)
+libpui_include_HEADERS = $(top_srcdir)/include/PUI.h $(top_srcdir)/include/PUI_backend.h
+
+libpui_la_CFLAGS = $(AM_CFLAGS) $(LIBPUI_CFLAGS)
+libpui_la_LIBADD = $(LIBPUI_LIBS)
+
+libpui_la_SOURCES = \
+        PUI.c \
+        PUI_backend.c \
+        PUI_common.h \
+        PUI_ani.c \
+        PUI_internal.h
index c5e8a94..579faf2 100644 (file)
--- a/src/PUI.c
+++ b/src/PUI.c
@@ -1,41 +1,31 @@
-#include "PUI.h"
 #include "PUI_internal.h"
 #include "PUI_backend.h"
+#include "PUI.h"
+
+#include <wayland-tbm-client.h>
+#include <tbm_surface_internal.h>
+#include <stdio.h>
+#include <dlfcn.h>
 
 #ifndef PUI_MODULE_DIR
 #define PUI_MODULE_DIR "/usr/lib"
 #endif
 
-#define pui_err(msg, ...)                                                                              \
-       do {                                                                                                            \
-               fprintf(stderr, "[ERROR][%s] " msg, __FUNCTION__, ##__VA_ARGS__);       \
-       } while(0)
-
-#define pui_warn(msg, ...)                                                                             \
-               do {                                                                                                    \
-                       fprintf(stderr, "[WARNING][%s] " msg, __FUNCTION__, ##__VA_ARGS__);     \
-               } while(0)
-
-#define pui_info(msg, ...)                                                                             \
-       do {                                                                                                            \
-               fprintf(stdout, "[INFO][%s] " msg, __FUNCTION__, ##__VA_ARGS__);        \
-       } while(0)
-
 static int _pui_init_count = 0;
-static pui_module_data *pui_module = NUJLL;
+static pui_module_data *pui_module = NULL;
 
-EAPI int PUI_EVENT_ANI_STARTED = 0;
-EAPI int PUI_EVENT_ANI_STOPPED = 0;
-EAPI int PUI_EVENT_ANI_PAUSED = 0;
-EAPI int PUI_EVENT_ANI_READY_TO_START = 0;
-EAPI int PUI_EVENT_ANI_READY_TO_RESUME = 0;
-EAPI int PUI_EVENT_ANI_FRAME_DONE = 0;
-EAPI int PUI_EVENT_ANI_BUFFER_RELEASED = 0;
+int PUI_EVENT_ANI_STARTED = 0;
+int PUI_EVENT_ANI_STOPPED = 0;
+int PUI_EVENT_ANI_PAUSED = 0;
+int PUI_EVENT_ANI_READY_TO_START = 0;
+int PUI_EVENT_ANI_READY_TO_RESUME = 0;
+int PUI_EVENT_ANI_FRAME_DONE = 0;
+int PUI_EVENT_ANI_BUFFER_RELEASED = 0;
 
-const pui_error_string
+pui_error_string
 pui_error_to_string(pui_error e)
 {
-       const pui_error_string str = NULL;
+       pui_error_string str = NULL;
 
        switch (e)
        {
@@ -51,10 +41,6 @@ pui_error_to_string(pui_error e)
                        str = "PUI_Invalid_Animation_Command";
                        break;
 
-               case PUI_ERROR_INVALID_ANI_OPT:
-                       str = "PUI_Invalid_Animation_Option";
-                       break;
-
                case PUI_ERROR_INTERNAL:
                        str = "PUI_Internal_Error";
                        break;
@@ -66,29 +52,16 @@ pui_error_to_string(pui_error e)
        return str;
 }
 
-static void
-_pui_cb_frame(Ecore_Wl2_Window *win, uint32_t timestamp EINA_UNUSED, void *data)
-{
-       pui_h handle = (pui_h) data;
-
-       TRACE("Frame done ! (window=%p)\n", win);
-
-       // TODO
-
-       return;
-}
-
 pui_h
 pui_create(Ecore_Wl2_Window *win)
 {
        pui_h handle = NULL;
-       Ecore_Wl2_display *ewd = ecore_wl2_window_display_get(win);
+       Ecore_Wl2_Display *ewd = ecore_wl2_window_display_get(win);
        struct wayland_tbm_client *wl_tbm_client = NULL;
-       Ecore_Wl2_Frame_Cb_Handle *frame_cb = NULL;
 
        if (!win || !ewd)
        {
-               pui_err("Invalid window or display !");
+               pui_err("Invalid window or display !\n");
                return NULL;
        }
 
@@ -96,7 +69,7 @@ pui_create(Ecore_Wl2_Window *win)
 
        if (!wl_tbm_client)
        {
-               pui_err("Failed to init wayland_tbm_client !");
+               pui_err("Failed to init wayland_tbm_client !\n");
                return NULL;
        }
 
@@ -133,7 +106,7 @@ err:
 void
 pui_destroy(pui_h handle)
 {
-       pui_ani_h *ani_h = NULL;
+       pui_ani_h ani_h = NULL;
 
        if (!handle)
                return;
@@ -147,7 +120,6 @@ pui_destroy(pui_h handle)
        if (handle->tbm_queue)
        {
                tbm_surface_queue_destroy(handle->tbm_queue);
-               handle->tbm_queue = NULL;
        }
 
        if (handle->wl_tbm_client)
@@ -197,11 +169,11 @@ _pui_load_backend_module(void)
        backend_module_minor = PUI_BACKEND_GET_ABI_MINOR(backend_module_info->abi_version);
 
        if (backend_module_major > pui_backend_major) {
-               TBM_ERR("PUI backend module ABI major ver(%d) is newer than the PUI's ver(%d)\n",
+               pui_err("PUI backend module ABI major ver(%d) is newer than the PUI's ver(%d)\n",
                        backend_module_major, pui_backend_major);
                goto err;
        } else if (backend_module_minor > pui_backend_minor) {
-               TBM_ERR("PUI backend module ABI minor ver(%d) is newer than the PUI's ver(%d)\n",
+               pui_err("PUI backend module ABI minor ver(%d) is newer than the PUI's ver(%d)\n",
                        backend_module_minor, pui_backend_minor);
                goto err;
        }
@@ -227,8 +199,8 @@ _pui_load_backend_module(void)
        return;
 
 err:
-       if (backend_module_info)
-               backend_module_info->backend_deinit
+       if (backend_module_info && backend_module_info->backend_init)
+               backend_module_info->backend_deinit(backend_module_data);
 
        if (module_info)
                dlclose(module_info);
index 2ac1d0d..6ed1b2d 100644 (file)
@@ -1,5 +1,6 @@
-#include "PUI.h"
 #include "PUI_internal.h"
+#include "PUI_backend.h"
+#include "PUI.h"
 #include <Eina.h>
 
 static int KEY_WL_BUFFER = 0xabcdbeaf;
@@ -53,8 +54,9 @@ _cb_focus_out(void *data, int type EINA_UNUSED, void *event)
 static Eina_Bool
 _cb_visibility_change(void *data, int type EINA_UNUSED, void *event)
 {
-       pui_ani_h handle =  (pui_ani_h)data;
-       pui_h ph = handle->pui_handle;
+       pui_ani_h ani_h =  (pui_ani_h)data;
+       pui_ani_t *ani = ani_h->ani;
+       pui_h ph = ani_h->pui_handle;
 
        Ecore_Wl2_Event_Window_Visibility_Change *ev;
        PUI_Event_Animation_Status *e = NULL;
@@ -63,48 +65,65 @@ _cb_visibility_change(void *data, int type EINA_UNUSED, void *event)
 
        pui_info("Visibility change (window=0x%x, fully_obscured=%d)\n", ev->win, ev->fully_obscured);
 
-       ph->visiblity = !(ev->fully_obscured);
+       /* check if this is needed */
+       ph->visibility = !(ev->fully_obscured);
 
        if (ev->fully_obscured)
        {
-               //TODO : e
-               if (handle->status == PUI_ANI_STATUS_RUNNING)
+               if (ani->status == PUI_ANI_STATUS_RUNNING)
                {
-                       handle->status = PUI_ANI_STATUS_STOPPED;
+                       ani->status = PUI_ANI_STATUS_STOPPED;
 
-                       //PUI_Event_Animation_Status e;
-                       if (e = (PUI_Event_Animation_Status *)calloc(1, sizeof(PUI_Event_Animation_Status)))
-                       {
-                               e->win = ev->win;
-                               e->status = PUI_ANI_STATUS_FORCE_STOPPED;
+                       e = (PUI_Event_Animation_Status *)calloc(1, sizeof(PUI_Event_Animation_Status));
 
-                               ecore_event_add(PUI_EVENT_ANI_STOPPED, e, NULL, handle);
+                       if (!e)
+                       {
+                               pui_err("Failed to allocate memory for PUI Event !\n");
+                               return ECORE_CALLBACK_PASS_ON;
                        }
+                       
+                       e->win = ev->win;
+                       e->status = PUI_ANI_STATUS_FORCE_STOPPED;
+                       
+                       ecore_event_add(PUI_EVENT_ANI_STOPPED, e, NULL, ani_h);
                }
        }
        else
        {
-               //TODO : e
-               if (e = (PUI_Event_Animation_Status *)calloc(1, sizeof(PUI_Event_Animation_Status)))
+               e = (PUI_Event_Animation_Status *)calloc(1, sizeof(PUI_Event_Animation_Status));
+               
+               if (!e)
                {
-                       e->win = ev->win;
-                       e->status = handle->status;
-
-                       if (handle->status == PUI_ANI_STATUS_STOPPED)
-                       {
-                               ecore_event_add(PUI_EVENT_ANI_READY_TO_START, e, NULL, handle);
-                       }
-                       else if(handle->status == PUI_ANI_STATUS_PAUSED)
-                       {
-                               ecore_event_add(PUI_EVENT_ANI_READY_TO_RESUME, e, NULL, handle);
-                       }
+                       pui_err("Failed to allocate memory for PUI Event !\n");
+                       return ECORE_CALLBACK_PASS_ON;
                }
+               
+               e->win = ev->win;
+               e->status = ani->status;
+               
+               if (ani->status == PUI_ANI_STATUS_STOPPED)
+                       ecore_event_add(PUI_EVENT_ANI_READY_TO_START, e, NULL, ani_h);
+               else if(ani->status == PUI_ANI_STATUS_PAUSED)
+                       ecore_event_add(PUI_EVENT_ANI_READY_TO_RESUME, e, NULL, ani_h);
        }
 
        return ECORE_CALLBACK_PASS_ON;
 }
 
 static void
+_pui_ani_cb_frame_done(Ecore_Wl2_Window *win, uint32_t timestamp EINA_UNUSED, void *data)
+{
+       pui_h handle = (pui_h) data;
+
+       pui_info("Frame done ! (window=%p)\n", win);
+
+       // TODO
+       (void) handle;
+
+       return;
+}
+
+static void
 _buffer_release(void *data, struct wl_buffer *buffer)
 {
        tbm_surface_h surface = (tbm_surface_h)data;
@@ -161,10 +180,10 @@ pui_ani_get_buffer(pui_ani_h ani_h)
                return NULL;
        }
 
-       tbm_surface_map(surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &handle->sinfo);
+       tbm_surface_map(surface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &handle->current_sinfo);
 
        handle->current_surface = surface;
-       buffer = (pui_ani_control_buffer *)&(handle->sinfo.planes[0]);
+       buffer = (pui_ani_control_buffer *)&(handle->current_sinfo.planes[0]);
 
        return buffer;
 }
@@ -207,6 +226,7 @@ pui_ani_update(pui_ani_h ani_h)
 {
        tbm_surface_h surface;
        tbm_surface_error_e ret;
+       struct wl_buffer *wl_buffer = NULL;
 
        pui_h handle = NULL;
 
@@ -243,7 +263,7 @@ pui_ani_update(pui_ani_h ani_h)
        if (ret != TBM_SURFACE_ERROR_NONE)
        {
                pui_err("[UPDATE] enqueue err:%d\n", ret);
-               return;
+               return PUI_INT_ERROR_INVALID_SURFACE;
        }
 
        ret = tbm_surface_queue_acquire(handle->tbm_queue, &surface);
@@ -251,7 +271,7 @@ pui_ani_update(pui_ani_h ani_h)
        if (ret != TBM_SURFACE_ERROR_NONE)
        {
                pui_err("[UPDATE] acquire err:%d\n", ret);
-               return;
+               return PUI_INT_ERROR_INVALID_SURFACE;
        }
 
        if (!tbm_surface_internal_get_user_data(surface, (unsigned long)&KEY_WL_BUFFER, (void **)&wl_buffer)) {
@@ -260,7 +280,7 @@ pui_ani_update(pui_ani_h ani_h)
                if (!wl_buffer)
                {
                        pui_err("[UPDATE] failed to create wl_buffer tbm_surface:%p\n", surface);
-                       return;
+                       return PUI_INT_ERROR_INVALID_BUFFER;
                }
 
                wl_buffer_add_listener(wl_buffer, &buffer_listener, surface);
@@ -274,7 +294,7 @@ pui_ani_update(pui_ani_h ani_h)
        if (!wl_buffer)
        {
                pui_err("[UPDATE] dequeue err:%d\n", ret);
-               return;
+               return PUI_INT_ERROR_INVALID_BUFFER;
        }
 
        ecore_wl2_window_buffer_attach(handle->win, wl_buffer, 0, 0, 0);
@@ -302,17 +322,17 @@ _pui_ani_event_handlers_init(pui_ani_h ani_h)
        if (!ani_h->ecore_event_hdls)
                ani_h->ecore_event_hdls = eina_array_new(5);
 
-       h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_SHOW, _cb_window_show, handle);
-       eina_array_push(ani_h->_ecore_event_hdls, h);
+       h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_SHOW, _cb_window_show, ani_h);
+       eina_array_push(ani_h->ecore_event_hdls, h);
 
-       h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_IN, _cb_focus_in, handle);
-       eina_array_push(ani_h->_ecore_event_hdls, h);
+       h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_IN, _cb_focus_in, ani_h);
+       eina_array_push(ani_h->ecore_event_hdls, h);
 
-       h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_OUT, _cb_focus_out, handle);
-       eina_array_push(ani_h->_ecore_event_hdls, h);
+       h = ecore_event_handler_add(ECORE_WL2_EVENT_FOCUS_OUT, _cb_focus_out, ani_h);
+       eina_array_push(ani_h->ecore_event_hdls, h);
 
-       h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, _cb_visibility_change, handle);
-       eina_array_push(ani_h->_ecore_event_hdls, h);
+       h = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, _cb_visibility_change, ani_h);
+       eina_array_push(ani_h->ecore_event_hdls, h);
 
 }
 
@@ -325,58 +345,201 @@ _pui_ani_event_handlers_shutdown(pui_ani_h ani_h)
                return;
        }
 
-       while (eina_array_count(ani_h->_ecore_event_hdls))
-               ecore_event_handler_del(eina_array_pop(ani_h->_ecore_event_hdls));
-       eina_array_free(ani_h->_ecore_event_hdls);
+       while (eina_array_count(ani_h->ecore_event_hdls))
+               ecore_event_handler_del(eina_array_pop(ani_h->ecore_event_hdls));
+       eina_array_free(ani_h->ecore_event_hdls);
+
+       ani_h->ecore_event_hdls = NULL;
+}
+
+Eina_Bool _pui_ani_frame_cb(void *data)
+{
+       Eina_Bool ret;
+
+       pui_ani_t *ani = (pui_ani_t *)data;
+
+       if (!ani)
+       {
+               pui_err("Invalid pui ani !\n");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       if (!ani->backend_frame_cb)
+       {
+               pui_err("Invalid backend frame_cb !\n");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       pui_info("frame_cb !\n");
+
+       ret = (Eina_Bool)ani->backend_frame_cb(ani, ++ani->serial);
+
+       if (!ani->frame_cb_timer)
+               return ECORE_CALLBACK_CANCEL;
+
+       pui_ani_status_update(ani, PUI_ANI_STATUS_RUNNING);
+
+       return ret;
+}
+
+void
+pui_ani_add_frame_cb(pui_ani_t *ani, pui_bool (*frame_cb)(void *data, int serial), double frame_interval)
+{
+       Ecore_Timer *timer = NULL;
+
+       if (!ani)
+       {
+               pui_err("Invalid put ani !\n");
+               return;
+       }
+
+       ani->frame_cb = _pui_ani_frame_cb;
+       ani->backend_frame_cb = frame_cb;
+       ani->frame_interval = frame_interval;
+       ani->frame_cb_data = ani;
+       ani->serial = 0;
+
+       timer = ecore_timer_add(frame_interval, (Ecore_Task_Cb)ani->frame_cb, ani->frame_cb_data);
+
+       if (ani->frame_cb_timer)
+       {
+               ecore_timer_del(ani->frame_cb_timer);
+               ani->frame_cb_timer = NULL;
+       }
+
+       ani->frame_cb_timer = timer;
 
-       ani_h->_ecore_event_hdls = NULL;
+       /* call frame_cb for starting the first frame */
+       _pui_ani_frame_cb(ani);
+}
+
+void
+pui_ani_remove_frame_cb(pui_ani_t *ani)
+{
+       if (!ani)
+               return;
+
+       if (ani->frame_cb_timer)
+       {
+               ecore_timer_del(ani->frame_cb_timer);
+               ani->frame_cb_timer = NULL;
+       }
+
+       ani->frame_cb = NULL;
+       ani->backend_frame_cb = NULL;
+       ani->frame_interval = 0;
+       ani->frame_cb_data = NULL;
 }
 
 pui_id
 pui_ani_get_id(pui_ani_h ani_h)
 {
-       if (ani_h && ani_h->id)
-               return ani_h->id;
+       if (!ani_h || !ani_h->ani)
+               return NULL;
+
+       return ani_h->ani->id;
 }
 
 pui_ani_cmd
 pui_ani_get_cmd(pui_ani_h ani_h)
 {
-       if (ani_h && ani_h->cmd)
-               return ani_h->cmd;
+       if (!ani_h || !ani_h->ani)
+               return PUI_ANI_CMD_NONE;
+
+       return ani_h->ani->cmd;
+}
+
+int
+pui_ani_get_repeat(pui_ani_h ani_h)
+{
+       if (!ani_h || !ani_h->ani)
+               return 0;
+
+       return ani_h->ani->repeat;
+}
+
+pui_backend_ani_data *
+pui_ani_get_ani_data(pui_ani_t *ani)
+{
+       if (!ani)
+               return NULL;
+
+       return ani->ani_data;
+}
+
+void
+pui_ani_status_update(pui_ani_t *ani, pui_ani_status status)
+{
+       //TODO : add PUI EVENT
+
+       ani->status = status;
 }
 
-pui_ani_opt
-pui_ani_get_opt(pui_ani_h ani_h)
+pui_ani_status
+pui_ani_status_get(pui_ani_t *ani)
 {
-       if (ani_h && ani_h->opt)
-               return ani_h->opt;
+       pui_ani_status status = PUI_ANI_STATUS_UNKNOWN;
+
+       if (!ani)
+       {
+               pui_err("Invalid pui ani !\n");
+               return status;
+       }
+
+       return ani->status;
 }
 
 pui_error
-pui_ani_control(pui_ani_h ani_h, pui_ani_cmd cmd, pui_ani_opt opt)
+pui_ani_control(pui_ani_h ani_h, pui_ani_cmd cmd, int repeat)
 {
+       pui_ani_t *ani = NULL;
+       pui_h handle = NULL;
+       pui_backend_ani_func *ani_func = NULL;
+
        if (!ani_h)
                return PUI_ERROR_INVALID_ANI_HANDLE;
 
        if (cmd < PUI_ANI_CMD_START || cmd >= PUI_ANI_CMD_LAST)
+       {
+               pui_err("Invalid cmd ! (repeat=%d)\n", repeat);
                return PUI_ERROR_INVALID_ANI_CMD;
+       }
 
-       if (opt < PUI_ANI_OPT_NONE || opt >= PUI_ANI_OPT_LAST)
-               return PUI_ERROR_INVALID_ANI_OPT;
+       if (repeat < -1)
+       {
+               pui_err("Invalid repeat count ! (repeat=%d)\n", repeat);
+               return PUI_ERROR_INVALID_ANI_REPEAT;
+       }
+
+       //TODO : check if there is any animation being played already
+       //NOTE : the id of the animation being played can be different from ani_h->id
+
+       handle = ani_h->pui_handle;
+       ani = ani_h->ani;
 
-       if (ani_h->id && ani_h->status == PUI_ANI_STATUS_RUNNING)
+       if (!ani || !ani->ani_data)
        {
-               
+               pui_err("Invalid ani or ani_data !\n");
+               return PUI_ERROR_INTERNAL;
+       }
+
+       ani_func = ani->ani_data->ani_func;
+
+       if (cmd == PUI_ANI_CMD_START)
+       {
+               ani_func->ani_start(ani, repeat);
+       }
+       else//cmd == PUI_ANI_CMD_STOP
+       {
+               ani_func->ani_stop(ani);
        }
 
-       ani_h->cmd = cmd;
-       ani_h->opt = opt;
-       ani_h->status = PUI_ANI_STATUS_STOPPED;
+       ani->cmd = cmd;
+       ani->repeat = repeat;
 
-       ani_h->frame_cb = ecore_wl2_window_frame_callback_add(win, _pui_cb_frame, handle);
+       ani_h->frame_done_cb = ecore_wl2_window_frame_callback_add(handle->win, _pui_ani_cb_frame_done, handle);
 
-       if (!ani_h->frame_cb)
+       if (!ani_h->frame_done_cb)
        {
                pui_err("Failed to add frame callback !");
                goto err;
@@ -394,20 +557,20 @@ pui_ani_h
 pui_ani_create(pui_h handle, pui_id id)
 {
        pui_ani_h ani_h = NULL;
-       pui_ani_mgr *ani_mgr = NULL;
-       pui_backend_ani_func *ani_func = NULL;
+       pui_ani_t *ani = NULL;
+       pui_backend_ani_data *ani_data = NULL;
 
-       if (!handle || !handle->backend_module_data))
+       if (!handle || !handle->backend_module_data)
        {
                pui_err("Invalid pui handle or backend module data !\n");
                return NULL;
        }
 
-       ani_func = handle->backend_module_data->get_ani_func(id);
+       ani_data = handle->backend_module_data->ani_create(id);
 
-       if (!ani_func)
+       if (!ani_data)
        {
-               pui_err("Invalid ani func from backend module data !\n");
+               pui_err("Invalid ani data from backend module data !\n");
                return NULL;
        }
 
@@ -416,49 +579,80 @@ pui_ani_create(pui_h handle, pui_id id)
        if (!ani_h)
        {
                pui_err("Failed to allocate memory for pui ani handle !\n");
-               return NULL;
+               goto err;
        }
 
        ani_h->ecore_event_hdls = NULL;
        _pui_ani_event_handlers_init(ani_h);
 
-       ani_mgr = (pui_ani_mgr *)calloc(1, sizeof(pui_ani_mgr));
+       ani = (pui_ani_t *)calloc(1, sizeof(pui_ani_t));
 
-       if (!ani_mgr)
+       if (!ani)
        {
                pui_err("Failed to allocate memory for pui ani mgr !\n");
                goto err;
        }
 
-       ani_mgr->ani_h = ani_h;
-       ani_mgr->id = id;
-       ani_mgr->status = PUI_ANI_STATUS_INITIAL;
-       ani_mgr->ani_func = ani_func;
+       ani->ani_h = ani_h;
+       ani->id = id;
+       ani->status = PUI_ANI_STATUS_INITIAL;
+       ani->ani_data = ani_data;
+
+       handle->ani_handles = eina_list_append(handle->ani_handles, ani_h);
 
        return ani_h;
 
 err:
+       if (ani_data)
+       {
+               handle->backend_module_data->ani_destroy(ani_data);
+       }
+
        if (ani_h)
                free(ani_h);
+
        return NULL;
 }
 
 void
 pui_ani_destroy(pui_ani_h ani_h)
 {
-       if (!ani_h)
+       pui_h handle = NULL;
+       pui_ani_t *ani = NULL;
+       pui_backend_module_data *backend_module_data = NULL;
+
+       if (!ani_h || !ani_h->pui_handle)
                return;
 
-       if (ani_h->ani_mgr->status != PUI_ANI_STATUS_STOPPED)
-               pui_ani_control(ani_h, PUI_ANI_CMD_STOP, PUI_ANI_OPT_NONE);
-       free(ani_h->ani_mgr);
+       handle = ani_h->pui_handle;
+       ani = ani_h->ani;
+
+       /* stop the animation being played already if any */
+       if (ani->status != PUI_ANI_STATUS_STOPPED)
+               pui_ani_control(ani_h, PUI_ANI_CMD_STOP, 0);
+
+       backend_module_data = handle->backend_module_data;
+       backend_module_data->ani_destroy(ani->ani_data);
+       ani->ani_data = NULL;
+
+       if (ani->frame_cb_timer)
+       {
+               ecore_timer_del(ani->frame_cb_timer);
+               ani->frame_cb_timer = NULL;
+       }
+
+       free(ani_h->ani);
 
        _pui_ani_event_handlers_shutdown(ani_h);
        
-       if (ani_h->frame_cb)
+       if (ani_h->frame_done_cb)
        {
-               ecore_wl2_window_frame_callback_del(ani_h->frame_cb);
-               ani_h->frame_cb = NULL;
+               ecore_wl2_window_frame_callback_del(ani_h->frame_done_cb);
+               ani_h->frame_done_cb = NULL;
        }
+
+       handle->ani_handles = eina_list_remove(handle->ani_handles, ani_h);
+
+       free(ani_h);
 }
 
index d985624..f3327e2 100644 (file)
@@ -1,13 +1,12 @@
-#include <PUI.h>
-#include "PUI_backend.h"
 #include "PUI_internal.h"
+#include "PUI_backend.h"
 
 pui_ani_control_buffer *
-pui_backend_ani_get_buffer(pui_ani_mgr *ani_mgr)
+pui_backend_ani_get_buffer(pui_ani_t *ani)
 {
        pui_ani_control_buffer *buffer = NULL;
 
-       buffer = pui_ani_get_buffer(ani_mgr->ani_h);
+       buffer = pui_ani_get_buffer(ani->ani_h);
 
        if (!buffer)
                return NULL;
@@ -16,66 +15,50 @@ pui_backend_ani_get_buffer(pui_ani_mgr *ani_mgr)
 }
 
 pui_int_error
-pui_backend_ani_set_buffer(pui_ani_mgr *ani_mgr, pui_ani_control_buffer *buffer)
+pui_backend_ani_set_buffer(pui_ani_t *ani, pui_ani_control_buffer *buffer)
 {
        pui_int_error err = PUI_INT_ERROR_NONE;
 
        if (!buffer)
                return PUI_INT_ERROR_INVALID_BUFFER;
 
-       err = pui_ani_set_buffer(ani_mgr->ani_h, buffer);
+       err = pui_ani_set_buffer(ani->ani_h, buffer);
 
        return err;
 }
 
 pui_int_error
-pui_backend_ani_update(pui_ani_mgr *ani_mgr)
+pui_backend_ani_update(pui_ani_t *ani)
 {
        pui_int_error err = PUI_INT_ERROR_NONE;
 
-       err = pui_ani_update(ani_mgr->ani_h);
+       err = pui_ani_update(ani->ani_h);
 
        return err;
 }
 
-void
-pui_backend_ani_add_frame_cb(pui_ani_mgr *ani_mgr, Eina_Bool (*frame_cb)(void *data), double expire, void *data)
+pui_ani_status
+pui_backend_ani_status_get(pui_ani_t *ani)
 {
-       Ecore_Timer *timer = NULL;
-
-       if (!ani_mgr)
-               return;
-
-       ani_mgr->frame_cb = frame_cb;
-       ani_mgr->expire = expire;
-       ani_mgr->frame_cb_data = data;
-
-       timer = ecore_timer_add(expire, (Ecore_Task_Cb)frame_cb, data);
-
-       if (ani_mgr->frame_cb_timer)
-       {
-               ecore_timer_del(ani_mgr->frame_cb_timer);
-               ani_mgr->frame_cb_timer = NULL;
-       }
-
-       ani_mgr->frame_cb_timer = timer;
+       return pui_ani_status_get(ani);
 }
 
 void
-pui_backend_ani_remove_frame_cb(pui_ani_mgr *ani_mgr, void *data)
+pui_backend_ani_add_frame_cb(pui_ani_t *ani, pui_bool (*frame_cb)(void *data, int serial), double frame_interval)
 {
-       if (!ani_mgr)
-               return;
+       pui_ani_add_frame_cb(ani, frame_cb, frame_interval);
+}
 
-       if (ani_mgr->frame_cb_timer)
-       {
-               ecore_timer_del(ani_mgr->frame_cb_timer);
-               ani_mgr->frame_cb_timer = NULL;
-       }
+void
+pui_backend_ani_remove_frame_cb(pui_ani_t *ani)
+{
+       pui_ani_remove_frame_cb(ani);
+}
 
-       ani_mgr->frame_cb = NULL;
-       ani_mgr->expire = 0;
-       ani_mgr->frame_cb_data = NULL;
+void
+pui_backend_ani_status_update(pui_ani_t *ani, pui_ani_status status)
+{
+       pui_ani_status_update(ani, status);
 }
 
 pui_backend_ani_func *
@@ -84,6 +67,7 @@ pui_backend_ani_alloc_ani_func(void)
        pui_backend_ani_func *ani_func = NULL;
 
        ani_func = (pui_backend_ani_func *)calloc(1, sizeof(pui_backend_ani_func));
+
        if (!ani_func)
        {
                pui_err("Failed to allocate memory !\n");
@@ -107,3 +91,9 @@ pui_backend_ani_free_ani_func(pui_backend_ani_func *ani_func)
        pui_info("Succeed to free memory !\n");
 }
 
+pui_backend_ani_data *
+pui_backend_ani_get_ani_data(pui_ani_t *ani)
+{
+       return pui_ani_get_ani_data(ani);
+}
+
diff --git a/src/PUI_common.h b/src/PUI_common.h
new file mode 100644 (file)
index 0000000..a8c02fd
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef _LIBPUI_COMMON_H_
+#define _LIBPUI_COMMON_H_
+
+typedef enum {
+       PUI_ERROR_NONE,
+       PUI_ERROR_INVALID_ANI_HANDLE,
+       PUI_ERROR_INVALID_ANI_CMD,
+       PUI_ERROR_INVALID_ANI_REPEAT,
+       PUI_ERROR_INTERNAL,
+} pui_error;
+
+typedef enum {
+       PUI_ANI_STATUS_INITIAL,
+       PUI_ANI_STATUS_UNKNOWN,
+       PUI_ANI_STATUS_STARTED,
+       PUI_ANI_STATUS_RUNNING,
+       PUI_ANI_STATUS_PAUSED,
+       PUI_ANI_STATUS_STOPPED,
+       PUI_ANI_STATUS_FORCE_STOPPED,
+} pui_ani_status;
+
+typedef enum {
+       PUI_ANI_CMD_NONE,
+       PUI_ANI_CMD_START,
+       PUI_ANI_CMD_STOP,
+       PUI_ANI_CMD_LAST,
+} pui_ani_cmd;
+
+typedef enum {
+       PUI_INT_ERROR_NONE,
+       PUI_INT_ERROR_INVALID_HANDLE,
+       PUI_INT_ERROR_INVALID_SURFACE,
+       PUI_INT_ERROR_INVALID_BUFFER,
+       PUI_INT_ERROR_ID_NOT_SUPPORTED,
+       PUI_INT_ERROR_INVALID_BACKEND_MGR,
+       PUI_INT_ERROR_NO_ANI_AVAILABLE,
+       PUI_INT_ERROR_BACKEND_FUNC_ERROR,
+} pui_int_error;
+
+typedef unsigned int pui_bool;
+typedef char* pui_id;
+typedef char* pui_error_string;
+typedef struct _pui * pui_h;
+typedef struct _pui_ani * pui_ani_h;
+typedef struct _pui_module_data pui_module_data;
+typedef struct _PUI_Event_Animation_Status PUI_Event_Animation_Status;
+
+typedef struct _pui_ani_control_buffer pui_ani_control_buffer;
+typedef struct _pui_ani_t pui_ani_t;
+typedef struct _pui_backend_ani_data pui_backend_ani_data;
+typedef struct _pui_backend_module_data pui_backend_module_data;
+typedef struct _pui_backend_module pui_backend_module;
+
+#define pui_err(msg, ...)                                                                              \
+       do {                                                                                                            \
+               fprintf(stderr, "[ERROR][%s] " msg, __FUNCTION__, ##__VA_ARGS__);       \
+       } while(0)
+
+#define pui_warn(msg, ...)                                                                             \
+               do {                                                                                                    \
+                       fprintf(stderr, "[WARNING][%s] " msg, __FUNCTION__, ##__VA_ARGS__);     \
+               } while(0)
+
+#define pui_info(msg, ...)                                                                             \
+       do {                                                                                                            \
+               fprintf(stdout, "[INFO][%s] " msg, __FUNCTION__, ##__VA_ARGS__);        \
+       } while(0)
+
+#endif//_LIBPUI_COMMON_H_
similarity index 53%
rename from include/PUI_internal.h
rename to src/PUI_internal.h
index 098d7a5..7d78fc9 100644 (file)
@@ -1,30 +1,19 @@
 #ifndef _LIBPUI_INTERNAL_H_
 #define _LIBPUI_INTERNAL_H_
 
-#include "PUI.h"
-#include "PUI_backend.h"
+#define EFL_BETA_API_SUPPORT
+
+#include <stdint.h>
+#include <Ecore_Wl2.h>
+#include <Eina.h>
+#include <wayland-tbm-client.h>
+#include <tbm_surface_internal.h>
+#include "PUI_common.h"
 
 #ifndef PATH_MAX
 #define PATH_MAX 4096
 #endif
 
-enum {
-       PUI_INT_ERROR_NONE,
-       PUI_INT_ERROR_INVALID_HANDLE,
-       PUI_INT_ERROR_INVALID_SURFACE,
-       PUI_INT_ERROR_INVALID_BUFFER,
-       PUI_INT_ERROR_ID_NOT_SUPPORTED,
-       PUI_INT_ERROR_INVALID_BACKEND_MGR,
-       PUI_NIT_ERROR_NO__ANI_AVAILABLE,
-       PUI_INT_ERROR_BACKEND_FUNC_ERROR,
-} pui_int_error;
-
-typedef struct _PUI_Event_Animation_Status
-{
-   unsigned int win;
-   pui_ani_status status;
-};
-
 struct _pui_ani_control_buffer
 {
        unsigned char *ptr;
@@ -34,32 +23,32 @@ struct _pui_ani_control_buffer
 struct _pui_ani
 {
        pui_h pui_handle;
-       pui_ani_mgr *ani_mgr;
+       pui_ani_t *ani;
 
        Eina_Array *ecore_event_hdls;
-       Ecore_Wl2_Frame_Cb_Handle *frame_cb;
+       Ecore_Wl2_Frame_Cb_Handle *frame_done_cb;
 
        pui_id id;
-       pui_ani_cmd cmd;
-       pui_ani_opt opt;
-       pui_ani_status status;
 };
 
-struct _pui_ani_mgr
+struct _pui_ani_t
 {
        pui_ani_h ani_h;
 
        pui_id id;
+       pui_ani_cmd cmd;
+       int repeat;
        pui_ani_status status;
 
-       pui_ani_control_buffer *buffer
+       int serial;
+       pui_ani_control_buffer *buffer;
 
        Eina_Bool (*frame_cb)(void *data);
+       pui_bool (*backend_frame_cb)(void *data, int serial);
        void *frame_cb_data;
-       double expire;
+       double frame_interval;
        Ecore_Timer *frame_cb_timer;
 
-       pui_backend_ani_func *ani_func;
        pui_backend_ani_data *ani_data;
 };
 
@@ -93,13 +82,28 @@ extern "C" {
 #endif
 
 pui_ani_control_buffer *
-get_buffer(pui_ani_h handle);
+pui_ani_get_buffer(pui_ani_h ani_h);
 
 pui_int_error
-set_buffer(pui_ani_h handle, pui_ani_control_buffer *buffer);
+pui_ani_set_buffer(pui_ani_h ani_h, pui_ani_control_buffer *buffer);
 
 pui_int_error
-pui_ani_update(pui_ani_h handle);
+pui_ani_update(pui_ani_h ani_h);
+
+void
+pui_ani_add_frame_cb(pui_ani_t *ani, pui_bool (*frame_cb)(void *data, int serial), double frame_interval);
+
+void
+pui_ani_remove_frame_cb(pui_ani_t *ani);
+
+void
+pui_ani_status_update(pui_ani_t *ani, pui_ani_status status);
+
+pui_ani_status
+pui_ani_status_get(pui_ani_t *ani);
+
+pui_backend_ani_data *
+pui_ani_get_ani_data(pui_ani_t *ani);
 
 #ifdef __cplusplus
 }