Initialize Tizen 2.3
authorSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 03:47:28 +0000 (12:47 +0900)
committerSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 03:47:28 +0000 (12:47 +0900)
20 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
TC/testcase/Makefile [new file with mode: 0644]
TC/testcase/tslist [new file with mode: 0644]
TC/testcase/utc_livebox.c [new file with mode: 0644]
data/CMakeLists.txt [new file with mode: 0644]
doc/livebox_doc.h [new file with mode: 0644]
include/debug.h [new file with mode: 0644]
include/dlist.h [new file with mode: 0644]
include/livebox.h [new file with mode: 0644]
include/util.h [new file with mode: 0644]
livebox.pc.in [new file with mode: 0644]
packaging/liblivebox.manifest [new file with mode: 0644]
packaging/liblivebox.spec [new file with mode: 0644]
src/dlist.c [new file with mode: 0644]
src/livebox.c [new file with mode: 0644]
src/snapshot_window.c [new file with mode: 0644]
src/util.c [new file with mode: 0644]
src/virtual_window.c [new file with mode: 0644]
src/virtual_window_wayland.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..44f73c1
--- /dev/null
@@ -0,0 +1,95 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(livebox C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(PROJECT_NAME "${PROJECT_NAME}")
+SET(LIBDIR "\${exec_prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}")
+SET(VERSION_MAJOR 0)
+SET(VERSION "${VERSION_MAJOR}.0.1")
+
+set(CMAKE_SKIP_BUILD_RPATH true)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+       dlog
+       livebox-service
+       provider
+       evas
+       ecore
+       elementary
+)
+
+IF (X11_SUPPORT)
+pkg_check_modules(pkgs_extra REQUIRED
+       x11
+)
+ADD_DEFINITIONS("-DHAVE_X11")
+SET(BUILD_SOURCE
+       src/virtual_window.c
+)
+ENDIF (X11_SUPPORT)
+
+IF (WAYLAND_SUPPORT)
+ADD_DEFINITIONS("-DHAVE_WAYLAND")
+SET(BUILD_SOURCE
+       src/virtual_window_wayland.c
+)
+ENDIF (WAYLAND_SUPPORT)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${pkgs_extra_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g")
+
+#ADD_DEFINITIONS("-Werror")
+#ADD_DEFINITIONS("-Wall")
+#ADD_DEFINITIONS("-Wextra")
+#ADD_DEFINITIONS("-ansi")
+#ADD_DEFINITIONS("-pedantic")
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"LIVEBOX\"")
+ADD_DEFINITIONS("-DNDEBUG")
+ADD_DEFINITIONS("-D_USE_ECORE_TIME_GET")
+ADD_DEFINITIONS("-DMASTER_PKGNAME=\"data-provider-master\"")
+ADD_DEFINITIONS("-DSLAVE_PKGNAME=\"org.tizen.data-provider-slave\"")
+
+IF (MOBILE)
+       ADD_DEFINITIONS("-DMOBILE")
+ELSEIF (WEARABLE)
+       ADD_DEFINITIONS("-DWEARABLE")
+       ADD_DEFINITIONS("-DENABLE_ACCESSIBILITY")
+ENDIF (MOBILE)
+
+SET (BUILD_SOURCE
+       ${BUILD_SOURCE}
+       src/dlist.c
+       src/livebox.c
+       src/util.c
+)
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${BUILD_SOURCE})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${pkgs_extra_LDFLAGS} "-lpthread")
+
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
+SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc")
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/livebox.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}")
+
+ADD_SUBDIRECTORY(data)
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..571fe79
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,206 @@
+Flora License
+
+Version 1.1, April, 2013
+
+http://floralicense.org/license/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction,
+and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by
+the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and
+all other entities that control, are controlled by, or are
+under common control with that entity. For the purposes of
+this definition, "control" means (i) the power, direct or indirect,
+to cause the direction or management of such entity,
+whether by contract or otherwise, or (ii) ownership of fifty percent (50%)
+or more of the outstanding shares, or (iii) beneficial ownership of
+such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity
+exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation source,
+and configuration files.
+
+"Object" form shall mean any form resulting from mechanical
+transformation or translation of a Source form, including but
+not limited to compiled object code, generated documentation,
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form,
+made available under the License, as indicated by a copyright notice
+that is included in or attached to the work (an example is provided
+in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form,
+that is based on (or derived from) the Work and for which the editorial
+revisions, annotations, elaborations, or other modifications represent,
+as a whole, an original work of authorship. For the purposes of this License,
+Derivative Works shall not include works that remain separable from,
+or merely link (or bind by name) to the interfaces of, the Work and
+Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original
+version of the Work and any modifications or additions to that Work or
+Derivative Works thereof, that is intentionally submitted to Licensor
+for inclusion in the Work by the copyright owner or by an individual or
+Legal Entity authorized to submit on behalf of the copyright owner.
+For the purposes of this definition, "submitted" means any form of
+electronic, verbal, or written communication sent to the Licensor or
+its representatives, including but not limited to communication on
+electronic mailing lists, source code control systems, and issue
+tracking systems that are managed by, or on behalf of, the Licensor
+for the purpose of discussing and improving the Work, but excluding
+communication that is conspicuously marked or otherwise designated
+in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity
+on behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.
+
+"Tizen Certified Platform" shall mean a software platform that complies
+with the standards set forth in the Tizen Compliance Specification
+and passes the Tizen Compliance Tests as defined from time to time
+by the Tizen Technical Steering Group and certified by the Tizen
+Association or its designated agent.
+
+2. Grant of Copyright License.  Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the
+Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License.  Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made,
+use, offer to sell, sell, import, and otherwise transfer the Work
+solely as incorporated into a Tizen Certified Platform, where such
+license applies only to those patent claims licensable by such
+Contributor that are necessarily infringed by their Contribution(s)
+alone or by combination of their Contribution(s) with the Work solely
+as incorporated into a Tizen Certified Platform to which such
+Contribution(s) was submitted. If You institute patent litigation
+against any entity (including a cross-claim or counterclaim
+in a lawsuit) alleging that the Work or a Contribution incorporated
+within the Work constitutes direct or contributory patent infringement,
+then any patent licenses granted to You under this License for that
+Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.  You may reproduce and distribute copies of the
+Work or Derivative Works thereof pursuant to the copyright license
+above, in any medium, with or without modifications, and in Source or
+Object form, provided that You meet the following conditions:
+
+  1. You must give any other recipients of the Work or Derivative Works
+     a copy of this License; and
+  2. You must cause any modified files to carry prominent notices stating
+     that You changed the files; and
+  3. You must retain, in the Source form of any Derivative Works that
+     You distribute, all copyright, patent, trademark, and attribution
+     notices from the Source form of the Work, excluding those notices
+     that do not pertain to any part of the Derivative Works; and
+  4. If the Work includes a "NOTICE" text file as part of its distribution,
+     then any Derivative Works that You distribute must include a readable
+     copy of the attribution notices contained within such NOTICE file,
+     excluding those notices that do not pertain to any part of
+     the Derivative Works, in at least one of the following places:
+     within a NOTICE text file distributed as part of the Derivative Works;
+     within the Source form or documentation, if provided along with the
+     Derivative Works; or, within a display generated by the Derivative Works,
+     if and wherever such third-party notices normally appear.
+     The contents of the NOTICE file are for informational purposes only
+     and do not modify the License. You may add Your own attribution notices 
+     within Derivative Works that You distribute, alongside or as an addendum 
+     to the NOTICE text from the Work, provided that such additional attribution 
+     notices cannot be construed as modifying the License. You may add Your own
+     copyright statement to Your modifications and may provide additional or
+     different license terms and conditions for use, reproduction, or
+     distribution of Your modifications, or for any such Derivative Works
+     as a whole, provided Your use, reproduction, and distribution of
+     the Work otherwise complies with the conditions stated in this License
+     and your own copyright statement or terms and conditions do not conflict
+     the conditions stated in the License including section 3.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+any Contribution intentionally submitted for inclusion in the Work
+by You to the Licensor shall be under the terms and conditions of
+this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify
+the terms of any separate license agreement you may have executed
+with Licensor regarding such Contributions.
+
+6. Trademarks.  This License does not grant permission to use the trade
+names, trademarks, service marks, or product names of the Licensor,
+except as required for reasonable and customary use in describing the
+origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+agreed to in writing, Licensor provides the Work (and each
+Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied, including, without limitation, any warranties or conditions
+of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any
+risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+whether in tort (including negligence), contract, or otherwise,
+unless required by applicable law (such as deliberate and grossly
+negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a
+result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill,
+work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses), even if such Contributor
+has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+the Work or Derivative Works thereof, You may choose to offer,
+and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this
+License. However, in accepting such obligations, You may act only
+on Your own behalf and on Your sole responsibility, not on behalf
+of any other Contributor, and only if You agree to indemnify,
+defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason
+of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Flora License to your work
+
+To apply the Flora License to your work, attach the following
+boilerplate notice, with the fields enclosed by brackets "[]"
+replaced with your own identifying information. (Don't include
+the brackets!) The text should be enclosed in the appropriate
+comment syntax for the file format. We also recommend that a
+file or class name and description of purpose be included on the
+same "printed page" as the copyright notice for easier
+identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Flora License, Version 1.1 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://floralicense.org/license/
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/TC/testcase/Makefile b/TC/testcase/Makefile
new file mode 100644 (file)
index 0000000..df6033d
--- /dev/null
@@ -0,0 +1,34 @@
+include ../config
+
+CC ?= gcc
+
+C_FILES = $(shell ls *.c)
+       
+PKGS = $(PKG_NAME)
+PKGS += glib-2.0
+PKGS += livebox-service
+PKGS += evas
+PKGS += ecore
+PKGS += elementary
+PKGS += dlog
+#PKGS += provider
+LDFLAGS = `pkg-config --libs $(PKGS)`
+LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o
+LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s
+LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s
+
+CFLAGS = -I. `pkg-config --cflags $(PKGS)`
+CFLAGS += -DTIZEN_ENGINEER_MODE
+CFLAGS += -DTIZEN_DEBUG_ENABLE
+CFLAGS += -I$(TET_ROOT)/inc/tet3
+CFLAGS += -Wall
+
+TCS := $(shell ls -1 *.c | cut -d. -f1)
+
+all: $(TCS)
+
+%: %.c
+       $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
+
+clean:
+       rm -f $(TCS)
diff --git a/TC/testcase/tslist b/TC/testcase/tslist
new file mode 100644 (file)
index 0000000..2fc5b2e
--- /dev/null
@@ -0,0 +1,2 @@
+/testcase/utc_livebox
+
diff --git a/TC/testcase/utc_livebox.c b/TC/testcase/utc_livebox.c
new file mode 100644 (file)
index 0000000..5c2edb2
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <tet_api.h>
+#include <stdlib.h>
+
+#define LOG_TAG "LIVEBOX_TC"
+
+#include <livebox-service.h>
+#include <livebox-errno.h>
+#include <livebox.h>
+#include <dlog.h>
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+static void startup(void)
+{
+       /* start of TC */
+       tet_printf("\n TC start");
+}
+
+
+static void cleanup(void)
+{
+       /* end of TC */
+       tet_printf("\n TC end");
+}
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+#define DUMMY_ID "/opt/usr/share/live_magazine/org.tizen.dummy.png"
+#define DUMMY_INVALID_ID "/usr/share/live_magazine/org.tizen.dummy.png"
+#define DUMMY_PKGNAME "org.tizen.dummy"
+
+static void utc_livebox_desc_open_n(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+
+       handle = livebox_desc_open(DUMMY_INVALID_ID, 0);
+       if (handle) {
+               (void)livebox_desc_close(handle);
+       }
+        dts_check_eq("livebox_desc_open", handle, NULL, "Must return NULL in case of invalid id is used"); 
+}
+
+static void utc_livebox_desc_open_p(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+        dts_check_ne("livebox_desc_open", handle, NULL, "Must return valid handle"); 
+}
+
+static void utc_livebox_desc_close_n(void)
+{
+       LOGD("");
+       int ret;
+
+       ret = livebox_desc_close(NULL);
+       dts_check_eq("livebox_desc_close", ret, LB_STATUS_ERROR_INVALID, "Must returns LB_STATUS_ERROR_INVALID");
+}
+
+static void utc_livebox_desc_close_p(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+       int ret;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+       if (!handle) {
+               dts_check_ne("livebox_desc_close", handle, NULL, "Failed to create a handle");
+               return;
+       }
+
+       ret = livebox_desc_close(handle);
+       dts_check_eq("livebox_desc_close", ret, LB_STATUS_SUCCESS, "Must returns LB_STATUS_SUCCESS");
+}
+
+static void utc_livebox_desc_set_category_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_desc_set_category(NULL, NULL, NULL);
+
+       dts_check_eq("livebox_desc_set_category", ret, LB_STATUS_ERROR_INVALID, "Invalid parameter used, LB_STATUS_ERROR_INVALID should be returned");
+}
+
+static void utc_livebox_desc_set_category_p(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+       int ret;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+       if (!handle) {
+               dts_check_ne("livebox_desc_set_category", handle, NULL, "Failed to create a handle");
+               return;
+       }
+
+       ret = livebox_desc_set_category(handle, NULL, "New Category");
+       (void)livebox_desc_close(handle);
+       dts_check_eq("livebox_desc_set_category", ret, LB_STATUS_SUCCESS, "LB_STATUS_SUCCESS should be returned\n");
+}
+
+static void utc_livebox_desc_set_id_n(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+       int ret;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+       if (!handle) {
+               dts_check_ne("livebox_desc_set_id", handle, NULL, "Failed to create a handle");
+               return;
+       }
+       ret = livebox_desc_set_id(handle, -1, NULL);
+       (void)livebox_desc_close(handle);
+       dts_check_eq("livebox_desc_set_id", ret, LB_STATUS_ERROR_NOT_EXIST, "LB_STATUS_ERROR_NOT_EXIST should be returned\n");
+}
+
+static void utc_livebox_desc_set_id_p(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+       int ret;
+       int idx;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+       if (!handle) {
+               dts_check_ne("livebox_desc_set_id", handle, NULL, "Failed to create a handle");
+               return;
+       }
+       idx = livebox_desc_add_block(handle, NULL, LB_DESC_TYPE_SCRIPT, "swallow,part", "/usr/apps/org.tizen.test-app/res/edje/test.edj", "test,group");
+       if (idx < 0) {
+               dts_check_ge("livebox_desc_set_id", idx, 0, "Failed to add a desc block");
+               (void)livebox_desc_close(handle);
+               return;
+       }
+
+       ret = livebox_desc_set_id(handle, idx, "new,id");
+       (void)livebox_desc_close(handle);
+       dts_check_eq("livebox_desc_set_id", ret, LB_STATUS_SUCCESS, "LB_STATUS_SUCCESS should be returned\n");
+}
+
+static void utc_livebox_desc_add_block_n(void)
+{
+       LOGD("");
+       int idx;
+
+       idx = livebox_desc_add_block(NULL, NULL, LB_DESC_TYPE_SCRIPT, "swallow,part", "/usr/apps/org.tizen.test-app/res/edje/test.edj", "test,group");
+       dts_check_eq("livebox_desc_add_block", idx, LB_STATUS_ERROR_INVALID, "LB_STATUS_ERROR_INVALID should be returned\n");
+}
+
+static void utc_livebox_desc_add_block_p(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+       int idx;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+       if (!handle) {
+               dts_check_ne("livebox_desc_add_block", handle, NULL, "Failed to create a handle");
+               return;
+       }
+
+       idx = livebox_desc_add_block(handle, NULL, LB_DESC_TYPE_SCRIPT, "swallow,part", "/usr/apps/org.tizen.test-app/res/edje/test.edj", "test,group");
+       dts_check_ge("livebox_desc_add_block", idx, 0, "idx should not be less than 0\n");
+       (void)livebox_desc_close(handle);
+}
+
+static void utc_livebox_desc_del_block_n(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+       int ret;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+       if (!handle) {
+               dts_check_ne("livebox_desc_del_block", handle, NULL, "Failed to create a handle");
+               return;
+       }
+
+       ret = livebox_desc_del_block(handle, 0);
+       dts_check_eq("livebox_desc_del_block", ret, LB_STATUS_ERROR_NOT_EXIST, "Block is not found, LB_STATUS_ERROR_NOT_EXIST should be returned\n");
+}
+
+static void utc_livebox_desc_del_block_p(void)
+{
+       LOGD("");
+       struct livebox_desc *handle;
+       int idx;
+       int ret;
+
+       handle = livebox_desc_open(DUMMY_ID, 0);
+       if (handle == NULL) {
+               dts_check_ne("livebox_desc_del_block", handle, NULL, "Failed to create desc handle");
+               return;
+       }
+       idx = livebox_desc_add_block(handle, NULL, LB_DESC_TYPE_SCRIPT, "swallow,part", "/usr/apps/org.tizen.test-app/res/edje/test.edj", "test,group");
+       if (idx < 0) {
+               dts_check_ge("livebox_desc_del_block", idx, 0, "Failed to add a desc block");
+               (void)livebox_desc_close(handle);
+               return;
+       }
+       ret = livebox_desc_del_block(handle, idx);
+       (void)livebox_desc_close(handle);
+       dts_check_eq("livebox_desc_del_block", ret, LB_STATUS_SUCCESS, "del_block should returns LB_STATUS_SUCCESS\n");
+}
+
+int livebox_trigger_update_monitor(const char *id, int is_pd)
+{
+       if (!id) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+static void utc_livebox_content_is_updated_n(void)
+{
+       LOGD("");
+       int ret;
+
+       ret = livebox_content_is_updated(NULL, 0);
+       dts_check_eq("livebox_content_is_updated", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_content_is_updated_p(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_content_is_updated(DUMMY_ID, 0);
+       dts_check_eq("livebox_content_is_updated", ret, LB_STATUS_SUCCESS, "should returns LB_STATUS_SUCCESS\n");
+}
+
+static void utc_livebox_request_close_pd_n(void)
+{
+       LOGD("");
+       int ret;
+
+       ret = livebox_request_close_pd(DUMMY_PKGNAME, DUMMY_ID, LB_STATUS_SUCCESS);
+       dts_check_eq("livebox_request_close_pd", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_request_close_pd_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_request_close_pd", "pass negative test");
+}
+
+static void utc_livebox_request_update_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_request_update(NULL);
+       dts_check_eq("livebox_request_update", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID");
+}
+
+static void utc_livebox_request_update_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_request_update", "pass negative test");
+}
+
+static void utc_livebox_util_nl2br_n(void)
+{
+       LOGD("");
+       char *nl2br;
+
+       nl2br = livebox_util_nl2br(NULL);
+       dts_check_eq("livebox_util_nl2br", nl2br, NULL, "should returns NULL\n");
+}
+
+static void utc_livebox_util_nl2br_p(void)
+{
+       LOGD("");
+       char *nl2br;
+       nl2br = livebox_util_nl2br("hello\nworld");
+       LOGD("[%s]", nl2br);
+       dts_check_str_eq("livebox_util_nl2br", nl2br, "hello<br>world", "should returns \"hello<br>world\"");
+       LOGD("");
+}
+
+static void utc_livebox_acquire_buffer_n(void)
+{
+       LOGD("");
+       struct livebox_buffer *handle;
+
+       handle = livebox_acquire_buffer(NULL, 0, 720, 200, NULL, NULL);
+       dts_check_eq("livebox_acquire_buffer", handle, NULL, "should returns NULL\n");
+}
+
+static void utc_livebox_acquire_buffer_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_acquire_buffer", "pass positive test");
+}
+
+static void utc_livebox_acquire_buffer_NEW_n(void)
+{
+       LOGD("");
+       struct livebox_buffer *handle;
+
+       handle = livebox_acquire_buffer_NEW(NULL, 0, 720, 200, NULL, NULL);
+       dts_check_eq("livebox_acquire_buffer_NEW", handle, NULL, "should returns NULL\n");
+}
+
+static void utc_livebox_acquire_buffer_NEW_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_acquire_buffer_NEW", "pass positive test");
+}
+
+
+static void utc_livebox_pixmap_id_n(void)
+{
+       LOGD("");
+       unsigned long pixmap;
+
+       pixmap = livebox_pixmap_id(NULL);
+       dts_check_eq("livebox_pixmap_id", pixmap, 0, "should returns 0\n");
+}
+
+static void utc_livebox_pixmap_id_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_pixmap_id", "pass positive test");
+}
+
+static void utc_livebox_ref_buffer_n(void)
+{
+       LOGD("");
+       void *ret;
+       ret = livebox_ref_buffer(NULL);
+       dts_check_eq("livebox_ref_buffer", ret, NULL, "should returns NULL\n");
+}
+
+static void utc_livebox_ref_buffer_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_ref_buffer", "pass positive test");
+}
+
+static void utc_livebox_sync_buffer_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_sync_buffer(NULL);
+       dts_check_eq("livebox_sync_buffer", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_sync_buffer_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_sync_buffer", "pass positive test");
+}
+
+static void utc_livebox_support_hw_buffer_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_support_hw_buffer(NULL);
+       dts_check_eq("livebox_support_hw_buffer", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_support_hw_buffer_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_support_hw_buffer", "pass positive test");
+}
+
+static void utc_livebox_create_hw_buffer_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_create_hw_buffer(NULL);
+       dts_check_eq("livebox_create_hw_buffer", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_create_hw_buffer_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_create_hw_buffer", "pass positive test");
+}
+
+static void utc_livebox_destroy_hw_buffer_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_destroy_hw_buffer(NULL);
+       dts_check_eq("livebox_destroy_hw_buffer", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_destroy_hw_buffer_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_destroy_hw_buffer", "pass positive test");
+}
+
+static void utc_livebox_buffer_hw_buffer_n(void)
+{
+       LOGD("");
+       void *ret;
+       ret = livebox_buffer_hw_buffer(NULL);
+       dts_check_eq("livebox_buffer_hw_buffer", ret, NULL, "should returns LB_STATUS_ERROR_INVALID");
+}
+
+static void utc_livebox_buffer_hw_buffer_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_buffer_hw_buffer", "pass positive test");
+}
+
+static void utc_livebox_buffer_pre_render_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_buffer_pre_render(NULL);
+       dts_check_eq("livebox_buffer_pre_render", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_buffer_pre_render_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_buffer_pre_render", "pass positive test");
+}
+
+static void utc_livebox_buffer_post_render_n(void)
+{
+       LOGD("");
+       int ret;
+       ret = livebox_buffer_post_render(NULL);
+       dts_check_eq("livebox_buffer_post_render", ret, LB_STATUS_ERROR_INVALID, "should returns LB_STATUS_ERROR_INVALID\n");
+}
+
+static void utc_livebox_buffer_post_render_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_buffer_post_render", "pass positive test");
+}
+
+static void utc_livebox_get_evas_object_n(void)
+{
+       LOGD("");
+       Evas_Object *obj;
+
+       obj = livebox_get_evas_object(NULL, 1);
+       dts_check_eq("livebox_get_evas_object", obj, NULL, "should returns NULL\n");
+}
+
+static void utc_livebox_get_evas_object_p(void)
+{
+       LOGD("");
+       /*!
+        * \note
+        * Unable to test the positive case
+        */
+       dts_pass("livebox_get_evas_object", "pass positve test");
+}
+
+struct tet_testlist tet_testlist[] = {
+       { utc_livebox_desc_open_n, NEGATIVE_TC_IDX },                        
+       { utc_livebox_desc_open_p, POSITIVE_TC_IDX },
+       { utc_livebox_desc_close_n, NEGATIVE_TC_IDX },
+       { utc_livebox_desc_close_p, POSITIVE_TC_IDX },  
+       { utc_livebox_desc_set_category_n, NEGATIVE_TC_IDX },   
+       { utc_livebox_desc_set_category_p, POSITIVE_TC_IDX },
+       { utc_livebox_desc_set_id_n, NEGATIVE_TC_IDX },
+       { utc_livebox_desc_set_id_p, POSITIVE_TC_IDX },
+       { utc_livebox_desc_add_block_n, NEGATIVE_TC_IDX },      
+       { utc_livebox_desc_add_block_p, POSITIVE_TC_IDX },
+       { utc_livebox_desc_del_block_n, NEGATIVE_TC_IDX },
+       { utc_livebox_desc_del_block_p, POSITIVE_TC_IDX },
+       { utc_livebox_content_is_updated_n, NEGATIVE_TC_IDX },
+       { utc_livebox_content_is_updated_p, POSITIVE_TC_IDX },
+       { utc_livebox_request_close_pd_n, NEGATIVE_TC_IDX },
+       { utc_livebox_request_close_pd_p, POSITIVE_TC_IDX },
+       { utc_livebox_request_update_n, NEGATIVE_TC_IDX },
+       { utc_livebox_request_update_p, POSITIVE_TC_IDX },
+       { utc_livebox_util_nl2br_n, NEGATIVE_TC_IDX },
+       { utc_livebox_util_nl2br_p, POSITIVE_TC_IDX },
+
+       { utc_livebox_acquire_buffer_n, NEGATIVE_TC_IDX },
+       { utc_livebox_acquire_buffer_p, POSITIVE_TC_IDX },
+       { utc_livebox_acquire_buffer_NEW_n, NEGATIVE_TC_IDX },
+       { utc_livebox_acquire_buffer_NEW_p, POSITIVE_TC_IDX },
+
+       { utc_livebox_pixmap_id_n, NEGATIVE_TC_IDX },
+       { utc_livebox_pixmap_id_p, POSITIVE_TC_IDX },
+
+       { utc_livebox_ref_buffer_n, NEGATIVE_TC_IDX },
+       { utc_livebox_ref_buffer_p, POSITIVE_TC_IDX },
+
+       { utc_livebox_sync_buffer_n, NEGATIVE_TC_IDX },
+       { utc_livebox_sync_buffer_p, POSITIVE_TC_IDX },
+
+       { utc_livebox_support_hw_buffer_n, NEGATIVE_TC_IDX },
+       { utc_livebox_support_hw_buffer_p, POSITIVE_TC_IDX },
+       { utc_livebox_create_hw_buffer_n, NEGATIVE_TC_IDX },
+       { utc_livebox_create_hw_buffer_p, POSITIVE_TC_IDX },
+       { utc_livebox_destroy_hw_buffer_n, NEGATIVE_TC_IDX },
+       { utc_livebox_destroy_hw_buffer_p, POSITIVE_TC_IDX },
+       { utc_livebox_buffer_hw_buffer_n, NEGATIVE_TC_IDX },
+       { utc_livebox_buffer_hw_buffer_p, POSITIVE_TC_IDX },
+       { utc_livebox_buffer_pre_render_n, NEGATIVE_TC_IDX },
+       { utc_livebox_buffer_pre_render_p, POSITIVE_TC_IDX },
+       { utc_livebox_buffer_post_render_n, NEGATIVE_TC_IDX },
+       { utc_livebox_buffer_post_render_p, POSITIVE_TC_IDX },
+       { utc_livebox_get_evas_object_n, NEGATIVE_TC_IDX },
+       { utc_livebox_get_evas_object_p, POSITIVE_TC_IDX },
+
+       { NULL, 0 },
+};
+
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/doc/livebox_doc.h b/doc/livebox_doc.h
new file mode 100644 (file)
index 0000000..4b21f45
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @ingroup CORE_LIB_GROUP
+ * @defgroup CAPI_LIVEBOX_FRAMEWORK Livebox
+ */
+
+/**
+ * \ingroup CAPI_LIVEBOX_FRAMEWORK
+ * \defgroup CAPI_LIVEBOX_HELPER_MODULE Livebox Helper
+ * \brief This helper library only can be used for Inhouse(EFL) liveboxes.
+ * \section CAPI_LIVEBOX_HELPER_MODULE_HEADER Required Header
+ * \#include <livebox.h>
+ * \section CAPI_LIVEBOX_HELPER_MODULE_OVERVIEW Overview
+ * Help the inhouse(EFL) Livebox developer to generate description data formally.
+ * This API set is only be able to used data-provider-slave process.
+ * Because some API should be linked with it while loading.
+ */
diff --git a/include/debug.h b/include/debug.h
new file mode 100644 (file)
index 0000000..d278fc4
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DbgPrint(format, arg...)       SECURE_LOGD(format, ##arg)
+#define ErrPrint(format, arg...)       SECURE_LOGE(format, ##arg)
+#define WarnPrint(format, arg...)      SECURE_LOGW(format, ##arg)
+/* End of a file */
diff --git a/include/dlist.h b/include/dlist.h
new file mode 100644 (file)
index 0000000..6ce75e0
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define dlist_remove_data(list, data) do { \
+       struct dlist *l; \
+       l = dlist_find_data(list, data); \
+       list = dlist_remove(list, l); \
+} while (0)
+
+#define dlist_foreach(list, l, data) \
+       for ((l) = (list); ((data) = dlist_data(l)); (l) = dlist_next(l))
+
+#define dlist_foreach_safe(list, l, n, data) \
+       for ((l) = (list), (n) = dlist_next(l); \
+               ((data) = dlist_data(l)); \
+               (l) = (n), (n) = dlist_next(l))
+
+struct dlist;
+
+extern struct dlist *dlist_append(struct dlist *list, void *data);
+extern struct dlist *dlist_prepend(struct dlist *list, void *data);
+extern struct dlist *dlist_remove(struct dlist *list, struct dlist *l);
+extern struct dlist *dlist_find_data(struct dlist *list, void *data);
+extern void *dlist_data(struct dlist *l);
+extern struct dlist *dlist_next(struct dlist *l);
+extern struct dlist *dlist_prev(struct dlist *l);
+extern int dlist_count(struct dlist *l);
+extern struct dlist *dlist_nth(struct dlist *l, int nth);
+
+/* End of a file */
diff --git a/include/livebox.h b/include/livebox.h
new file mode 100644 (file)
index 0000000..4baf9f5
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LIVEBOX_HELPER_H
+#define __LIVEBOX_HELPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Evas.h>
+
+/**
+ * \addtogroup CAPI_LIVEBOX_HELPER_MODULE
+ * \{
+ */
+
+/*!
+ * \brief Defined by provider
+ */
+struct livebox_buffer;
+
+/*!
+ * \brief
+ * Return values of livebox programming interfaces.
+ */
+/*!
+ * \brief
+ * Operation is successfully done
+ */
+extern const int DONE;
+
+/*!
+ * \brief
+ * Contents is updated
+ */
+extern const int OUTPUT_UPDATED;
+
+/*!
+ * \brief
+ * Need to call the livebox_need_to_update and livebox_update_content
+ */
+extern const int NEED_TO_SCHEDULE;
+
+/*!
+ * Need to do force update
+ */
+extern const int FORCE_TO_SCHEDULE;
+
+/*!
+ * \brief
+ * Need to create a new instance
+ */
+extern const int NEED_TO_CREATE;
+
+/*!
+ * \brief
+ * Need to destroy this instance
+ */
+extern const int NEED_TO_DESTROY;
+
+/*!
+ * \brief
+ * Need to update
+ */
+extern const int NEED_TO_UPDATE;
+
+/*!
+ * \brief
+ * Using network
+ */
+extern const int USE_NET;
+
+/*!
+ * \brief
+ * System font is changed
+ */
+extern const int LB_SYS_EVENT_FONT_CHANGED;
+
+/*!
+ * \brief
+ * System language is changed
+ */
+extern const int LB_SYS_EVENT_LANG_CHANGED;
+
+/*!
+ * \brief
+ * System time is changed
+ */
+extern const int LB_SYS_EVENT_TIME_CHANGED;
+
+/*!
+ * \brief
+ * Region changed
+ */
+extern const int LB_SYS_EVENT_REGION_CHANGED;
+
+/*!
+ * \brief
+ * Livebox is paused
+ */
+extern const int LB_SYS_EVENT_PAUSED;
+
+/*!
+ * \brief
+ * Livebox is resumed
+ */
+extern const int LB_SYS_EVENT_RESUMED;
+
+/*!
+ * \brief
+ * MMC Status change event
+ */
+extern const int LB_SYS_EVENT_MMC_STATUS_CHANGED;
+
+/*!
+ * \brief
+ * COLOR BLOCK
+ */
+#define LB_DESC_TYPE_COLOR "color"
+
+/*!
+ * \brief
+ * TEXT BLOCK
+ */
+#define LB_DESC_TYPE_TEXT "text"
+
+/*!
+ * \brief
+ * IMAGE BLOCK
+ */
+#define LB_DESC_TYPE_IMAGE "image"
+
+/*!
+ * \brief
+ * SIGNAL BLOCK
+ */
+#define LB_DESC_TYPE_SIGNAL "signal"
+
+/*!
+ * \brief
+ * INFO BLOCK
+ */
+#define LB_DESC_TYPE_INFO "info"
+
+/*!
+ * \brief
+ * DRAG BLOCK
+ */
+#define LB_DESC_TYPE_DRAG "drag"
+
+/*!
+ * \brief
+ * SCRIPT SCRIPT
+ */
+#define LB_DESC_TYPE_SCRIPT "script"
+
+/*!
+ * \brief
+ * ACCESSIBILITY INFORMATION BLOCK
+ */
+#define LB_DESC_TYPE_ACCESS "access"
+
+/*!
+ * \brief
+ * Accessibility operation.
+ */
+#define LB_DESC_TYPE_ACCESS_OPERATION  "access,operation"
+
+/*!
+ * \brief
+ * Set highlight on specified part
+ */
+#define LB_DESC_DATA_ACCESS_OPERATION_HL_SET "set,hl"
+
+/*!
+ * \brief
+ * Remove highlight from specified part
+ */
+#define LB_DESC_DATA_ACCESS_OPERATION_HL_UNSET "unset,hl"
+
+/*!
+ * \brief
+ * Move the highlight to next part
+ */
+#define LB_DESC_DATA_ACCESS_OPERATION_HL_NEXT "next,hl"
+
+/*!
+ * \brief
+ * Move the highlight to previous part
+ */
+#define LB_DESC_DATA_ACCESS_OPERATION_HL_PREV "prev,hl"
+
+/*!
+ * \brief
+ * Reset the chain of accessibility highlight list.
+ */
+#define LB_DESC_DATA_ACCESS_OPERATION_RESET "reset,focus"
+
+/*!
+ * \brief
+ * Specify the highligt move option.
+ * If the highlight list reaches to the last object, move back to the first object.
+ */
+#define LB_DESC_OPTION_ACCESS_HL_LOOP "cycle"
+
+/*!
+ * \brief
+ * [Default] Specify the highlight move option.
+ * If the highlight list reaches to the last object(or the first object),
+ * the "prev,hl", "next,hl" will be failed.
+ */
+#define LB_DESC_OPTION_ACCESS_HL_NOLOOP "no,cycle"
+
+/*!
+ * \brief
+ * Extra event informatino for livebox_content_event interface function
+ */
+#ifndef __PROVIDER_H
+struct event_info {
+       struct {
+               double x;
+               double y;
+               int down;
+       } pointer; /*!< Down/Up state and mouse position */
+
+       struct {
+               double sx;
+               double sy;
+               double ex;
+               double ey;
+       } part; /*!< Geometry of event received part */
+};
+#endif
+
+/*!
+ * Livebox description data handle structure.
+ */
+struct livebox_desc;
+
+/*!
+ * \brief Update a description file.
+ * \details explain api more detail
+ * \remarks must be used only by Inhouse livebox
+ * \param[in] filename
+ * \param[in] for_pd
+ * \return handle
+ * \retval Handle of desc instance
+ * \pre Should be loaded by data-provider-slave
+ * \post Should be destroyed(flushed) using livebox_desc_close API
+ * \see livebox_desc_close
+ */
+extern struct livebox_desc *livebox_desc_open(const char *filename, int for_pd);
+
+/*!
+ * \brief Complete the description file updating
+ * \details Only if this API is called, the description data will be applied to the content of livebox(or PD).
+ * \remarks must be used only by Inhouse livebox
+ * \param[in] handle Handle which is created by livebox_desc_open function
+ * \return int
+ * \retval LB_STATUS_SUCCESS If the flushing description data is successfully done.
+ * \retval LB_STATUS_ERROR_INVALID If the given handle is not valid.
+ * \pre handle must be created by livebox_desc_open
+ * \post Handle must not be used after return from this function
+ * \see livebox_desc_open
+ */
+extern int livebox_desc_close(struct livebox_desc *handle);
+
+/*!
+ * \brief
+ *    Set the category information of current description data
+ * \details
+ *    Create a new description block for updating category information of layout object
+ * \remarks N/A
+ * \param[in] handle Handle which is created by livebox_desc_open function
+ * \param[in] id Id string of target object.
+ * \param[in] category Category string that will be used by layout object
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Invalid handle
+ * \retval LB_STATUS_ERROR_MEMORY Memory is not enough to add this block
+ * \retval index Index(>=0) of added block, which can be used by livebox_desc_set_id
+ * \pre Must be called after create a handle using livebox_desc_open.
+ * \post N/A
+ * \see livebox_desc_set_id
+ */
+extern int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category);
+
+/*!
+ * \brief
+ *    Set the content size
+ * \details
+ *    Set the content size of layout
+ * \remarks N/A
+ * \param[in] handle Handle which is created by livebox_desc_open function
+ * \param[in] id Id string of target object.
+ * \param[in] w Width in pixel
+ * \param[in] h Height in pixel
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \retval LB_STATUS_ERROR_MEMORY Not enough memory to add a new block
+ * \retval index Index(>=0) of added block Successfully added
+ * \pre N/A
+ * \post N/A
+ * \see livebox_desc_open
+ * \see livebox_desc_set_id
+ */
+extern int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h);
+
+/*!
+ * \brief
+ *    Set the target id of given block
+ *    Only available for the script block
+ * \details
+ *    N/A
+ * \remarks N/A
+ * \param[in] handle Handle which is created by livebox_desc_open function
+ * \param[in] idx Index of target block
+ * \param[in] id Id String which will be used by other livebox_desc_XXX functions
+ * \return int
+ * \retval LB_STATUS_SUCCESS Id is successfully updated for given idx of desc block
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \retval LB_STATUS_ERROR_NOT_EXIST Given index of desc block is not exists
+ * \pre desc block should be exists which has given index "idx"
+ * \post specified Id string("id") can be used by other livebox_desc_XXXX functions
+ * \see livebox_desc_open
+ * \see livebox_desc_set_id
+ */
+extern int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id);
+
+/*!
+ * \brief Add a new block
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Handle which is created by livebox_desc_open function
+ * \param[in] id ID of source script object
+ * \param[in] type image|text|script|signal|...
+ * \param[in] part target part to update with given content(data)
+ * \param[in] data content for specified part
+ * \param[in] option option for the block. (script: group, image: option, ...)
+ * \return idx Index of current description block
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \retval LB_STATUS_ERROR_MEMORY Not enough memory to add a new desc block
+ * \retval Index index(>=0) of added desc block
+ * \pre handle must be created using livebox_desc_open
+ * \post N/A
+ * \see livebox_desc_set_id
+ * \see livebox_desc_del_block
+ */
+extern int livebox_desc_add_block(struct livebox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option);
+
+/*!
+ * \brief Delete a added block
+ * \details
+ *    If you discard the added desc block, use this API and the index of created desc block.
+ * \remarks N/A
+ * \param[in] handle Handle which is created by livebox_desc_open function
+ * \param[in] idx Index of added block, returned from livebox_desc_add_block, livebox_desc_set_size, livebox_desc_set_category, ...
+ * \return int
+ * \retval LB_STATUS_SUCCESS Successfully deleted
+ * \retval LB_STATUS_ERROR_NOT_EXIST Given index of desc block is not exists
+ * \pre index must be exists.
+ * \post N/A
+ * \see livebox_desc_add_block
+ * \see livebox_desc_open
+ */
+extern int livebox_desc_del_block(struct livebox_desc *handle, int idx);
+
+/*!
+ * \brief Notify the updated content to the provider.
+ * \details
+ *    Forcely notify the updated contents.
+ *    This function can be used from async callback function to notify the updated content.
+ * \remarks N/A
+ * \param[in] id Instance Id which is passed to you via the first parameter of every livebox_XXXX interface functions.
+ * \param[in] is_pd 1 for updating content of PD or 0(for content of LB).
+ * \return int
+ * \retval LB_STATUS_ERROR_MEMORY Not enough memory
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \retval LB_STATUS_ERROR_IO I/O failed, Cannot access given resource file(id)
+ * \retval LB_STATUS_SUCCESS Successfully notified
+ * \pre This API only can be used after loaded into the data-provider-slave process.
+ * \post N/A
+ * \see N/A
+ */
+extern int livebox_content_is_updated(const char *id, int is_pd);
+
+/*!
+ * \brief Replace "\n"(new line character) with &lt;br&gt;
+ * \details
+ *    This utility function is used to replace all NEW LINE CHARACTER("\n") with &lt;br&gt; tag.
+ * \remarks N/A
+ * \param[in] str Source string
+ * \return char *
+ * \retval String that is allocted in the heap
+ * \retval NULL if it fails to replace string
+ * \pre N/A
+ * \post Returned string must has to be free'd by user manually.
+ * \see N/A
+ */
+extern char *livebox_util_nl2br(const char *str);
+
+
+/*!
+ * \brief
+ * Interfaces for direct buffer management (Available only for the PD area)
+ */
+#ifndef __PROVIDER_BUFFER_H
+/*!
+ * \note
+ * This enumeration value should be sync'd with provider
+ */
+enum buffer_event {
+       BUFFER_EVENT_ENTER, /*!< Mouse cursor enter */
+       BUFFER_EVENT_LEAVE, /*!< Mouse cursor leave */
+       BUFFER_EVENT_DOWN, /*!< Mouse down */
+       BUFFER_EVENT_MOVE, /*!< Mouse move */
+       BUFFER_EVENT_UP, /*!< Mouse up */
+
+       BUFFER_EVENT_KEY_DOWN, /*!< Key down */
+       BUFFER_EVENT_KEY_UP, /*!< Key up */
+       BUFFER_EVENT_KEY_FOCUS_IN, /*!< Key focus in */
+       BUFFER_EVENT_KEY_FOCUS_OUT, /*!< Key focus out */
+
+       BUFFER_EVENT_HIGHLIGHT, /*!< Accessibility - Highlight */
+       BUFFER_EVENT_HIGHLIGHT_NEXT, /*!< Accessibility - Move highlight to next */
+       BUFFER_EVENT_HIGHLIGHT_PREV, /*!< Accessibility - Move highlight to prev */
+       BUFFER_EVENT_ACTIVATE, /*!< Accessibility - Activate the highlighted object */
+       BUFFER_EVENT_ACTION_UP, /*!< Accessibility - Make UP action */
+       BUFFER_EVENT_ACTION_DOWN, /*!< Accessibility - Make Down action */
+       BUFFER_EVENT_SCROLL_UP, /*!< Accessibility - Scroll up */
+       BUFFER_EVENT_SCROLL_MOVE, /*!< Accessibility - Scroll move */
+       BUFFER_EVENT_SCROLL_DOWN, /*!< Accessibility - Scroll down */
+       BUFFER_EVENT_UNHIGHLIGHT, /*!< Accessibility - Remove highlight */
+
+       BUFFER_EVENT_ON_HOLD,   /*!< To prevent from generating mouse clicked event */
+       BUFFER_EVENT_OFF_HOLD,  /*!< Stopped holding. */
+       BUFFER_EVENT_ON_SCROLL, /*!< On scrolling */
+       BUFFER_EVENT_OFF_SCROLL /*!< Scrolling stopped */
+};
+
+struct buffer_event_data {
+       enum buffer_event type; /*!< Mouse, Keyboard, Accessibility event type */
+       double timestamp; /*!< Timestamp of events */
+
+       union input_data {
+               struct mouse {
+                       int x; /*!< If the event type is for accessibility or mouse, coordinates of X for pointer */
+                       int y; /*!< If the event type is for accessibility or mouse, coordinates of Y for pointer */
+               } pointer;
+
+               unsigned int keycode; /*!< If the event type is for keyboard, the value of keycode */
+       } info;
+};
+#endif
+
+/*!
+ * \brief
+ *    Acquire a buffer for PD or LB, Currently, we only supporting the PD.
+ * \details N/A
+ * \remarks N/A
+ * \param[in] id Id of a livebox instance
+ * \param[in] is_pd 1 for PD or 0 for livebox
+ * \param[in] width Width in pixel
+ * \param[in] height Height in pixel
+ * \param[in] handler Event handling callback
+ * \param[in] data user data for event handling callback
+ * \return handler Buffer handle
+ * \retval NULL Failed to acquire buffer
+ * \retval Handle object
+ * \pre
+ *    Given instance must be specify its type as buffer. or this API will be fail
+ * \post
+ *    Allocated buffer object must be released via livebox_release_Buffer
+ * \see livebox_release_buffer
+ * \sa livebox_acquire_buffer_NEW
+ */
+extern struct livebox_buffer *livebox_acquire_buffer(const char *id, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data);
+extern struct livebox_buffer *livebox_acquire_buffer_NEW(const char *id, int is_pd, int width, int height, int pixels, int (*handler)(struct livebox_buffer *, struct buffer_event_data *, void *), void *data);
+
+/*!
+ * \brief Acquire the ID of pixmap resource
+ *        Only if the provider uses pixmap for providing render buffer.
+ * \details N/A
+ * \remarks Pixmap Id can be destroyed if you call the livebox_release_buffer. than this pixmap Id is not guaranteed to use.
+ * \param[in] handle Buffer handle
+ * \return unsigned
+ * \retval positive Pixmap Id
+ * \retval 0 failed to get pixmap Id.
+ * \pre The system must be set to use the pixmap method for content sharing
+ * \post N/A
+ * \see livebox_acquire_buffer
+ */
+extern unsigned long livebox_pixmap_id(struct livebox_buffer *handle);
+
+/*!
+ * \brief Release the buffer of livebox
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \retval LB_STATUS_SUCCESS Successfully released
+ * \pre handle must be created using livebox_acquire_buffer.
+ * \post N/A
+ * \see livebox_acquire_buffer
+ * \sa livebox_release_buffer_NEW
+ */
+extern int livebox_release_buffer(struct livebox_buffer *handle);
+extern int livebox_release_buffer_NEW(struct livebox_buffer *handle);
+
+/*!
+ * \brief Get the address of S/W render buffer.
+ *        If you try to use this, after create_hw_buffer, you will get NULL
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return void* address of the render buffer
+ * \retval NULL if it falis to get buffer address
+ * \retval address if it succeed to get the buffer address
+ * \pre N/A
+ * \post N/A
+ * \see livebox_unref_buffer
+ */
+extern void *livebox_ref_buffer(struct livebox_buffer *handle);
+
+/*!
+ * \brief Release the S/W render buffer.
+ * \details N/A
+ * \remarks N/A
+ * \param[in] buffer Address of render buffer
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Invalid handle
+ * \retval LB_STATUS_SUCCESS Successfully unref'd
+ * \pre livebox_ref_buffer must be called
+ * \post N/A
+ * \see livebox_ref_buffer
+ */
+extern int livebox_unref_buffer(void *buffer);
+
+/*!
+ * \brief Sync the updated buffer
+ *        This is only needed for non-H/W accelerated buffer
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return int
+ * \retval LB_STATUS_SUCCESS Successfully sync'd
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \pre N/A
+ * \post N/A
+ * \see livebox_acquire_buffer
+ */
+extern int livebox_sync_buffer(struct livebox_buffer *handle);
+
+/*!
+ * \brief Request schedule the update operation to a provider.
+ * \details
+ * \remarks N/A
+ * \param[in] id Livebox Id
+ * \return int 0 if succeed or errno < 0
+ * \retval LB_STATUS_SUCCESS Successfully triggered
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \retval LB_STATUS_ERROR_MEMORY Not enough memory
+ * \retval LB_STATUS_ERROR_NOT_EXIST Given id instance is not exist
+ * \pre N/A
+ * \post N/A
+ * \see N/A
+ */
+extern int livebox_request_update(const char *id);
+
+/*!
+ * \brief Checking wether the livebox support H/W acceleration or not.
+ * \details
+ * \remarks N/A
+ * \param[in] handle Buffer handle.
+ * \return int
+ * \retval 1 if the buffer handle support the H/W acceleration buffer
+ * \retval 0 if it doesn not supported
+ * \pre N/A
+ * \post N/A
+ * \see livebox_acquire_buffer
+ */
+extern int livebox_support_hw_buffer(struct livebox_buffer *handle);
+
+/*!
+ * \brief Create the H/W accelerated buffer.
+ * \details Create the H/W accelerated buffer
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return int
+ * \retval LB_STATUS_ERROR_ALREADY H/W buffer is already created
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \retval LB_STATUS_SUCCESS Successfully created
+ * \pre Must be checked whether the H/W buffer is supported or not.
+ * \post Must be destroyed if it is not necessary
+ * \see livebox_support_hw_buffer
+ */
+extern int livebox_create_hw_buffer(struct livebox_buffer *handle);
+
+/*!
+ * \brief Destroy the H/W accelerated buffer.
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return int
+ * \retval LB_STATUS_SUCCESS Successfully destroyed
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \pre Must be created h/w buffer using livebox_create_hw_buffer
+ * \post N/A
+ * \see livebox_create_hw_buffer
+ */
+extern int livebox_destroy_hw_buffer(struct livebox_buffer *handle);
+
+/*!
+ * \brief Get the address of accelerated H/W buffer
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return void *
+ * \retval NULL failed to get H/W accelerated buffer address
+ * \retval addr H/W accelerated buffer address
+ * \pre N/A
+ * \post N/A
+ * \see livebox_create_hw_buffer
+ */
+extern void *livebox_buffer_hw_buffer(struct livebox_buffer *handle);
+
+/*!
+ * \brief Pre-processing for rendering content.
+ *        This is only needed for accessing H/W accelerated buffer.
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Invalid handle
+ * \retval LB_STATUS_SUCCESS Successfully done
+ * \pre N/A
+ * \post livebox_buffer_post_render must be called after the rendering (accessing buffer) is completed.
+ * \see livebox_support_hw_buffer
+ * \see livebox_buffer_post_render
+ */
+extern int livebox_buffer_pre_render(struct livebox_buffer *handle);
+
+/*!
+ * \brief Post-processing for rendering content.
+ * \details N/A
+ * \remarks N/A
+ * \param[in] handle Buffer handle
+ * \return integer 0 if succeed or errno < 0
+ * \retval LB_STATUS_SUCCESS if succeed
+ * \retval LB_STATUS_ERROR_INVALID Invalid argument
+ * \pre livebox_buffer_pre_render must be called
+ * \post N/A
+ * \see livebox_support_hw_buffer
+ * \see livebox_buffer_pre_render
+ */
+extern int livebox_buffer_post_render(struct livebox_buffer *handle);
+
+/*!
+ * \brief
+ * Deprecated API set.
+extern Evas_Object *livebox_snapshot_window_add(const char *id, int size_type);
+extern int livebox_snapshot_window_flush(Evas_Object *snapshot_win, double timeout, void (*flush_cb)(Evas_Object *snapshot_window, const char *id, int status, void *data), void *data);
+extern int livebox_snapshot_window_del(Evas_Object *snapshot_win);
+*/
+
+/*!
+ * \brief Create an Evas_Object to create a elm_win object
+ * \details Creating a new Evas_Object using livebox frame buffer.
+ * \remarks N/A
+ * \param[in] id Instance Id
+ * \param[in] is_pd 1 if this object is created for PD or 0 (for LB)
+ * \return Evas_Object* Evas Object
+ * \retval Address Valid evas object
+ * \retval NULL failed to create
+ * \pre N/A
+ * \post N/A
+ * \see livebox_set_elm_window
+ */
+extern Evas_Object *livebox_get_evas_object(const char *id, int is_pd);
+
+/*!
+ * \brief Send a request to the viewer (homescreen) to close the PD.
+ * \details Even though you call this function. the homescreen can ignore it.
+ * \remarks
+ * \param[in] pkgname Livebox Package Id
+ * \param[in] id Livebox Instance Id
+ * \param[in] reason LB_STATUS_SUCCESS(0)
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Invalid parameters
+ * \retval LB_STATUS_ERROR_MEMORY Out of memory
+ * \retval LB_STATUS_ERROR_FAULT Failed to send a request
+ * \retval LB_STATUS_SUCCESS Successfully requested
+ * \pre N/A
+ * \post N/A
+ * \see
+ */
+extern int livebox_request_close_pd(const char *pkgname, const char *id, int reason);
+
+/*!
+ * \brief Send a freeze request to the viewer (homescreen)
+ * \details
+ *        The viewer will get this request via event callback.
+ *        Then it should freeze its scroller or stop moving the livebox.
+ * \remarks If the viewer doesn't care this request, this will has no effect.
+ * \param[in] pkgname Livebox Package Id
+ * \param[in] id Livebox Instance Id
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Invalid parameters
+ * \retval LB_STATUS_ERROR_MEMORY Out of memory
+ * \retval LB_STATUS_ERROR_FAULT Failed to send requet
+ * \retval LB_STATUS_SUCCESS Successfully requested
+ * \pre N/A
+ * \post N/A
+ * \see livebox_release_scroller
+ */
+extern int livebox_freeze_scroller(const char *pkgname, const char *id);
+
+/*!
+ * \brief Send a release request to the viewer (homescreen)
+ * \details
+ *        The viewer will get this request via event callback.
+ *        Then it should release its scroller or continue moving the livebox.
+ * \remarks If the viewer doesn't care this request, this will has no effect.
+ * \param[in] pkgname Livebox Package Id
+ * \param[in] id Livebox Instance Id
+ * \retval LB_STATUS_ERROR_INVALID Invalid parameters
+ * \retval LB_STATUS_ERROR_MEMORY Out of memory
+ * \retval LB_STATUS_ERROR_FAULT Failed to send requet
+ * \retval LB_STATUS_SUCCESS Successfully requested
+ * \pre N/A
+ * \post N/A
+ * \see livebox_freeze_scroller
+ */
+extern int livebox_release_scroller(const char *pkgname, const char *id);
+
+/*!
+ * \brief Get the configuration status of premultiplied alpha.
+ * \details
+ *     If the system uses the premultiplied alpha for content,
+ *     This function will returns 1.
+ * \remarks This function only works with the inhouse provider.
+ * \return status of premultiplied alpha.
+ * \retval 1 Content rendered with premultiplied alpha.
+ * \retval 0 Content doesn't rendered with premultiplied alpha.
+ */
+extern int livebox_conf_premultiplied_alpha(void);
+
+/*!
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* End of a file */
diff --git a/include/util.h b/include/util.h
new file mode 100644 (file)
index 0000000..905974d
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+extern int util_check_extension(const char *filename, const char *check_ptr);
+extern double util_timestamp(void);
+
+/* End of a file */
diff --git a/livebox.pc.in b/livebox.pc.in
new file mode 100644 (file)
index 0000000..60193d3
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: livebox
+Description: livebox supporting library
+Version: @VERSION@
+Libs: -L${libdir} -llivebox
+Cflags: -I${includedir}
+cppflags: -I${includedir}
diff --git a/packaging/liblivebox.manifest b/packaging/liblivebox.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/packaging/liblivebox.spec b/packaging/liblivebox.spec
new file mode 100644 (file)
index 0000000..2f2bc87
--- /dev/null
@@ -0,0 +1,95 @@
+%bcond_with wayland
+
+Name: liblivebox
+Summary: Livebox development library
+Version: 0.7.4
+Release: 1
+Group: HomeTF/Livebox
+License: Flora
+Source0: %{name}-%{version}.tar.gz
+Source1001: %{name}.manifest
+BuildRequires: cmake, gettext-tools, coreutils
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(livebox-service)
+BuildRequires: pkgconfig(provider)
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(evas)
+BuildRequires: pkgconfig(elementary)
+
+%if %{with wayland}
+%else
+BuildRequires: pkgconfig(x11)
+%endif
+
+%if "%{sec_product_feature_livebox}" == "0"
+ExclusiveArch:
+%endif
+
+%description
+Library for the development of a livebox
+
+%package devel
+Summary: Livebox development library (dev)
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Header & Package configuration files for livebox development
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS="${CFLAGS} -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS="${CXXFLAGS} -DTIZEN_ENGINEER_MODE"
+export FFLAGS="${FFLAGS} -DTIZEN_ENGINEER_MODE"
+%endif
+
+%if "%{_repository}" == "wearable"
+export WEARABLE=On
+export MOBILE=Off
+%elseif "%{_repository}" == "mobile"
+export WEARABLE=Off
+export MOBILE=On
+%endif
+
+%if %{with wayland}
+export WAYLAND_SUPPORT=On
+export X11_SUPPORT=Off
+%else
+export WAYLAND_SUPPORT=Off
+export X11_SUPPORT=On
+%endif
+
+%cmake . -DWAYLAND_SUPPORT=${WAYLAND_SUPPORT} -DX11_SUPPORT=${X11_SUPPORT} -DMOBILE=${MOBILE} -DWEARABLE=${WEARABLE}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+mkdir -p %{buildroot}/%{_datarootdir}/license
+
+%post -n liblivebox -p /sbin/ldconfig
+%postun -n liblivebox -p /sbin/ldconfig
+
+%files -n liblivebox
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_libdir}/*.so*
+%{_datarootdir}/license/*
+
+%files devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_includedir}/livebox/livebox.h
+%{_libdir}/pkgconfig/*.pc
+
+# End of a file
diff --git a/src/dlist.c b/src/dlist.c
new file mode 100644 (file)
index 0000000..b545904
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "dlist.h"
+
+struct dlist {
+       struct dlist *next;
+       struct dlist *prev;
+       void *data;
+};
+
+struct dlist *dlist_append(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item) {
+               return NULL;
+       }
+
+       item->next = NULL;
+       item->data = data;
+
+       if (!list) {
+               item->prev = item;
+
+               list = item;
+       } else {
+               item->prev = list->prev;
+               item->prev->next = item;
+
+               list->prev = item;
+       }
+
+       assert(!list->prev->next && "item NEXT");
+
+       return list;
+}
+
+struct dlist *dlist_prepend(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item) {
+               return NULL;
+       }
+
+       if (!list) {
+               item->prev = item;
+               item->next = NULL;
+       } else {
+               item->prev = list->prev;
+               list->prev = item;
+               item->next = list;
+       }
+
+       return item;
+}
+
+struct dlist *dlist_remove(struct dlist *list, struct dlist *l)
+{
+       if (!list || !l) {
+               return NULL;
+       }
+
+       if (l == list) {
+               l->prev = list->prev;
+               list = l->next;
+       } else {
+               l->prev->next = l->next;
+       }
+
+       if (l->next) {
+               l->next->prev = l->prev;
+       }
+
+       free(l);
+       return list;
+}
+
+struct dlist *dlist_find_data(struct dlist *list, void *data)
+{
+       struct dlist *l;
+       void *_data;
+
+       dlist_foreach(list, l, _data) {
+               if (data == _data) {
+                       return l;
+               }
+       }
+
+       return NULL;
+}
+
+void *dlist_data(struct dlist *l)
+{
+       return l ? l->data : NULL;
+}
+
+struct dlist *dlist_next(struct dlist *l)
+{
+       return l ? l->next : NULL;
+}
+
+struct dlist *dlist_prev(struct dlist *l)
+{
+       return l ? l->prev : NULL;
+}
+
+int dlist_count(struct dlist *l)
+{
+       register int i;
+       struct dlist *n;
+       void *data;
+
+       i = 0;
+       dlist_foreach(l, n, data) {
+               i++;
+       }
+
+       return i;
+}
+
+struct dlist *dlist_nth(struct dlist *l, int nth)
+{
+       register int i;
+       struct dlist *n;
+       void *data;
+
+       i = 0;
+       dlist_foreach(l, n, data) {
+               if (i == nth) {
+                       return l;
+               }
+
+               i++;
+       }
+
+       return NULL;
+}
+
+/* End of a file */
diff --git a/src/livebox.c b/src/livebox.c
new file mode 100644 (file)
index 0000000..b71c116
--- /dev/null
@@ -0,0 +1,1388 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h> /* malloc */
+#include <string.h> /* strdup */
+#include <libgen.h>
+#include <unistd.h> /* access */
+#define __USE_GNU
+#include <dlfcn.h>
+
+#include <dlog.h>
+#include <livebox-service.h>
+#include <provider.h>
+#include <provider_buffer.h>
+#include <livebox-errno.h>
+
+#include "debug.h"
+#include "livebox.h"
+#include "dlist.h"
+#include "util.h"
+
+#define PUBLIC __attribute__((visibility("default")))
+
+#define FILE_SCHEMA    "file://"
+
+/* Must has to sync'd with data-provider-slave */
+struct conf {
+       int width;
+       int height;
+
+       int base_width;
+       int base_height;
+       double minimum_period;
+
+       struct {
+               char *script;
+               char *abi;
+               char *pd_group;
+               double period;
+       } default_conf;
+
+       struct {
+               char *name;
+               char *secured;
+               char *abi;
+       } launch_key;
+
+       double default_packet_time;
+
+       char *empty_content;
+       char *empty_title;
+
+       char *default_content;
+       char *default_title;
+
+       unsigned long minimum_space;
+
+       char *replace_tag;
+
+       double slave_ttl;
+       double slave_activate_time;
+       double slave_relaunch_time;
+       int slave_relaunch_count;
+
+       int max_log_line;
+       int max_log_file;
+
+       unsigned long sqlite_flush_max;
+
+       struct {
+               char *conf;
+               char *image;
+               char *script;
+               char *root;
+               char *script_port;
+               char *slave_log;
+               char *reader;
+               char *always;
+               char *db;
+               char *module;
+               char *input;
+       } path;
+
+       int max_size_type;
+
+       int slave_max_load;
+
+       double ping_time;
+
+       int use_sw_backend;
+       char *provider_method;
+       int debug_mode;
+       int overwrite_content;
+       int com_core_thread;
+       int use_xmonitor;
+       int premultiplied;
+};
+
+/*!
+ * \brief This function is defined by the data-provider-slave
+ */
+static struct info {
+       const char *(*find_pkgname)(const char *filename);
+       int (*request_update_by_id)(const char *uri);
+       int (*trigger_update_monitor)(const char *id, int is_pd);
+       int (*update_extra_info)(const char *id, const char *content, const char *title, const char *icon, const char *name);
+       struct conf *conf;
+} s_info = {
+       .find_pkgname = NULL,
+       .request_update_by_id = NULL,
+       .trigger_update_monitor = NULL,
+       .update_extra_info = NULL,
+       .conf = NULL,
+};
+
+struct block {
+       unsigned int idx;
+
+       char *type;
+       char *part;
+       char *data;
+       char *option;
+       char *id;
+       char *file;
+       char *target_id;
+};
+
+struct livebox_desc {
+       FILE *fp;
+       int for_pd;
+
+       unsigned int last_idx;
+
+       struct dlist *block_list;
+};
+
+struct livebox_buffer_data {
+       int is_pd;
+       int accelerated;
+
+       /* for Buffer event wrapper */
+       int (*handler_NEW)(struct livebox_buffer *, struct buffer_event_data *, void *);
+       int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
+       void *cbdata;
+
+       char *content;
+       char *title;
+       char *icon;
+       char *name;
+};
+
+PUBLIC const int DONE = 0x00;
+PUBLIC const int OUTPUT_UPDATED = 0x02;
+PUBLIC const int USE_NET = 0x04;
+
+PUBLIC const int NEED_TO_SCHEDULE = 0x01;
+PUBLIC const int NEED_TO_CREATE = 0x01;
+PUBLIC const int NEED_TO_DESTROY = 0x01;
+PUBLIC const int NEED_TO_UPDATE = 0x01;
+PUBLIC const int FORCE_TO_SCHEDULE = 0x08;
+
+PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
+PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
+PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
+PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
+PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
+PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
+PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
+
+static char *id_to_uri(const char *id)
+{
+       char *uri;
+       int uri_len;
+
+       uri_len = strlen(id) + strlen(FILE_SCHEMA) + 1;
+
+       uri = malloc(uri_len);
+       if (!uri) {
+               return NULL;
+       }
+
+       snprintf(uri, uri_len, FILE_SCHEMA "%s", id);
+       return uri;
+}
+
+PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
+{
+       struct livebox_desc *handle;
+       char *new_fname;
+
+       handle = calloc(1, sizeof(*handle));
+       if (!handle) {
+               ErrPrint("Error: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       if (for_pd) {
+               int len;
+               len = strlen(filename) + strlen(".desc") + 1;
+               new_fname = malloc(len);
+               if (!new_fname) {
+                       ErrPrint("Error: %s\n", strerror(errno));
+                       free(handle);
+                       return NULL;
+               }
+               snprintf(new_fname, len, "%s.desc", filename);
+       } else {
+               new_fname = strdup(filename);
+               if (!new_fname) {
+                       ErrPrint("Error: %s\n", strerror(errno));
+                       free(handle);
+                       return NULL;
+               }
+       }
+
+       DbgPrint("Open a file %s with merge mode %s\n",
+                               new_fname,
+                               access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
+
+       handle->fp = fopen(new_fname, "at");
+       free(new_fname);
+       if (!handle->fp) {
+               ErrPrint("Failed to open a file: %s\n", strerror(errno));
+               free(handle);
+               return NULL;
+       }
+
+       return handle;
+}
+
+PUBLIC int livebox_desc_close(struct livebox_desc *handle)
+{
+       struct dlist *l;
+       struct dlist *n;
+       struct block *block;
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       dlist_foreach_safe(handle->block_list, l, n, block) {
+               handle->block_list = dlist_remove(handle->block_list, l);
+
+               fprintf(handle->fp, "{\n");
+               if (block->type) {
+                       fprintf(handle->fp, "type=%s\n", block->type);
+               }
+
+               if (block->part) {
+                       fprintf(handle->fp, "part=%s\n", block->part);
+               }
+
+               if (block->data) {
+                       fprintf(handle->fp, "data=%s\n", block->data);
+               }
+
+               if (block->option) {
+                       fprintf(handle->fp, "option=%s\n", block->option);
+               }
+
+               if (block->id) {
+                       fprintf(handle->fp, "id=%s\n", block->id);
+               }
+
+               if (block->target_id) {
+                       fprintf(handle->fp, "target=%s\n", block->target_id);
+               }
+               fprintf(handle->fp, "}\n");
+
+               free(block->type);
+               free(block->part);
+               free(block->data);
+               free(block->option);
+               free(block->id);
+               free(block->target_id);
+               free(block);
+       }
+
+       if (fclose(handle->fp) != 0) {
+               ErrPrint("fclose: %s\n", strerror(errno));
+       }
+       free(handle);
+       return LB_STATUS_SUCCESS;
+}
+
+PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
+{
+       struct block *block;
+
+       if (!handle || !category) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       block = calloc(1, sizeof(*block));
+       if (!block) {
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->type = strdup(LB_DESC_TYPE_INFO);
+       if (!block->type) {
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->part = strdup("category");
+       if (!block->part) {
+               free(block->type);
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->data = strdup(category);
+       if (!block->data) {
+               free(block->type);
+               free(block->part);
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       if (id) {
+               block->id = strdup(id);
+               if (!block->id) {
+                       free(block->data);
+                       free(block->type);
+                       free(block->part);
+                       free(block);
+                       return LB_STATUS_ERROR_MEMORY;
+               }
+       }
+
+       block->idx = handle->last_idx++;
+       handle->block_list = dlist_append(handle->block_list, block);
+       return block->idx;
+}
+
+PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
+{
+       struct block *block;
+       char buffer[BUFSIZ];
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       block = calloc(1, sizeof(*block));
+       if (!block) {
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->type = strdup(LB_DESC_TYPE_INFO);
+       if (!block->type) {
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->part = strdup("size");
+       if (!block->part) {
+               free(block->type);
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       if (id) {
+               block->id = strdup(id);
+               if (!block->id) {
+                       free(block->part);
+                       free(block->type);
+                       free(block);
+                       return LB_STATUS_ERROR_MEMORY;
+               }
+       }
+
+       snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
+       block->data = strdup(buffer);
+       if (!block->data) {
+               free(block->part);
+               free(block->type);
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->idx = handle->last_idx++;
+       handle->block_list = dlist_append(handle->block_list, block);
+       return block->idx;
+}
+
+PUBLIC char *livebox_util_nl2br(const char *str)
+{
+       int len;
+       register int i;
+       char *ret;
+       char *ptr;
+
+       if (!str) {
+               return NULL;
+       }
+
+       len = strlen(str);
+       if (!len) {
+               return NULL;
+       }
+
+       ret = malloc(len + 1);
+       if (!ret) {
+               return NULL;
+       }
+
+       ptr = ret;
+       i = 0;
+       while (*str) {
+               switch (*str) {
+               case '\n':
+                       if (len - i < 5) {
+                               char *tmp;
+                               len += len;
+
+                               tmp = realloc(ret, len + 1);
+                               if (!tmp) {
+                                       free(ret);
+                                       return NULL;
+                               }
+
+                               ret = tmp;
+                               ptr = tmp + i;
+                       }
+
+                       strcpy(ptr, "<br>");
+                       ptr += 4;
+                       i += 4;
+                       break;
+               default:
+                       *ptr++ = *str;
+                       i++;
+                       break;
+               }
+
+               str++;
+       }
+       *ptr = '\0';
+
+       return ret;
+}
+
+PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
+{
+       struct dlist *l;
+       struct block *block;
+
+       dlist_foreach(handle->block_list, l, block) {
+               if (block->idx == idx) {
+                       if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
+                               ErrPrint("Invalid block is used\n");
+                               return LB_STATUS_ERROR_INVALID;
+                       }
+
+                       free(block->target_id);
+                       block->target_id = NULL;
+
+                       if (!id || !strlen(id)) {
+                               return LB_STATUS_SUCCESS;
+                       }
+
+                       block->target_id = strdup(id);
+                       if (!block->target_id) {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                               return LB_STATUS_ERROR_MEMORY;
+                       }
+
+                       return LB_STATUS_SUCCESS;
+               }
+       }
+
+       return LB_STATUS_ERROR_NOT_EXIST;
+}
+
+/*!
+ * \return idx
+ */
+PUBLIC int livebox_desc_add_block(struct livebox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
+{
+       struct block *block;
+
+       if (!handle || !type) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!part) {
+               part = "";
+       }
+
+       if (!data) {
+               data = "";
+       }
+
+       block = calloc(1, sizeof(*block));
+       if (!block) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->type = strdup(type);
+       if (!block->type) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->part = strdup(part);
+       if (!block->part) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(block->type);
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       block->data = strdup(data);
+       if (!block->data) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(block->type);
+               free(block->part);
+               free(block);
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       if (option) {
+               block->option = strdup(option);
+               if (!block->option) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       free(block->data);
+                       free(block->type);
+                       free(block->part);
+                       free(block);
+                       return LB_STATUS_ERROR_MEMORY;
+               }
+       }
+
+       if (id) {
+               block->id = strdup(id);
+               if (!block->id) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       free(block->option);
+                       free(block->data);
+                       free(block->type);
+                       free(block->part);
+                       free(block);
+                       return LB_STATUS_ERROR_MEMORY;
+               }
+       }
+
+       block->idx = handle->last_idx++;
+       handle->block_list = dlist_append(handle->block_list, block);
+       return block->idx;
+}
+
+PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
+{
+       struct dlist *l;
+       struct block *block;
+
+       if (!handle || idx < 0) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       dlist_foreach(handle->block_list, l, block) {
+               if (block->idx == idx) {
+                       handle->block_list = dlist_remove(handle->block_list, l);
+                       free(block->type);
+                       free(block->part);
+                       free(block->data);
+                       free(block->option);
+                       free(block->id);
+                       free(block->target_id);
+                       free(block);
+                       return LB_STATUS_SUCCESS;
+               }
+       }
+
+       return LB_STATUS_ERROR_NOT_EXIST;
+}
+
+static inline int event_handler_wrapper_NEW(struct livebox_buffer *buffer, struct buffer_event_data *event_info, void *data)
+{
+       const char *pkgname;
+       const char *id;
+       struct livebox_buffer_data *cbdata = data;
+       int ret;
+
+       pkgname = provider_buffer_pkgname(buffer);
+       if (!pkgname) {
+               ErrPrint("pkgname is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       id = provider_buffer_id(buffer);
+       if (!id) {
+               ErrPrint("id is not valid[%s]\n", pkgname);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (cbdata->handler_NEW) {
+               ret = cbdata->handler_NEW(buffer, event_info, cbdata->cbdata);
+       } else {
+               ret = LB_STATUS_ERROR_FAULT;
+       }
+
+       switch (event_info->type) {
+       case BUFFER_EVENT_HIGHLIGHT:
+       case BUFFER_EVENT_HIGHLIGHT_NEXT:
+       case BUFFER_EVENT_HIGHLIGHT_PREV:
+       case BUFFER_EVENT_ACTIVATE:
+       case BUFFER_EVENT_ACTION_UP:
+       case BUFFER_EVENT_ACTION_DOWN:
+       case BUFFER_EVENT_SCROLL_UP:
+       case BUFFER_EVENT_SCROLL_MOVE:
+       case BUFFER_EVENT_SCROLL_DOWN:
+       case BUFFER_EVENT_UNHIGHLIGHT:
+               DbgPrint("Accessibility event: %d\n", event_info->type);
+               if (ret < 0) {
+                       (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
+               } else {
+                       (void)provider_send_access_status(pkgname, id, ret);
+               }
+               break;
+       case BUFFER_EVENT_KEY_UP:
+       case BUFFER_EVENT_KEY_DOWN:
+       case BUFFER_EVENT_KEY_FOCUS_IN:
+       case BUFFER_EVENT_KEY_FOCUS_OUT:
+               DbgPrint("Key event: %d\n", event_info->type);
+               if (ret < 0) {
+                       (void)provider_send_key_status(pkgname, id, LB_KEY_STATUS_ERROR);
+               } else {
+                       (void)provider_send_key_status(pkgname, id, ret);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+/*!
+ * \note
+ * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
+ */
+static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event type, double timestamp, double x, double y, void *data)
+{
+       const char *pkgname;
+       const char *id;
+       struct livebox_buffer_data *cbdata = data;
+       int ret;
+
+       pkgname = provider_buffer_pkgname(buffer);
+       if (!pkgname) {
+               ErrPrint("pkgname is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       id = provider_buffer_id(buffer);
+       if (!id) {
+               ErrPrint("id is not valid[%s]\n", pkgname);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (cbdata->handler) {
+               ret = cbdata->handler(buffer, type, timestamp, x, y, cbdata->cbdata);
+       } else {
+               ret = LB_STATUS_ERROR_FAULT;
+       }
+
+       switch (type) {
+       case BUFFER_EVENT_HIGHLIGHT:
+       case BUFFER_EVENT_HIGHLIGHT_NEXT:
+       case BUFFER_EVENT_HIGHLIGHT_PREV:
+       case BUFFER_EVENT_ACTIVATE:
+       case BUFFER_EVENT_ACTION_UP:
+       case BUFFER_EVENT_ACTION_DOWN:
+       case BUFFER_EVENT_SCROLL_UP:
+       case BUFFER_EVENT_SCROLL_MOVE:
+       case BUFFER_EVENT_SCROLL_DOWN:
+       case BUFFER_EVENT_UNHIGHLIGHT:
+               DbgPrint("Accessibility event: %d\n", type);
+               if (ret < 0) {
+                       (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
+               } else {
+                       (void)provider_send_access_status(pkgname, id, ret);
+               }
+               break;
+       case BUFFER_EVENT_KEY_UP:
+       case BUFFER_EVENT_KEY_DOWN:
+       case BUFFER_EVENT_KEY_FOCUS_IN:
+       case BUFFER_EVENT_KEY_FOCUS_OUT:
+               DbgPrint("Key event: %d\n", type);
+               if (ret < 0) {
+                       (void)provider_send_key_status(pkgname, id, LB_KEY_STATUS_ERROR);
+               } else {
+                       (void)provider_send_key_status(pkgname, id, ret);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+static inline int default_event_handler_NEW(struct livebox_buffer *buffer, struct buffer_event_data *event_info, void *data)
+{
+       /* NOP */
+       return 0;
+}
+
+static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event type, double timestamp, double x, double y, void *data)
+{
+       /* NOP */
+       return 0;
+}
+
+PUBLIC struct livebox_buffer *livebox_acquire_buffer_NEW(const char *filename, int is_pd, int width, int height, int pixels, int (*handler)(struct livebox_buffer *, struct buffer_event_data *, void *), void *data)
+{
+       struct livebox_buffer_data *user_data;
+       const char *pkgname;
+       struct livebox_buffer *handle;
+       char *uri;
+
+       if (!filename || !width || !height) {
+               ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
+               return NULL;
+       }
+
+       user_data = calloc(1, sizeof(*user_data));
+       if (!user_data) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       user_data->is_pd = is_pd;
+       user_data->handler_NEW = handler ? handler : default_event_handler_NEW;
+       user_data->handler = NULL;
+       user_data->cbdata = data;
+
+       uri = id_to_uri(filename);
+       if (!uri) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(user_data);
+               return NULL;
+       }
+
+       if (!s_info.find_pkgname) {
+               s_info.find_pkgname = dlsym(RTLD_DEFAULT, "livebox_find_pkgname");
+               if (!s_info.find_pkgname) {
+                       ErrPrint("Failed to find a \"livebox_find_pkgname\"\n");
+                       free(user_data);
+                       free(uri);
+                       return NULL;
+               }
+       }
+
+       pkgname = s_info.find_pkgname(uri);
+       if (!pkgname) {
+               ErrPrint("Invalid Request\n");
+               free(user_data);
+               free(uri);
+               return NULL;
+       }
+
+       handle = provider_buffer_create((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, event_handler_wrapper_NEW, user_data);
+       free(uri);
+       if (!handle) {
+               free(user_data);
+               return NULL;
+       }
+
+       if (provider_buffer_acquire_NEW(handle, width, height, pixels) < 0) {
+               provider_buffer_destroy(handle);
+               free(user_data);
+               return NULL;
+       }
+
+       (void)provider_buffer_set_user_data(handle, user_data);
+       return handle;
+}
+
+PUBLIC struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data)
+{
+       struct livebox_buffer_data *user_data;
+       const char *pkgname;
+       struct livebox_buffer *handle;
+       char *uri;
+
+       if (!filename || !width || !height) {
+               ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
+               return NULL;
+       }
+
+       user_data = calloc(1, sizeof(*user_data));
+       if (!user_data) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       user_data->is_pd = is_pd;
+       user_data->handler = handler ? handler : default_event_handler;
+       user_data->handler_NEW = NULL;
+       user_data->cbdata = data;
+
+       uri = id_to_uri(filename);
+       if (!uri) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(user_data);
+               return NULL;
+       }
+
+       if (!s_info.find_pkgname) {
+               s_info.find_pkgname = dlsym(RTLD_DEFAULT, "livebox_find_pkgname");
+               if (!s_info.find_pkgname) {
+                       ErrPrint("Failed to find a \"livebox_find_pkgname\"\n");
+                       free(user_data);
+                       free(uri);
+                       return NULL;
+               }
+       }
+
+       pkgname = s_info.find_pkgname(uri);
+       if (!pkgname) {
+               ErrPrint("Invalid Request\n");
+               free(user_data);
+               free(uri);
+               return NULL;
+       }
+
+       handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
+       DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
+       free(uri);
+       if (!handle) {
+               free(user_data);
+               return NULL;
+       }
+
+       (void)provider_buffer_set_user_data(handle, user_data);
+       return handle;
+}
+
+PUBLIC int livebox_request_update(const char *filename)
+{
+       char *uri;
+       int ret;
+
+       if (!filename) {
+               ErrPrint("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       uri = id_to_uri(filename);
+       if (!uri) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       if (!s_info.request_update_by_id) {
+               s_info.request_update_by_id = dlsym(RTLD_DEFAULT, "livebox_request_update_by_id");
+               if (!s_info.request_update_by_id) {
+                       ErrPrint("\"livebox_request_update_by_id\" is not exists\n");
+                       free(uri);
+                       return LB_STATUS_ERROR_FAULT;
+               }
+       }
+       ret = s_info.request_update_by_id(uri);
+       free(uri);
+       return ret;
+}
+
+PUBLIC int livebox_conf_premultiplied_alpha(void)
+{
+       if (!s_info.conf) {
+               s_info.conf = dlsym(RTLD_DEFAULT, "g_conf");
+               if (!s_info.conf) {
+                       ErrPrint("g_conf is not found\n");
+                       return 1;
+               }
+
+               DbgPrint("Premultiplied alpha: %d\n", s_info.conf->premultiplied);
+       }
+
+       return s_info.conf->premultiplied;
+}
+
+PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
+{
+       return provider_buffer_pixmap_id(handle);
+}
+
+PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (user_data) {
+               free(user_data->content);
+               free(user_data->title);
+               free(user_data->icon);
+               free(user_data->name);
+               free(user_data);
+               provider_buffer_set_user_data(handle, NULL);
+       }
+
+       DbgPrint("Release buffer\n");
+       return provider_buffer_release(handle);
+}
+
+PUBLIC int livebox_release_buffer_NEW(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (user_data) {
+               free(user_data->content);
+               free(user_data->title);
+               free(user_data->icon);
+               free(user_data->name);
+               free(user_data);
+               provider_buffer_set_user_data(handle, NULL);
+       }
+
+       (void)provider_buffer_release_NEW(handle);
+       (void)provider_buffer_destroy(handle);
+
+       DbgPrint("Release buffer\n");
+       return 0;
+}
+
+PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+       void *data;
+       int w, h, size;
+       int ret;
+
+       if (!handle) {
+               return NULL;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (!user_data) {
+               return NULL;
+       }
+
+       if (user_data->accelerated) {
+               DbgPrint("H/W accelerated buffer is allocated\n");
+               return NULL;
+       }
+
+       ret = provider_buffer_get_size(handle, &w, &h, &size);
+
+       data = provider_buffer_ref(handle);
+       if (data && !ret && w > 0 && h > 0 && size > 0) {
+               memset(data, 0, w * h * size);
+               (void)provider_buffer_sync(handle);
+       }
+
+       DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
+       return data;
+}
+
+PUBLIC int livebox_unref_buffer(void *buffer)
+{
+       if (!buffer) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       DbgPrint("Unref buffer\n");
+       return provider_buffer_unref(buffer);
+}
+
+PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+       const char *pkgname;
+       const char *id;
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (!user_data) {
+               ErrPrint("Invalid buffer\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (user_data->accelerated) {
+               DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
+               return LB_STATUS_SUCCESS;
+       }
+
+       pkgname = provider_buffer_pkgname(handle);
+       if (!pkgname) {
+               ErrPrint("Invalid buffer handler\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       id = provider_buffer_id(handle);
+       if (!id) {
+               ErrPrint("Invalid buffer handler\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       (void)provider_buffer_sync(handle);
+
+       if (user_data->is_pd == 1) {
+               if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
+                       ErrPrint("Failed to send PD updated (%s)\n", id);
+               }
+       } else {
+               int w;
+               int h;
+               int pixel_size;
+
+               if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
+                       ErrPrint("Failed to get size (%s)\n", id);
+               }
+
+               if (provider_send_updated_NEW(pkgname, id, w, h, -1.0f, user_data->content, user_data->title, user_data->icon, user_data->name) < 0) {
+                       ErrPrint("Failed to send updated (%s)\n", id);
+               }
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
+{
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return provider_buffer_pixmap_is_support_hw(handle);
+}
+
+PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+       int ret;
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (!user_data) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (user_data->accelerated) {
+               return LB_STATUS_ERROR_ALREADY;
+       }
+
+       ret = provider_buffer_pixmap_create_hw(handle);
+       user_data->accelerated = (ret == 0);
+       return ret;
+}
+
+PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+
+       if (!handle) {
+               LOGD("handle is NULL\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (!user_data || !user_data->accelerated) {
+               LOGD("user_data is NULL\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data->accelerated = 0;
+
+       return provider_buffer_pixmap_destroy_hw(handle);
+}
+
+PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+
+       if (!handle) {
+               return NULL;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (!user_data || !user_data->accelerated) {
+               return NULL;
+       }
+
+       return provider_buffer_pixmap_hw_addr(handle);
+}
+
+PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
+{
+       struct livebox_buffer_data *user_data;
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (!user_data) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!user_data->accelerated) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       /*!
+        * \note
+        * Do preprocessing for accessing the H/W render buffer
+        */
+       return provider_buffer_pre_render(handle);
+}
+
+PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
+{
+       int ret;
+       const char *pkgname;
+       const char *id;
+       struct livebox_buffer_data *user_data;
+
+       if (!handle) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       user_data = provider_buffer_user_data(handle);
+       if (!user_data) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!user_data->accelerated) {
+               return LB_STATUS_SUCCESS;
+       }
+
+       pkgname = provider_buffer_pkgname(handle);
+       if (!pkgname) {
+               ErrPrint("Invalid buffer handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       id = provider_buffer_id(handle);
+       if (!id) {
+               ErrPrint("Invalid buffer handler\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       ret = provider_buffer_post_render(handle);
+       if (ret < 0) {
+               ErrPrint("Failed to post render processing\n");
+               return ret;
+       }
+
+       if (user_data->is_pd == 1) {
+               if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
+                       ErrPrint("Failed to send PD updated (%s)\n", id);
+               }
+       } else {
+               int w;
+               int h;
+               int pixel_size;
+
+               if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
+                       ErrPrint("Failed to get size (%s)\n", id);
+               }
+
+               if (provider_send_updated_NEW(pkgname, id, w, h, -1.0f, user_data->content, user_data->title, user_data->icon, user_data->name) < 0) {
+                       ErrPrint("Failed to send updated (%s)\n", id);
+               }
+       }
+
+       return LB_STATUS_SUCCESS;
+}
+
+PUBLIC int livebox_content_is_updated(const char *filename, int is_pd)
+{
+       if (!s_info.trigger_update_monitor) {
+               s_info.trigger_update_monitor = dlsym(RTLD_DEFAULT, "livebox_trigger_update_monitor");
+               if (!s_info.trigger_update_monitor) {
+                       ErrPrint("Trigger update monitor function is not exists\n");
+                       return LB_STATUS_ERROR_FAULT;
+               }
+       }
+
+       return s_info.trigger_update_monitor(filename, is_pd);
+}
+
+PUBLIC int livebox_request_close_pd(const char *pkgname, const char *id, int reason)
+{
+       char *uri;
+       int schema_len = strlen(FILE_SCHEMA);
+       int ret;
+
+       if (!pkgname || !id) {
+               ErrPrint("Invalid parameters (%s) (%s)\n", pkgname, id);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (strncmp(id, FILE_SCHEMA, schema_len)) {
+               uri = id_to_uri(id);
+               if (!uri) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       return LB_STATUS_ERROR_MEMORY;
+               }
+       } else {
+               uri = strdup(id);
+               if (!uri) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       return LB_STATUS_ERROR_MEMORY;
+               }
+       }
+
+       ret = provider_send_request_close_pd(pkgname, uri, reason);
+       free(uri);
+       return ret;
+}
+
+PUBLIC int livebox_freeze_scroller(const char *pkgname, const char *id)
+{
+       char *uri;
+       int ret;
+
+       uri = id_to_uri(id);
+       if (!uri) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       ret = provider_send_hold_scroll(pkgname, uri, 1);
+       free(uri);
+       return ret;
+}
+
+PUBLIC int livebox_release_scroller(const char *pkgname, const char *id)
+{
+       char *uri;
+       int ret;
+
+       uri = id_to_uri(id);
+       if (!uri) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       ret = provider_send_hold_scroll(pkgname, uri, 0);
+       free(uri);
+       return ret;
+}
+
+PUBLIC int livebox_set_extra_info(const char *id, const char *content, const char *title, const char *icon, const char *name)
+{
+       struct livebox_buffer *handle;
+       const char *pkgname;
+       char *uri;
+
+       uri = id_to_uri(id);
+       if (!uri) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
+       }
+
+       pkgname = s_info.find_pkgname(uri);
+       if (!pkgname) {
+               ErrPrint("Failed to find a package (%s)\n", uri);
+               free(uri);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       handle = provider_buffer_find_buffer(TYPE_LB, pkgname, uri);
+       free(uri);
+       if (handle) {
+               struct livebox_buffer_data *user_data;
+
+               user_data = provider_buffer_user_data(handle);
+               if (!user_data) {
+                       ErrPrint("User data is not available\n");
+                       return LB_STATUS_ERROR_FAULT;
+               }
+
+               if (content && strlen(content)) {
+                       char *_content;
+
+                       _content = strdup(content);
+                       if (_content) {
+                               if (user_data->content) {
+                                       free(user_data->content);
+                                       user_data->content = NULL;
+                               }
+
+                               user_data->content = _content;
+                       } else {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                       }
+               }
+
+               if (title && strlen(title)) {
+                       char *_title;
+
+                       _title = strdup(title);
+                       if (_title) {
+                               if (user_data->title) {
+                                       free(user_data->title);
+                                       user_data->title = NULL;
+                               }
+
+                               user_data->title = _title;
+                       } else {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                       }
+               }
+
+               if (icon && strlen(icon)) {
+                       char *_icon;
+
+                       _icon = strdup(icon);
+                       if (_icon) {
+                               if (user_data->icon) {
+                                       free(user_data->icon);
+                                       user_data->icon = NULL;
+                               }
+
+                               user_data->icon = _icon;
+                       } else {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                       }
+               }
+
+               if (name && strlen(name)) {
+                       char *_name;
+
+                       _name = strdup(name);
+                       if (_name) {
+                               if (user_data->name) {
+                                       free(user_data->name);
+                                       user_data->name = NULL;
+                               }
+
+                               user_data->name = _name;
+                       } else {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                       }
+               }
+
+               return LB_STATUS_SUCCESS;
+       }
+
+       if (!s_info.update_extra_info) {
+               s_info.update_extra_info = dlsym(RTLD_DEFAULT, "livebox_update_extra_info");
+               if (!s_info.update_extra_info) {
+                       ErrPrint("Failed to find a \"livebox_update_extra_info\"\n");
+                       return LB_STATUS_ERROR_INVALID;
+               }
+       }
+
+       return s_info.update_extra_info(id, content, title, icon, name);
+}
+
+/* End of a file */
diff --git a/src/snapshot_window.c b/src/snapshot_window.c
new file mode 100644 (file)
index 0000000..f1187d1
--- /dev/null
@@ -0,0 +1,529 @@
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Ecore.h>
+#include <unistd.h>
+
+#include <dlog.h>
+#include <livebox-service.h>
+#include <livebox-errno.h>
+
+#include "livebox.h"
+#include "debug.h"
+
+#define QUALITY_N_COMPRESS "quality=100 compress=1"
+#define PUBLIC __attribute__((visibility("default")))
+
+struct snapshot_info {
+       char *id;
+       void (*flush_cb)(Evas_Object *snapshot_window, const char *id, int status, void *data);
+       void *data;
+
+       Ecore_Timer *flush_timer;
+
+       int render_cnt;
+       double timeout;
+};
+
+static void post_render_cb(void *data, Evas *e, void *event_info);
+static void pre_render_cb(void *data, Evas *e, void *event_info);
+
+
+
+static inline Evas *create_virtual_canvas(int w, int h)
+{
+        Ecore_Evas *internal_ee;
+        Evas *internal_e;
+
+        // Create virtual canvas
+        internal_ee = ecore_evas_buffer_new(w, h);
+        if (!internal_ee) {
+                LOGD("Failed to create a new canvas buffer\n");
+                return NULL;
+        }
+
+       ecore_evas_alpha_set(internal_ee, EINA_TRUE);
+       ecore_evas_manual_render_set(internal_ee, EINA_FALSE);
+
+        // Get the "Evas" object from a virtual canvas
+        internal_e = ecore_evas_get(internal_ee);
+        if (!internal_e) {
+                ecore_evas_free(internal_ee);
+                LOGD("Faield to get Evas object\n");
+                return NULL;
+        }
+
+        return internal_e;
+}
+
+
+
+static inline int flush_data_to_file(Evas *e, char *data, const char *filename, int w, int h)
+{
+        Evas_Object *output;
+
+        output = evas_object_image_add(e);
+        if (!output) {
+               LOGD("Failed to create an image object\n");
+                return LB_STATUS_ERROR_FAULT;
+        }
+
+        evas_object_image_data_set(output, NULL);
+        evas_object_image_colorspace_set(output, EVAS_COLORSPACE_ARGB8888);
+        evas_object_image_alpha_set(output, EINA_TRUE);
+        evas_object_image_size_set(output, w, h);
+        evas_object_image_smooth_scale_set(output, EINA_TRUE);
+        evas_object_image_data_set(output, data);
+       evas_object_image_fill_set(output, 0, 0, w, h);
+        evas_object_image_data_update_add(output, 0, 0, w, h);
+
+        if (evas_object_image_save(output, filename, NULL, QUALITY_N_COMPRESS) == EINA_FALSE) {
+                evas_object_del(output);
+               SECURE_LOGD("Faield to save a captured image (%s)\n", filename);
+                return LB_STATUS_ERROR_IO;
+        }
+
+       evas_object_del(output);
+
+        if (access(filename, F_OK) != 0) {
+               SECURE_LOGD("File %s is not found\n", filename);
+                return LB_STATUS_ERROR_IO;
+        }
+
+       SECURE_LOGD("Flush data to a file (%s)\n", filename);
+       return LB_STATUS_SUCCESS;
+}
+
+
+
+static inline int destroy_virtual_canvas(Evas *e)
+{
+        Ecore_Evas *ee;
+
+        ee = ecore_evas_ecore_evas_get(e);
+        if (!ee) {
+               LOGD("Failed to ecore evas object\n");
+                return LB_STATUS_ERROR_FAULT;
+        }
+
+        ecore_evas_free(ee);
+        return LB_STATUS_SUCCESS;
+}
+
+
+
+static inline int flush_to_file(void *canvas, const char *filename, int w, int h)
+{
+       int status;
+       Evas *shot_e;
+       Ecore_Evas *shot_ee;
+
+       shot_e = create_virtual_canvas(w, h);
+       if (!shot_e) {
+               LOGE("Unable to create a new virtual window\n");
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       shot_ee = ecore_evas_ecore_evas_get(shot_e);
+       if (!shot_ee) {
+               LOGE("Unable to get Ecore_Evas\n");
+               destroy_virtual_canvas(shot_e);
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       ecore_evas_manual_render_set(shot_ee, EINA_TRUE);
+
+       status = flush_data_to_file(shot_e, canvas, filename, w, h);
+       destroy_virtual_canvas(shot_e);
+
+       return status;
+}
+
+
+
+static void del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+       struct snapshot_info *info;
+
+       info = evas_object_data_del(obj, "snapshot,info");
+       if (!info) {
+               return;
+       }
+
+       SECURE_LOGD("Delete object (%s)\n", info->id);
+
+       if (info->flush_cb) {
+               info->flush_cb(obj, info->id, LB_STATUS_ERROR_CANCEL, info->data);
+               LOGD("Flush is canceled\n");
+       }
+
+       /*!
+        * \note
+        * Render callback will be deleted.
+        */
+       destroy_virtual_canvas(e);
+       free(info->id);
+       free(info);
+}
+
+
+
+static Eina_Bool direct_snapshot_cb(void *data)
+{
+       Evas *e;
+       Ecore_Evas *ee;
+       void *canvas;
+       int status;
+       int w;
+       int h;
+       void (*flush_cb)(Evas_Object *snapshot_window, const char *id, int status, void *data);
+       Evas_Object *snapshot_win = data;
+       struct snapshot_info *info;
+
+       info = evas_object_data_get(snapshot_win, "snapshot,info");
+       if (!info) {
+               LOGE("Unable to get snapshot info\n");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       info->flush_timer = NULL;
+       flush_cb = info->flush_cb;
+       info->flush_cb = NULL; /* To prevent call this from the delete callback */
+
+       e = evas_object_evas_get(snapshot_win);
+       if (!e) {
+               LOGE("Invalid object, failed to get Evas\n");
+               if (flush_cb) {
+                       flush_cb(snapshot_win, info->id, LB_STATUS_ERROR_FAULT, info->data);
+               }
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       ee = ecore_evas_ecore_evas_get(e);
+       if (!ee) {
+               LOGE("Unable to get Ecore_Evas object\n");
+               if (flush_cb) {
+                       flush_cb(snapshot_win, info->id, LB_STATUS_ERROR_FAULT, info->data);
+               }
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+       ecore_evas_manual_render_set(ee, EINA_TRUE);
+
+       canvas = ecore_evas_buffer_pixels_get(ee);
+       if (!canvas) {
+               LOGE("Failed to get canvas\n");
+               if (flush_cb) {
+                       flush_cb(snapshot_win, info->id, LB_STATUS_ERROR_FAULT, info->data);
+               }
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       status = flush_to_file(canvas, info->id, w, h);
+       if (flush_cb) {
+               flush_cb(snapshot_win, info->id, status, info->data);
+       }
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+static Eina_Bool snapshot_cb(void *data)
+{
+       Evas_Object *snapshot_win = data;
+       struct snapshot_info *info;
+       Evas *e;
+       Ecore_Evas *ee;
+       void *canvas;
+       void (*flush_cb)(Evas_Object *snapshot_window, const char *id, int status, void *data);
+
+       info = evas_object_data_get(snapshot_win, "snapshot,info");
+       if (!info) {
+               LOGE("Invalid object\n");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       info->flush_timer = NULL;
+       flush_cb = info->flush_cb;
+       info->flush_cb = NULL; /* To prevent call this from the delete callback */
+
+       e = evas_object_evas_get(snapshot_win);
+       if (!e) {
+               LOGE("Invalid object\n");
+               if (flush_cb) {
+                       flush_cb(snapshot_win, info->id, LB_STATUS_ERROR_FAULT, info->data);
+               }
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       ee = ecore_evas_ecore_evas_get(e);
+       if (!ee) {
+               LOGE("Invalid object (ee)\n");
+               if (flush_cb) {
+                       flush_cb(snapshot_win, info->id, LB_STATUS_ERROR_FAULT, info->data);
+               }
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       canvas = (void*)ecore_evas_buffer_pixels_get(ee);
+       if (!canvas) {
+               LOGD("Failed to get pixel canvas\n");
+               if (flush_cb) {
+                       flush_cb(snapshot_win, info->id, LB_STATUS_ERROR_FAULT, info->data);
+               }
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       if (flush_cb) {
+               int w;
+               int h;
+               int status;
+
+               ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+
+               SECURE_LOGD("Flush size: %dx%d\n", w, h);
+               status = flush_to_file(canvas, info->id, w, h);
+
+               flush_cb(snapshot_win, info->id, status, info->data);
+               /*!
+                * Do not access info after this.
+                */
+       }
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+
+
+static void post_render_cb(void *data, Evas *e, void *event_info)
+{
+       Evas_Object *snapshot_win = data;
+       struct snapshot_info *info;
+
+       info = evas_object_data_get(snapshot_win, "snapshot,info");
+       if (!info) {
+               LOGE("snapshot info is not valid\n");
+               return;
+       }
+
+       info->render_cnt++;
+
+       if (info->flush_timer) {
+               /*!
+                * This has not to be happens.
+                */
+               LOGE("Flush timer is not cleared\n");
+               ecore_timer_del(info->flush_timer);
+               info->flush_timer = NULL;
+       }
+
+       if (!info->flush_cb) {
+               LOGD("Flush request is not initiated yet\n");
+               return;
+       }
+
+       /*!
+        * \NOTE
+        * Even if tehre is no timer registered, we should capture the content
+        * from out of this callback.
+        * Or we can met unexpected problems.
+        * To avoid it, use the 0.0001f to get timer callback ASAP, not in this function.
+        */
+       LOGD("Fire the flush timer %lf (%d)\n", info->timeout, info->render_cnt);
+       info->flush_timer = ecore_timer_add(info->timeout, snapshot_cb, snapshot_win);
+       if (!info->flush_timer) {
+               void (*flush_cb)(Evas_Object *snapshot_window, const char *id, int status, void *data);
+
+               LOGE("Unalbe to add timer for getting the snapshot\n");
+               flush_cb = info->flush_cb;
+               info->flush_cb = NULL;
+
+               flush_cb(snapshot_win, info->id, LB_STATUS_ERROR_FAULT, info->data);
+               /*!
+                * \note
+                * Do not access info after from here.
+                */
+       }
+}
+
+
+
+static void pre_render_cb(void *data, Evas *e, void *event_info)
+{
+       Evas_Object *snapshot_win = data;
+       struct snapshot_info *info;
+
+       info = evas_object_data_get(snapshot_win, "snapshot,info");
+       if (!info) {
+               LOGE("snapshot info is not valid\n");
+               return;
+       }
+
+       if (info->flush_timer) {
+               ecore_timer_del(info->flush_timer);
+               info->flush_timer = NULL;
+               LOGD("Clear the flush timer\n");
+       }
+
+       LOGD("Pre-render callback\n");
+}
+
+
+
+static void resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+       Ecore_Evas *ee;
+       int w;
+       int h;
+       int ow;
+       int oh;
+
+       ee = ecore_evas_ecore_evas_get(e);
+       if (!ee) {
+               return;
+       }
+
+       ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+       evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
+       if (ow == w && oh == h) {
+               SECURE_LOGD("Size is not changed: %dx%d\n", w, h);
+               return;
+       }
+
+       /*!
+        * Box(parent object) is resized.
+        * Try to resize the canvas too.
+        */
+       ecore_evas_resize(ee, w, h);
+       SECURE_LOGD("Canvas is resized to %dx%d\n", w, h);
+}
+
+
+
+PUBLIC Evas_Object *livebox_snapshot_window_add(const char *id, int size_type)
+{
+       struct snapshot_info *info;
+       Evas_Object *snapshot_win;
+       Evas *e;
+       int w;
+       int h;
+
+       if (livebox_service_get_size(size_type, &w, &h) != LB_STATUS_SUCCESS) {
+               LOGE("Invalid size\n");
+               return NULL;
+       }
+
+       info = malloc(sizeof(*info));
+       if (!info) {
+               LOGE("Heap: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       info->id = strdup(id);
+       if (!info->id) {
+               LOGE("Heap: %s\n", strerror(errno));
+               free(info);
+               return NULL;
+       }
+
+       info->flush_cb = NULL;
+       info->data = NULL;
+       info->flush_timer = NULL;
+       info->render_cnt = 0;
+
+       e = create_virtual_canvas(w, h);
+       if (!e) {
+               free(info->id);
+               free(info);
+               return NULL;
+       }
+
+       snapshot_win = evas_object_rectangle_add(e);
+       if (!snapshot_win) {
+               destroy_virtual_canvas(e);
+               free(info->id);
+               free(info);
+               return NULL;
+       }
+
+       SECURE_LOGD("Add new window %dx%d\n", w, h);
+       evas_object_event_callback_add(snapshot_win, EVAS_CALLBACK_DEL, del_cb, NULL);
+       evas_object_event_callback_add(snapshot_win, EVAS_CALLBACK_RESIZE, resize_cb, NULL);
+       evas_object_resize(snapshot_win, w, h);
+       evas_object_show(snapshot_win);
+
+       evas_object_data_set(snapshot_win, "snapshot,info", info);
+
+       evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, post_render_cb, snapshot_win);
+       evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, snapshot_win);
+
+       return snapshot_win;
+}
+
+
+
+PUBLIC int livebox_snapshot_window_flush(Evas_Object *snapshot_win, double timeout, void (*flush_cb)(Evas_Object *snapshot_window, const char *id, int status, void *data), void *data)
+{
+       struct snapshot_info *info;
+
+       if (!flush_cb || timeout < 0.0f) {
+               LOGE("Invalid argument (%p, %lf)\n", flush_cb, timeout);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       info = evas_object_data_get(snapshot_win, "snapshot,info");
+       if (!info) {
+               LOGE("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       info->timeout = timeout;
+
+       if (timeout == 0.0f) {
+               /*!
+                * This timer is just used for guarantees same behavious even if it flushes content directly,
+                * The callback should be called from next loop.
+                * or the developer will get confused
+                */
+               info->flush_timer = ecore_timer_add(0.0001f, direct_snapshot_cb, snapshot_win);
+               if (!info->flush_timer) {
+                       return LB_STATUS_ERROR_FAULT;
+               }
+       } else if (info->render_cnt) {
+               /*!
+                * Try to watit pre-render callback.
+                * If there is rendered contents.
+                */
+               DbgPrint("Rendered %d times already\n", info->render_cnt);
+               info->flush_timer = ecore_timer_add(info->timeout, snapshot_cb, snapshot_win);
+               if (!info->flush_timer) {
+                       return LB_STATUS_ERROR_FAULT;
+               }
+       }
+
+       info->flush_cb = flush_cb;
+       info->data = data;
+
+       return LB_STATUS_SUCCESS;
+}
+
+
+
+PUBLIC int livebox_snapshot_window_del(Evas_Object *snapshot_win)
+{
+       Evas *e;
+       if (!snapshot_win || !evas_object_data_get(snapshot_win, "snapshot,info")) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       e = evas_object_evas_get(snapshot_win);
+       evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
+       evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
+
+       evas_object_del(snapshot_win);
+       return LB_STATUS_SUCCESS;
+}
+
+
+
+// End of a file
diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..208ee6c
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2013  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#include <Ecore.h>
+#include <dlog.h>
+
+#include "debug.h"
+#include "util.h"
+
+int errno;
+
+int util_check_extension(const char *filename, const char *check_ptr)
+{
+       int name_len;
+
+       name_len = strlen(filename);
+       while (--name_len >= 0 && *check_ptr) {
+               if (filename[name_len] != *check_ptr)
+                       return -EINVAL;
+
+               check_ptr ++;
+       }
+
+       return 0;
+}
+
+double util_timestamp(void)
+{
+#if defined(_USE_ECORE_TIME_GET)
+       return ecore_time_get();
+#else
+       struct timeval tv;
+
+       gettimeofday(&tv, NULL);
+
+       return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
+#endif
+}
+
+/* End of a file */
diff --git a/src/virtual_window.c b/src/virtual_window.c
new file mode 100644 (file)
index 0000000..0868494
--- /dev/null
@@ -0,0 +1,605 @@
+#include <Elementary.h>
+#include <string.h>
+#include <Ecore_Evas.h>
+#include <Ecore_X.h>
+#include <Evas.h>
+
+#include <X11/Xlib.h>
+
+#include <dlog.h>
+#include <livebox-errno.h>
+#include <livebox-service.h>
+
+#include "livebox.h"
+#include "debug.h"
+
+#define IS_PD 1
+
+#define PUBLIC __attribute__((visibility("default")))
+
+/*!
+ * \brief
+ * Abstracted Data Type of Virtual Window
+ */
+struct info {
+       char *id; /*!< Identification */
+       struct livebox_buffer *handle; /*!< Livebox buffer handle */
+       int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
+       Ecore_Evas *ee;
+       Evas *e;
+       int is_pd;
+       int deleted;
+       int w;
+       int h;
+};
+
+#if defined(ENABLE_ACCESSIBILITY)
+static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
+{
+       Evas_Object *o, *ho;
+
+       o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
+       if (!o) return NULL;
+
+       ho = evas_object_data_get(o, "_elm_access_target");
+       return ho;
+}
+#endif
+
+/*!
+ * \note
+ * Every user event (mouse) on the buffer will be passed via this event callback
+ */
+static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_data *event_info, void *data)
+{
+       struct info *info = data;
+#if defined(ENABLE_ACCESSIBILITY)
+       Elm_Access_Action_Info action_info;
+       Elm_Access_Action_Type action_type;
+#endif
+       int ret = 0;
+       Evas_Object *parent_elm;
+       KeySym *key_symbol;
+       unsigned int flags = 0;
+
+       if (!info->handle) {
+               /* Just ignore this event */
+               return 0;
+       }
+
+       /*!
+        * \note
+        * Feed up events
+        */
+       switch (event_info->type) {
+       case BUFFER_EVENT_ON_HOLD:
+               flags = evas_event_default_flags_get(info->e);
+               flags |= EVAS_EVENT_FLAG_ON_HOLD;
+               evas_event_default_flags_set(info->e, flags);
+               break;
+       case BUFFER_EVENT_OFF_HOLD:
+               flags = evas_event_default_flags_get(info->e);
+               flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
+               evas_event_default_flags_set(info->e, flags);
+               break;
+       case BUFFER_EVENT_ON_SCROLL:
+               flags = evas_event_default_flags_get(info->e);
+               flags |= EVAS_EVENT_FLAG_ON_SCROLL;
+               evas_event_default_flags_set(info->e, flags);
+               break;
+       case BUFFER_EVENT_OFF_SCROLL:
+               flags = evas_event_default_flags_get(info->e);
+               flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
+               evas_event_default_flags_set(info->e, flags);
+               break;
+       case BUFFER_EVENT_ENTER:
+               evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
+               break;
+       case BUFFER_EVENT_LEAVE:
+               evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
+               break;
+       case BUFFER_EVENT_DOWN:
+               /*!
+                * \note
+                * Calculate the event occurred X & Y on the buffer
+                */
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, (event_info->timestamp - 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
+               evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
+               break;
+       case BUFFER_EVENT_MOVE:
+               /*!
+                * \note
+                * Calculate the event occurred X & Y on the buffer
+                */
+               DbgPrint("[MOVE] %lu x %lu\n", event_info->info.pointer.x, event_info->info.pointer.y);
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
+               break;
+       case BUFFER_EVENT_UP:
+               DbgPrint("[UP] %lu x %lu\n", event_info->info.pointer.x, event_info->info.pointer.y);
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
+               evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, (event_info->timestamp + 0.001f) * 1000, NULL);
+
+               flags = evas_event_default_flags_get(info->e);
+               flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
+               flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
+               evas_event_default_flags_set(info->e, flags);
+               break;
+       case BUFFER_EVENT_HIGHLIGHT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
+               /*!
+                * \note
+                * Calculate the event occurred X & Y on the buffer
+                */
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               if (ret == EINA_TRUE) {
+                       if (!get_highlighted_object(parent_elm)) {
+                               LOGE("Highlighted object is not found\n");
+                               ret = LB_ACCESS_STATUS_ERROR;
+                       } else {
+                               LOGD("Highlighted object is found\n");
+                               ret = LB_ACCESS_STATUS_DONE;
+                       }
+               } else {
+                       LOGE("Action error\n");
+                       ret = LB_ACCESS_STATUS_ERROR;
+               }
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_HIGHLIGHT_NEXT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+               action_info.highlight_cycle = EINA_FALSE;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_HIGHLIGHT_PREV:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+               action_info.highlight_cycle = EINA_FALSE;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_ACTIVATE:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_ACTIVATE;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_ACTION_UP:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_UP;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_ACTION_DOWN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_DOWN;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_SCROLL_UP:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_SCROLL;
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               action_info.mouse_type = 2;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_SCROLL_MOVE:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_SCROLL;
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               action_info.mouse_type = 1;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_SCROLL_DOWN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_SCROLL;
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               action_info.mouse_type = 0;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_UNHIGHLIGHT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+#if defined(ENABLE_ACCESSIBILITY)
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+#else
+               ret = LB_ACCESS_STATUS_ERROR;
+#endif
+               break;
+       case BUFFER_EVENT_KEY_DOWN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+               }
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       case BUFFER_EVENT_KEY_UP:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+               }
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       case BUFFER_EVENT_KEY_FOCUS_IN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+               }
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       case BUFFER_EVENT_KEY_FOCUS_OUT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+               }
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       default:
+               LOGD("Unhandled buffer event (%d)\n", event_info->type);
+               break;
+       }
+
+       return ret;
+}
+
+static void *alloc_fb(void *data, int size)
+{
+       struct info *info = data;
+       void *buffer;
+
+       if (info->ee) {
+               ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
+               LOGD("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
+       }
+
+       /*!
+        * Acquire a buffer for canvas.
+        */
+       info->handle = livebox_acquire_buffer_NEW(info->id, info->is_pd,
+                                       info->w, info->h, sizeof(int),
+                                       event_handler_cb, info);
+
+       /*!
+        * If it supports the H/W accelerated buffer,
+        * Use it.
+        */
+       if (livebox_support_hw_buffer(info->handle)) {
+               if (livebox_create_hw_buffer(info->handle) == 0) {
+                       buffer = livebox_buffer_hw_buffer(info->handle);
+                       if (buffer) {
+                               LOGD("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
+                               info->is_hw = 1;
+                               return buffer;
+                       }
+               }
+
+               LOGE("Failed to allocate HW Accelerated buffer\n");
+       }
+
+       /*!
+        * Or use the buffer of a S/W backend.
+        */
+       buffer = livebox_ref_buffer(info->handle);
+       LOGD("SW buffer is created (%dx%d)\n", info->w, info->h);
+       info->is_hw = 0;
+       return buffer;
+}
+
+static void free_fb(void *data, void *ptr)
+{
+       struct info *info = data;
+
+       if (!info->handle) {
+               return;
+       }
+
+       if (info->is_hw) {
+               if (livebox_destroy_hw_buffer(info->handle) == 0) {
+                       LOGD("HW Accelerated buffer is destroyed\n");
+               }
+       } else {
+               LOGD("SW buffer is destroyed, %p\n", info);
+               livebox_unref_buffer(ptr);
+       }
+
+       livebox_release_buffer_NEW(info->handle);
+       info->handle = NULL;
+
+       if (info->deleted) {
+               free(info->id);
+               info->id = NULL;
+
+               free(info);
+       }
+}
+
+static void pre_render_cb(void *data, Evas *e, void *event_info)
+{
+       struct info *info = data;
+
+       if (!info->handle) {
+               return;
+       }
+
+       if (livebox_conf_premultiplied_alpha()) {
+               Evas_Coord w;
+               Evas_Coord h;
+
+               ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
+               evas_damage_rectangle_add(e, 0, 0, w, h);
+       }
+
+       if (info->is_hw) {
+               livebox_buffer_pre_render(info->handle);
+       }
+}
+
+static void post_render_cb(void *data, Evas *e, void *event_info)
+{
+       struct info *info = data;
+
+       if (!info->handle) {
+               return;
+       }
+
+       if (livebox_conf_premultiplied_alpha()) {
+               void *canvas;
+               int x, y, w, h;
+
+               // Get a pointer of a buffer of the virtual canvas
+               canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
+               if (!canvas) {
+                       ErrPrint("Failed to get pixel canvas\n");
+                       return;
+               }
+
+               ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
+               evas_data_argb_unpremul(canvas, w * h);
+       }
+
+       if (info->is_hw) {
+               livebox_buffer_post_render(info->handle);
+       } else {
+               livebox_sync_buffer(info->handle);
+       }
+}
+
+static void ecore_evas_free_cb(Ecore_Evas *ee)
+{
+       struct info *info;
+
+       info = ecore_evas_data_get(ee, "dynamic,box,info");
+       if (!info) {
+               LOGD("Info is not valid\n");
+               return;
+       }
+
+       if (info->e) {
+               evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
+               evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
+       }
+
+       info->deleted = 1;
+       info->ee = NULL;
+}
+
+PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
+{
+       struct info *info;
+       Evas_Object *rect;
+
+       if (!id) {
+               ErrPrint("Invalid parameter\n");
+               return NULL;
+       }
+
+       info = calloc(1, sizeof(*info));
+       if (!info) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       info->id = strdup(id);
+       if (!info->id) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(info);
+               return NULL;
+       }
+
+       info->is_pd = is_pd;
+
+       /*!
+        * Size information must be initialized before call the ecore_evas_buffer_new.
+        */
+       info->w = 1;
+       info->h = 1;
+
+       info->ee = ecore_evas_buffer_allocfunc_new(1, 1, alloc_fb, free_fb, info);
+       if (!info->ee) {
+               ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
+               free(info->id);
+               free(info);
+               return NULL;
+       }
+
+       info->e = ecore_evas_get(info->ee);
+       if (!info->e) {
+               ErrPrint("Failed to get evas\n");
+               ecore_evas_free(info->ee);
+               return NULL;
+       }
+
+       ecore_evas_data_set(info->ee, "dynamic,box,info", info);
+
+       pre_render_cb(info, NULL, NULL);
+       ecore_evas_alpha_set(info->ee, EINA_TRUE);
+       post_render_cb(info, NULL, NULL);
+
+       ecore_evas_manual_render_set(info->ee, EINA_FALSE);
+       ecore_evas_resize(info->ee, 1, 1);
+
+       ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
+       evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
+       evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
+
+       rect = evas_object_rectangle_add(info->e);
+       if (!rect) {
+               ErrPrint("Failed to create evas_object\n");
+               ecore_evas_free(info->ee);
+               return NULL;
+       }
+
+       evas_object_resize(rect, 1, 1);
+       evas_object_color_set(rect, 0, 0, 0, 0);
+       return rect;
+}
+
+/* End of a file */
diff --git a/src/virtual_window_wayland.c b/src/virtual_window_wayland.c
new file mode 100644 (file)
index 0000000..3a1dadf
--- /dev/null
@@ -0,0 +1,433 @@
+#include <Elementary.h>
+#include <string.h>
+#include <Ecore_Evas.h>
+#include <Ecore_X.h>
+#include <Evas.h>
+
+#include <dlog.h>
+#include <livebox-errno.h>
+#include <livebox-service.h>
+
+#include "livebox.h"
+#include "debug.h"
+
+#define IS_PD 1
+
+#define PUBLIC __attribute__((visibility("default")))
+
+/*!
+ * \brief
+ * Abstracted Data Type of Virtual Window
+ */
+struct info {
+       char *id; /*!< Identification */
+       struct livebox_buffer *handle; /*!< Livebox buffer handle */
+       int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
+       Ecore_Evas *ee;
+       Evas *e;
+       int is_pd;
+};
+
+static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
+{
+       Evas_Object *o, *ho;
+
+       o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
+       if (!o) return NULL;
+
+       ho = evas_object_data_get(o, "_elm_access_target");
+       return ho;
+}
+
+/*!
+ * \note
+ * Every user event (mouse) on the buffer will be passed via this event callback
+ */
+static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_data *event_info, void *data)
+{
+       struct info *info = data;
+       Elm_Access_Action_Info action_info;
+       Elm_Access_Action_Type action_type;
+       int ret = 0;
+       Evas_Object *parent_elm;
+
+
+       if (!info->handle) {
+               /* Just ignore this event */
+               return 0;
+       }
+
+       /*!
+        * \note
+        * Feed up events
+        */
+       switch (event_info->type) {
+       case BUFFER_EVENT_ENTER:
+               evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
+               break;
+       case BUFFER_EVENT_LEAVE:
+               evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
+               break;
+       case BUFFER_EVENT_DOWN:
+               /*!
+                * \note
+                * Calculate the event occurred X & Y on the buffer
+                */
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, (event_info->timestamp - 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
+               evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
+               break;
+       case BUFFER_EVENT_MOVE:
+               /*!
+                * \note
+                * Calculate the event occurred X & Y on the buffer
+                */
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
+               break;
+       case BUFFER_EVENT_UP:
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
+               evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, (event_info->timestamp + 0.001f) * 1000, NULL);
+               break;
+       case BUFFER_EVENT_HIGHLIGHT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
+               /*!
+                * \note
+                * Calculate the event occurred X & Y on the buffer
+                */
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               if (ret == EINA_TRUE) {
+                       if (!get_highlighted_object(parent_elm)) {
+                               LOGE("Highlighted object is not found\n");
+                               ret = LB_ACCESS_STATUS_ERROR;
+                       } else {
+                               LOGD("Highlighted object is found\n");
+                               ret = LB_ACCESS_STATUS_DONE;
+                       }
+               } else {
+                       LOGE("Action error\n");
+                       ret = LB_ACCESS_STATUS_ERROR;
+               }
+               break;
+       case BUFFER_EVENT_HIGHLIGHT_NEXT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+               action_info.highlight_cycle = EINA_FALSE;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_HIGHLIGHT_PREV:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+               action_info.highlight_cycle = EINA_FALSE;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_ACTIVATE:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_ACTIVATE;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_ACTION_UP:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_UP;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_ACTION_DOWN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_DOWN;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_SCROLL_UP:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_SCROLL;
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               action_info.mouse_type = 2;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_SCROLL_MOVE:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_SCROLL;
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               action_info.mouse_type = 1;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_SCROLL_DOWN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_SCROLL;
+               action_info.x = event_info->info.pointer.x;
+               action_info.y = event_info->info.pointer.y;
+               action_info.mouse_type = 0;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_UNHIGHLIGHT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               break;
+       case BUFFER_EVENT_KEY_DOWN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       case BUFFER_EVENT_KEY_UP:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       case BUFFER_EVENT_KEY_FOCUS_IN:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       case BUFFER_EVENT_KEY_FOCUS_OUT:
+               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               if (!parent_elm) {
+                       ret = LB_ACCESS_STATUS_ERROR;
+                       break;
+               }
+
+               ret = LB_KEY_STATUS_ERROR;
+               break;
+       default:
+               LOGD("Unhandled buffer event (%d)\n", event_info->type);
+               break;
+       }
+
+       return ret;
+}
+
+static void *alloc_fb(void *data, int size)
+{
+       struct info *info = data;
+       void *buffer;
+       int width = 0;
+       int height = 0;
+
+       if (info->ee == NULL) {
+               width = 1;
+               height = 1;
+       } else {
+               ecore_evas_geometry_get(info->ee, NULL, NULL, &width, &height);
+       }
+
+       /*!
+        * Acquire a buffer for canvas.
+        */
+       info->handle = livebox_acquire_buffer_NEW(info->id, info->is_pd,
+                                       width, height,
+                                       event_handler_cb, info);
+
+       /*!
+        * If it supports the H/W accelerated buffer,
+        * Use it.
+        */
+       if (livebox_support_hw_buffer(info->handle)) {
+               if (livebox_create_hw_buffer(info->handle) == 0) {
+                       buffer = livebox_buffer_hw_buffer(info->handle);
+                       if (buffer) {
+                               LOGD("HW Accelerated buffer is created\n");
+                               info->is_hw = 1;
+                               return buffer;
+                       }
+               }
+
+               LOGE("Failed to allocate HW Accelerated buffer\n");
+       }
+
+       /*!
+        * Or use the buffer of a S/W backend.
+        */
+       buffer = livebox_ref_buffer(info->handle);
+       LOGD("SW buffer is created\n");
+       info->is_hw = 0;
+       return buffer;
+}
+
+static void free_fb(void *data, void *ptr)
+{
+       struct info *info = data;
+
+       if (!info->handle) {
+               return;
+       }
+
+       if (info->is_hw) {
+               if (livebox_destroy_hw_buffer(info->handle) == 0) {
+                       LOGD("HW Accelerated buffer is destroyed\n");
+                       goto out;
+               }
+       }
+
+       livebox_unref_buffer(ptr);
+       LOGD("SW buffer is destroyed\n");
+out:
+       livebox_release_buffer(info->handle);
+       info->handle = NULL;
+}
+
+static void pre_render_cb(void *data, Evas *e, void *event_info)
+{
+       struct info *info = data;
+
+       if (!info->handle) {
+               return;
+       }
+
+       if (info->is_hw) {
+               livebox_buffer_pre_render(info->handle);
+       }
+}
+
+static void post_render_cb(void *data, Evas *e, void *event_info)
+{
+       struct info *info = data;
+
+       if (!info->handle) {
+               return;
+       }
+
+       if (info->is_hw) {
+               livebox_buffer_post_render(info->handle);
+       } else {
+               livebox_sync_buffer(info->handle);
+       }
+}
+
+PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
+{
+       struct info *info;
+       Evas_Object *rect;
+
+       if (!id) {
+               ErrPrint("Invalid parameter\n");
+               return NULL;
+       }
+
+       info = calloc(1, sizeof(*info));
+       if (!info) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       info->id = strdup(id);
+       if (!info->id) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(info);
+               return NULL;
+       }
+
+       info->is_pd = is_pd;
+
+       info->ee = ecore_evas_buffer_allocfunc_new(1, 1, alloc_fb, free_fb, info);
+       if (!info->ee) {
+               ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
+               free(info->id);
+               free(info);
+               return NULL;
+       }
+
+       pre_render_cb(info, NULL, NULL);
+       ecore_evas_alpha_set(info->ee, EINA_TRUE);
+       post_render_cb(info, NULL, NULL);
+
+       ecore_evas_data_set(info->ee, "dynamic,box,info", info);
+
+       ecore_evas_manual_render_set(info->ee, EINA_FALSE);
+       ecore_evas_resize(info->ee, 1, 1);
+
+       info->e = ecore_evas_get(info->ee);
+       if (!info->e) {
+               ErrPrint("Failed to get evas\n");
+               ecore_evas_free(info->ee);
+               return NULL;
+       }
+
+       evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
+       evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
+
+       rect = evas_object_rectangle_add(info->e);
+       if (!rect) {
+               ErrPrint("Failed to create evas_object\n");
+               ecore_evas_free(info->ee);
+               return NULL;
+       }
+
+       evas_object_resize(rect, 1, 1);
+       evas_object_color_set(rect, 0, 0, 0, 0);
+       return rect;
+}
+
+/* End of a file */