From a6bbe4b5e39a712a259cc9406da0dc68a0080124 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Wed, 7 Aug 2019 20:54:07 +0900 Subject: [PATCH] renew pui prototype again Change-Id: I0240934656a3e275ce702f4b3aa9c4b7f745137e Signed-off-by: Sung-Jin Park --- AUTHORS | 2 + COPYING | 26 +++ Makefile.am | 4 + autogen.sh | 9 + backends/Makefile.am | 15 ++ backends/default_backend.c | 220 ++++++++++++++---------- configure.ac | 77 +++++++++ include/PUI.h | 83 +++------- include/PUI_backend.h | 47 +++--- packaging/libpui.manifest | 5 + packaging/libpui.spec | 90 ++++++++++ pkgconfig/libpui.pc.in | 10 ++ samples/Makefile.am | 9 + samples/PUI_sample.c | 93 +++++------ src/Makefile.am | 19 +++ src/PUI.c | 76 +++------ src/PUI_ani.c | 358 +++++++++++++++++++++++++++++++--------- src/PUI_backend.c | 68 ++++---- src/PUI_common.h | 69 ++++++++ {include => src}/PUI_internal.h | 66 ++++---- 20 files changed, 922 insertions(+), 424 deletions(-) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100644 backends/Makefile.am create mode 100644 configure.ac create mode 100644 packaging/libpui.manifest create mode 100644 packaging/libpui.spec create mode 100644 pkgconfig/libpui.pc.in create mode 100644 samples/Makefile.am create mode 100644 src/Makefile.am create mode 100644 src/PUI_common.h rename {include => src}/PUI_internal.h (53%) diff --git a/AUTHORS b/AUTHORS new file mode 100644 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 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 index 0000000..bfabf5d --- /dev/null +++ b/Makefile.am @@ -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 index 0000000..916169a --- /dev/null +++ b/autogen.sh @@ -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 index 0000000..00db99b --- /dev/null +++ b/backends/Makefile.am @@ -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 diff --git a/backends/default_backend.c b/backends/default_backend.c index f0ca99d..ab13717 100644 --- a/backends/default_backend.c +++ b/backends/default_backend.c @@ -1,9 +1,9 @@ -#include +//#include +#include +#include #include -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 index 0000000..764b8f0 --- /dev/null +++ b/configure.ac @@ -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=], + [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=], + [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 diff --git a/include/PUI.h b/include/PUI.h index 42cafab..16275c2 100644 --- a/include/PUI.h +++ b/include/PUI.h @@ -1,59 +1,26 @@ #ifndef _LIBPUI_H_ #define _LIBPUI_H_ -#include "PUI_internal.h" -#include -#include -#include +#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 + +#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 } diff --git a/include/PUI_backend.h b/include/PUI_backend.h index 147066a..a39f197 100644 --- a/include/PUI_backend.h +++ b/include/PUI_backend.h @@ -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) \ @@ -16,15 +15,11 @@ #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) ; +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 index 0000000..017d22d --- /dev/null +++ b/packaging/libpui.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libpui.spec b/packaging/libpui.spec new file mode 100644 index 0000000..9052ecc --- /dev/null +++ b/packaging/libpui.spec @@ -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 index 0000000..0b9ba3a --- /dev/null +++ b/pkgconfig/libpui.pc.in @@ -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 index 0000000..d8170e8 --- /dev/null +++ b/samples/Makefile.am @@ -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 diff --git a/samples/PUI_sample.c b/samples/PUI_sample.c index cc4744d..359fd8e 100644 --- a/samples/PUI_sample.c +++ b/samples/PUI_sample.c @@ -1,7 +1,10 @@ #include -#include - #define NUM_ECORE_EVENT_HANDLERS 4 +#define EFL_BETA_API_SUPPORT + +#include +#include +#include #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 index 0000000..346e0c9 --- /dev/null +++ b/src/Makefile.am @@ -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 diff --git a/src/PUI.c b/src/PUI.c index c5e8a94..579faf2 100644 --- 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 +#include +#include +#include #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); diff --git a/src/PUI_ani.c b/src/PUI_ani.c index 2ac1d0d..6ed1b2d 100644 --- a/src/PUI_ani.c +++ b/src/PUI_ani.c @@ -1,5 +1,6 @@ -#include "PUI.h" #include "PUI_internal.h" +#include "PUI_backend.h" +#include "PUI.h" #include 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); } diff --git a/src/PUI_backend.c b/src/PUI_backend.c index d985624..f3327e2 100644 --- a/src/PUI_backend.c +++ b/src/PUI_backend.c @@ -1,13 +1,12 @@ -#include -#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 index 0000000..a8c02fd --- /dev/null +++ b/src/PUI_common.h @@ -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_ diff --git a/include/PUI_internal.h b/src/PUI_internal.h similarity index 53% rename from include/PUI_internal.h rename to src/PUI_internal.h index 098d7a5..7d78fc9 100644 --- a/include/PUI_internal.h +++ b/src/PUI_internal.h @@ -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 +#include +#include +#include +#include +#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 } -- 2.7.4